Compare commits

...

106 Commits
7.73.0 ... main

Author SHA1 Message Date
Igor Vinokur aa213c3003
Update ch.qos.logback dependency version to latest (#687)
In order to fix the CVE-2023-6378 vulnerability, update ch.qos.logback maven dependency version to 1.5.6
2024-05-27 09:29:31 +03:00
Igor Vinokur 88cbaebd1a
Support raw devfile urls without yaml extension (#683)
On handling raw devfile urls, request content by the url, and check if the content is a devfile. If yes treat the url as a raw devfile url.

---------

Signed-off-by: ivinokur <ivinokur@redhat.com>
Co-authored-by: Anatolii Bazko <abazko@redhat.com>
2024-05-15 10:13:37 +03:00
che-bot e072c7642b
chore: Update from ubi8-minimal:8.9-1108 to ubi8-minimal:8.9-1161 (#681)
* chore: Update from ubi8-minimal:8.9-1108 to ubi8-minimal:8.9-1161

Signed-off-by: Nick Boldt <nboldt@redhat.com>

* chore: Update from ubi8-minimal:8.9-1108 to ubi8-minimal:8.9-1161

Signed-off-by: Nick Boldt <nboldt@redhat.com>

---------

Signed-off-by: Nick Boldt <nboldt@redhat.com>
Co-authored-by: Nick Boldt <nboldt@redhat.com>
2024-04-29 08:49:33 +03:00
che-bot b5f110c659
chore: Bump to 7.86.0-SNAPSHOT in main (#680)
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
Co-authored-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2024-04-26 08:16:38 +03:00
Shmaraiev Oleksandr 95b1c390b2
Add info messages to git-flow tests (#676)
* Add info messages to tests
* Add 'waitFinishDeploymentCheServer' to avoid 'error: lost connection to pod'
2024-04-19 20:33:08 +03:00
Dmytro Nochevnov 858a12b3ff
Download chectl install script from che-incubator.github.io in tests (#677) 2024-04-17 14:22:19 +02:00
che-bot 7c07c3c135
chore: Bump to 7.85.0-SNAPSHOT in main (#675)
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
Co-authored-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2024-04-09 15:52:32 +03:00
Igor Vinokur 2cfce0568a
Rework the Bitbucket Server oauth token validation (#673)
- Change the validation API request to get current user request. The /rest/api/1.0/application-properties request is irrelevant as it does not require a token.
- Pass oath token to the getPersonalAccessToken() API request in order to avoid circular getToken() request.
2024-04-08 09:30:02 +03:00
ivinokur c51919d1e3 fixup! Fix gitlab oauth token validation request 2024-04-04 11:10:45 +02:00
ivinokur 1fc4e07988 Fix gitlab oauth token validation request 2024-04-04 11:10:45 +02:00
sdawley 799fcb1d0e Updating tomcat version to 10.1.14 for CRW-4941
Signed-off-by: sdawley <sdawley@redhat.com>
2024-03-27 15:43:15 +01:00
Igor Vinokur 2e27c47f2f
Add provider name annotation to PAT secret (#670)
Add che.eclipse.org/scm-provider-name annotation to Personal Access Token secret.
2024-03-25 14:57:27 +02:00
ivinokur b8e0397b0a Update io.fabric8.kubernetes-client to 6.10.0 2024-03-22 18:13:04 +01:00
che-bot 661d852250
chore: Bump to 7.84.0-SNAPSHOT in main (#669)
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
Co-authored-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2024-03-19 08:51:13 +02:00
Igor Vinokur ba6f30f963
Add Gitlab invalidate token implementation (#667) 2024-03-16 12:56:55 +02:00
Igor Vinokur dbe167276a
Encode redirect URL if needed on oauth1 callback request (#663)
The latest BItBucket Server decodes the callback url so that causes IllegalArgumentException error. Catch the error and decode the redirect url.
2024-03-16 06:26:52 +02:00
Anatolii Bazko 28002fb835
fix: Support BitBucket endpoint with path (#665)
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2024-03-12 10:22:04 +01:00
Igor Vinokur 6cdf6f655a
Do not pass oauth2 as a username to Git credentials for Bitbucket (#662)
Set bitbucket-***** as a token name annotation for bitbucket token secret. This is needed to pass username instead of oauth2 for bitbucket credentials
2024-03-07 11:08:33 +02:00
Anatolii Bazko 7dc7a61511
chore: Remote workspace-stop roles (#659)
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2024-03-05 12:38:09 +01:00
che-bot 60262e3a72
chore: Bump to 7.83.0-SNAPSHOT in main (#658) 2024-02-28 09:18:10 +02:00
Ilya Buziuk 5d79a849ef
Update CODEOWNERS (#657) 2024-02-27 17:27:09 +02:00
Igor Vinokur 3fef2347f0
Remove the DB related modules (#630) 2024-02-27 15:27:58 +02:00
Igor Vinokur aebdc3a04d
Add debug logs to KubernetesPersonalAccessTokenManager class (#656) 2024-02-21 20:24:27 +02:00
Igor Vinokur a691074548
Add debug logs to KubernetesPersonalAccessTokenManager class (#655) 2024-02-20 18:07:04 +02:00
Igor Vinokur f9f4c8e5d5
Encode redirect URL if needed on oauth callback request (#654)
Some SCM providers like BItBucket Server decode the callback url so that cause IllegalArgumentException error. Catch the error and decode the redirect url.
2024-02-19 19:07:07 +02:00
Igor Vinokur 4f8a84cb1d
Fetch oauth tokens from kubernetes secrets (#652)
Move AuthorisationRequestManager interface towsmaster/che-core-api-factory module in order to avoid circular dependency.
Rework the get oauth token method to return an oauth token from kubernetes secrets if token is not found in the system memory of the che-server pod. If provider name value is not configured in the kubernetes secret oauth token, get the token by mapping it by provider url from the secret and oauth provider name from the aouth config secret.
2024-02-08 10:22:51 +02:00
ivinokur 6f40c9856f Add isNullOrEmpty check to the BitbucketServerURLParser 2024-02-06 14:18:05 +01:00
che-bot 62f301c42d
chore: Bump to 7.82.0-SNAPSHOT in main (#651)
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
Co-authored-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2024-02-02 19:53:07 +02:00
Shmaraiev Oleksandr 9422bf86ac
Add test 'che-smoke-test' as PR checks
* Add 'smoke-test' to OpenShift CI
* Add 'pod-che-smoke-test.yaml' component
* Add 'startSmokeTest' to 'common.sh'
* Update 'pod-oauth-factory-test.yaml' component
2024-01-30 12:06:23 +02:00
Nick Boldt be4383abac chore: remove Nick and Mario as code owners; add Sam
Change-Id: Ibb4d2cab011a42279ae93da528d7aa566bf4860d
Signed-off-by: Nick Boldt <nboldt@redhat.com>
2024-01-23 12:04:37 +01:00
Dmytro Nochevnov fa7d6442f5
Fix syntax error in Dockerfile of OpenShift CI jobs (#646)
Signed-off-by: Dmytro Nochevnov <dnochevn@redhat.com>
2024-01-19 13:25:47 +02:00
Dmytro Nochevnov e1ae06ec50
Get rid of failing curl in OpenShift CI jobs (#645)
Signed-off-by: Dmytro Nochevnov <dnochevn@redhat.com>
2024-01-19 12:15:49 +02:00
Dmytro Nochevnov 901a30ea8c
Move installation of oc client from Dockerfile to common.sh (#644)
Signed-off-by: Dmytro Nochevnov <dnochevn@redhat.com>
2024-01-18 16:41:12 +02:00
Dmytro Nochevnov 76913d93c2
Fix openshift-client-linux.tar.gz version in OpenShift CI job Dockerfile (#643)
Signed-off-by: Dmytro Nochevnov <dnochevn@redhat.com>
2024-01-17 15:40:00 +02:00
Dmytro Nochevnov dc7edf634e
Get more OpenShift CI image build command logs 2024-01-17 13:17:42 +02:00
Igor Vinokur 12a3a8a8e7
Remove devfile validation schema mechanism (#640)
Remove devfile validation schema mechanism and related stuff.
2024-01-17 09:21:44 +02:00
Nick Boldt 3fb1df91f7 chore: Update from ubi8-minimal:8.9-1029 to ubi8-minimal:8.9-1108
Signed-off-by: Nick Boldt <nboldt@redhat.com>
2024-01-15 14:40:57 +01:00
Nick Boldt 0e3b7c107c chore: Update from ubi8-minimal:8.9-1029 to ubi8-minimal:8.9-1108
Signed-off-by: Nick Boldt <nboldt@redhat.com>
2024-01-15 14:40:57 +01:00
Mykhailo Kuznietsov 978f2cdd21 chore: Bump to 7.81.0-SNAPSHOT in main
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2024-01-11 15:35:09 +01:00
Igor Vinokur f547c681a8
Fix license headers (#638)
Fix maven build by updating corresponding license headers
2024-01-10 11:36:56 +02:00
Igor Vinokur 06e14c854d
Pass status code to Exception on Unauthorised to GitHub Error (#618)
Pass status code to Exception on Unauthorised to GitHub Error in order to be able to recognise GitHub Server url if oAuth is not configured and no PAT is present.
2024-01-10 10:46:02 +02:00
Igor Vinokur d077bdd93d
Add new devfile versions support (#637)
Add missing devfile versions to the list of supported devfile versions
Add corresponding jsons.
2024-01-09 18:16:34 +02:00
Shmaraiev Oleksandr 96ac9beb7f
Delete 'yq' from Dockerfile (#636) 2024-01-09 10:14:54 +02:00
Nick Boldt 4e067e94d7
Update README.md - add link to status badge (#575) 2023-12-28 22:34:36 +02:00
che-bot e3ccf70b64
chore: Bump to 7.80.0-SNAPSHOT in main (#628)
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
Co-authored-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2023-12-28 02:23:26 +02:00
Shmaraiev Oleksandr 6b584db971
Create test to check 'git-oauth-setup-flow' as PR checks (#633)
* Add new components to implement 'git-oauth-setup-flow' test
* Update existing files to implement 'git-oauth-setup-flow' test
2023-12-27 17:44:40 +02:00
Mykhailo Kuznietsov cc4dac0922
fix: adapt to latest changes in build.sh that uses podman now (#629)
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2023-12-21 15:38:22 +02:00
Igor Vinokur 151ef89772
Return oauth1 providers on registered oauth providers list request (#624)
Add the list of oauth1 providers to the list of registered oauth2 providers on get registered oauth providers API request.
2023-12-21 14:03:42 +02:00
Nick Boldt bda80f1d7b
chore(build): remove commented code that we didn't need for 7.77 release, as it's evidently safe to delete (#627)
Change-Id: I0d6db01942b35a1c5f31ad22718743dec8a90f23

Signed-off-by: RHDH Build (rhdh-bot) <rhdh-bot@redhat.com>
Co-authored-by: RHDH Build (rhdh-bot) <rhdh-bot@redhat.com>
2023-12-20 09:29:10 -04:00
Igor Vinokur 3ecfbcd8b1
Modify the `build.sh` script to work with podman (#559)
In order to be able to build images directly in a wotkspace container, add BUILDER variable to be able to execute the build.sh script not only with docker but with podman and buildah.
2023-12-11 16:11:05 +02:00
Anatolii Bazko f7a49f9fec
fix: work with Bitbucket users containing special characters in theirs names (#622)
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-12-07 17:35:43 +01:00
Igor Vinokur ebca10356e
Throw the API exception with authorization URL on SCMunauthorised error (#621)
Fixes a bug with broken oauth flow caused by https://github.com/eclipse-che/che-server/pull/615
2023-12-04 20:57:25 +02:00
Anatolii Bazko 7fe2a4dd3f
feat: Advanced authorization (#619)
* feat: Advanced authorization

Signed-off-by: Anatolii Bazko <abazko@redhat.com>

* Renames fields

Signed-off-by: Anatolii Bazko <abazko@redhat.com>

* Address remarks

Signed-off-by: Anatolii Bazko <abazko@redhat.com>

* Address remarks

Signed-off-by: Anatolii Bazko <abazko@redhat.com>

* Address remarks

Signed-off-by: Anatolii Bazko <abazko@redhat.com>

---------

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-12-04 15:55:35 +01:00
Mykhailo Kuznietsov 7acf4cc2d9 chore: Bump to 7.79.0-SNAPSHOT in main
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2023-11-30 12:24:39 +01:00
Igor Vinokur 5baa3a7ccf
Align the unreachable devfile exception message (#615)
Add a common exception message and use it for cases when:

The devfile location is unavailable.
The devfile content is is not valid: e.g the response content is an html content of an scm authorisation page.
2023-11-28 18:09:57 +02:00
Igor Vinokur f34e80450b
Expand the raw devfile url resolver pattern with token query parameter (#616)
Rework the accept() check in the raw devfile url resolver to respect token query parameters e.g. https://raw.githubusercontent.com/vinokurig/private/main/devfile.yaml?token=<token>
2023-11-28 18:08:57 +02:00
Igor Vinokur 974c1b1890
Add support for PATs in GitHub Enterprise server (#603)
Add necessary checks to the GithubURLParser and AbstractGithubURLParser classes in order to support PAT for GitHub Enterprise server without configuring oAuth.
2023-11-21 11:11:06 +02:00
che-bot 6ca7127939
chore: Update from ubi8-minimal:8.7-1085 to ubi8-minimal:8.9-1029 (#612)
* chore: Update from ubi8-minimal:8.7-1085 to ubi8-minimal:8.9-1029

Signed-off-by: Nick Boldt <nboldt@redhat.com>

* chore: Update from ubi8-minimal:8.8-1072 to ubi8-minimal:8.9-1029

Signed-off-by: Nick Boldt <nboldt@redhat.com>

---------

Signed-off-by: Nick Boldt <nboldt@redhat.com>
Co-authored-by: Nick Boldt <nboldt@redhat.com>
2023-11-19 23:45:09 -04:00
Anatolii Bazko b9317fd1af
fix: Ignore PAT with emtpy SCM url (#610)
* fix: Ignore PAT with emtpy SCM url

Signed-off-by: Anatolii Bazko <abazko@redhat.com>


---------

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-11-17 16:37:19 +01:00
Anatolii Bazko b5e1e2a4a2
chore: Validate OAuth token secrets on namespace provisioning (#608)
* chore: Validate OAuth token secrets on namespace provisioning

Signed-off-by: Anatolii Bazko <abazko@redhat.com>

---------

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-11-15 15:08:48 +01:00
che-bot 92b37d2b6e
chore: Bump to 7.78.0-SNAPSHOT in main (#605)
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
Co-authored-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2023-11-13 13:38:23 +02:00
Samantha Dawley 7192bf1302
Merge pull request #606 from eclipse-che/SDawley-patch-2
Update make-release.sh
2023-11-09 18:32:26 -05:00
Samantha Dawley c68b96d762
Update make-release.sh
I think we're missing a folder. Hopefully fix build.
2023-11-09 15:30:28 -05:00
Mykhailo Kuznietsov 77011bb3c8
fix: che-22646 use gh instead of hub (#604)
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2023-11-09 14:43:43 +02:00
Anatolii Bazko 72f191bcda
feat: Allow to configure 2 github providers simultaneously (#598)
* feat: Support enabling Github enterprise and SaaS simultaneously on Dev Spaces

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-11-07 12:57:48 +01:00
Shmaraiev Oleksandr 2c198333ef
Fix up tests in the PR checks on Openshift CI
* Update 'devworkspace-test.yaml' file
2023-11-06 16:21:37 +02:00
Mykhailo Kuznietsov 26cf509ea7 chore: Bump to 7.77.0-SNAPSHOT in main
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2023-11-06 09:39:16 +01:00
Igor Vinokur cb0c9f9d39
Fix update token on workspace start (#597)
Change the getHostName() function to getProviderUrl() in order to fix an error while updating an oauth token on workspace start.
Throw ScmUnauthorizedException if an oAuth token is not valid, for the dashboard to open the authorisation page and update the token.
2023-11-04 19:12:12 +02:00
Samantha Dawley c4156b61f5
Merge pull request #593 from eclipse-che/22616
chore: comment out node10 (updated to node18) and maven 3.6 (updated to 3.8) installs, as we likely don't need them (either not required or handled by GH action) #22616
2023-10-19 13:16:52 -04:00
Igor Vinokur ba49012fb2
Move dockerfiles to build/dockerfiles (#573)
Moves dockerfiles from dockerfiles/che to build/dockerfiles
Removes the endpoint-watcher, postgres and keycloak images.
Adds brew.Dockerfile from downstream.

Coauthored with @SDawley
2023-10-19 14:49:31 +03:00
Nick Boldt 270be77cc7 support building with podman too
Change-Id: I83fc89be6ad2411b64a4bf4e2308c048a9ab2ff4
Signed-off-by: Nick Boldt <nboldt@redhat.com>
2023-10-18 18:31:17 -03:00
Nick Boldt bfb531761d use maven 3.8 for typescript-dto build too
Change-Id: Ie70fa428ba1a68bbe663577947f05b6a2c4fe3a6
Signed-off-by: Nick Boldt <nboldt@redhat.com>
2023-10-18 18:25:24 -03:00
Nick Boldt 6e67a3b492 comment out node10 (updated to node18) and maven 3.6 (updated to 3.8) installs, as we likely don
't need them (either not required or handled by GH action) #22616

Change-Id: I5d0920b58e413247fd5466a269fb26b1af60578c
Signed-off-by: Nick Boldt <nboldt@redhat.com>
2023-10-18 17:38:57 -03:00
Samantha Dawley 473f67db7e
Update release.yml to install hub (#591)
Adding hub so the release workflow can run successfully.
I don't know where it came from previously, but if it was in Ubuntu by default it likely got taken out due to issues with the previous recommended install method:
https://github.com/mislav/hub/issues?q=is%3Aissue+snap
2023-10-18 17:06:34 -03:00
dependabot[bot] b2284aecee
chore(deps): bump maven-antrun-plugin from 3.0.0 to 3.1.0 (#484)
* chore(deps): bump maven-antrun-plugin from 3.0.0 to 3.1.0

Bumps [maven-antrun-plugin](https://github.com/apache/maven-antrun-plugin) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/apache/maven-antrun-plugin/releases)
- [Commits](https://github.com/apache/maven-antrun-plugin/compare/maven-antrun-plugin-3.0.0...maven-antrun-plugin-3.1.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-antrun-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update pom.xml

* Update pom.xml

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Igor Vinokur <ivinokur@redhat.com>
2023-10-12 16:40:32 +03:00
dependabot[bot] 2adb6f6bee
chore(deps): bump maven-install-plugin from 3.0.0-M1 to 3.1.1 (#488)
* chore(deps): bump maven-install-plugin from 3.0.0-M1 to 3.1.1

Bumps [maven-install-plugin](https://github.com/apache/maven-install-plugin) from 3.0.0-M1 to 3.1.1.
- [Release notes](https://github.com/apache/maven-install-plugin/releases)
- [Commits](https://github.com/apache/maven-install-plugin/compare/maven-install-plugin-3.0.0-M1...maven-install-plugin-3.1.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-install-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update pom.xml

* Update pom.xml

* Update pom.xml

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Igor Vinokur <ivinokur@redhat.com>
2023-10-12 16:00:18 +03:00
Igor Vinokur 148415c691
Respect authorisation request opt-out on workspace start (#576)
If user rejects an scm provider authorisation request while creating or starting existed workspace store the name of the scm provider in the workspace-preferences config-map. The workspace create/start step must proceed without token fetch step. If user creates another workspace or starts existed workspace from an scm provider which name is stored in the config-map, do not ask the authorisation as it was already rejected once.
2023-10-12 15:59:42 +03:00
dependabot[bot] 386f84962d
chore(deps): bump mockito-testng from 0.4.13 to 0.5.2 (#509)
* chore(deps): bump mockito-testng from 0.4.13 to 0.5.0

Bumps [mockito-testng](https://github.com/mockito/mockito-testng) from 0.4.13 to 0.5.0.
- [Release notes](https://github.com/mockito/mockito-testng/releases)
- [Changelog](https://github.com/mockito/mockito-testng/blob/master/docs/release-notes.md)
- [Commits](https://github.com/mockito/mockito-testng/compare/v0.4.13...v0.5.0)

---
updated-dependencies:
- dependency-name: org.mockito:mockito-testng
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update pom.xml

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Igor Vinokur <ivinokur@redhat.com>
2023-10-12 15:42:17 +03:00
Igor Vinokur f27f8b1589
Update minor maven dependencies (#577) 2023-10-12 14:38:05 +03:00
Igor 5d645e1d3c Update contributing.md file 2023-09-29 18:07:57 +02:00
Igor ea9bb95f7c Add CONTRIBUTING.md file 2023-09-29 18:07:57 +02:00
Mykhailo Kuznietsov 2f2a939823 chore: Bump to 7.76.0-SNAPSHOT in main
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2023-09-28 10:13:22 +02:00
Igor Vinokur b2ff110da5
Encode the authentication reject error to build a proper callback url (#568)
Encode the &error_code=access_denied query param for the callback url in order to fix the bug when the authentication request appears again if it was rejected.
2023-09-27 14:20:27 +03:00
Nick Boldt 46592e65ce
chore: update to latest com.fasterxml.jackson 2.14.z (CRW-4790, #22548) (#571)
Change-Id: Iacdbd86ccc1480c8badbbc15ffe48bdb01206e44

Signed-off-by: Nick Boldt <nboldt@redhat.com>
2023-09-25 16:53:30 -03:00
che-bot 9a553b6344
chore: Update from ubi8-minimal:8.8-1037 to ubi8-minimal:8.8-1072 (#570)
Signed-off-by: Nick Boldt <nboldt@redhat.com>
Co-authored-by: Nick Boldt <nboldt@redhat.com>
2023-09-25 10:17:02 -03:00
Anatolii Bazko a28e1553d2
chore: Add tests to start a workspace from raw devfile and ssh urls f… (#569)
* chore: Add tests to start a workspace from raw devfile and ssh urls for GITEA provider

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-09-25 14:54:49 +02:00
Igor Vinokur b1da9ef121
Add an SSH Factory parameter resolver for unsupported SCM providers (#567)
Return the SSH factory resolver in order to handle SSH urls from unsupported SCM providers.
Add a priority value for all factory resolvers to be able to control resolver's priority.

---------

Co-authored-by: Aleksandr Shmaraiev <oshmarai@redhat.com>
2023-09-22 17:09:48 +03:00
Igor Vinokur 261be8f99d
Add a null check before reading GitHub response (#563)
Add a null check to prevent NullPointer exception while reading body from the GitHub API response. response.body() should not return null according to the java documentation, but the NullPointer exception was found in the customer debug logs
2023-09-21 10:48:32 +03:00
Anatolii Bazko a3cceea640
chore: Add tests to start a workspace from raw devfile and ssh urls when PAT configured (#566)
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-09-18 11:18:37 +02:00
Anatolii Bazko e337edc50f
chore: Add Eclipse Che server azure and gitlab providers tests (#564)
* chore: Add Eclipse Che server azure and gitlab providers tests

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-09-15 15:01:10 +02:00
Anatolii Bazko 3bac40d2a3
chore: Add PR checks to test workspace startup from raw devfile and s… (#562)
* chore: Add PR checks to test workspace startup from raw devfile and ssh urls for GitHub provider

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-09-14 10:12:58 +02:00
Anatolii Bazko f67bbbd52a
chore: Add PR check for BitBucket to start a workspace from a raw and… (#558)
* chore: Add PR check for BitBucket to start a workspace from a raw and ssh urls

Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-09-12 15:45:41 +02:00
Nick Boldt 74924f84ae
chore: tweak dockerfile; (#560)
use latest ocp 4.12 oc binary;
fix typo in pom.xml
bump to latest mavn 3.9.4

Change-Id: Ie9d9aea49e7e46bec4814477489450b277f926b4

Signed-off-by: Nick Boldt <nboldt@redhat.com>
2023-09-12 09:17:48 -03:00
che-bot 033d310b0d
chore: Bump to 7.75.0-SNAPSHOT in main (#554)
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
Co-authored-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2023-09-11 19:17:12 -03:00
Shmaraiev Oleksandr 8731ac153a
Add tests to check 'Azure DevOps' provider in PR checks (#552)
* Add tests to check git-flow on 'azure-devops' git-provider

* Refactor methods

* Upfdate tests

* Update 'pat-secret.yaml' file

* Update the '.ci/openshift-ci/Dockerfile'

* Exclude 'testFactoryResolverNoPatOAuth' from the test

* Fix variable name

* Refactor '<testClone>' methods to handle errors more informative
2023-09-11 15:15:17 -03:00
Shmaraiev Oleksandr a6ea66285f
Update command 'dnf install' (#556) 2023-09-08 10:27:14 +03:00
Shmaraiev Oleksandr 7686dab07a
Update Dockerfile to fix an error 'node is not installed' (#555)
* Update Dockerfile to fix an error

* Fix the image
2023-09-07 13:53:32 +03:00
Igor Vinokur 9d43803100
Simplify the Raw devfile filename check (#548)
Do not check the Raw devfile file name but check if the url ends with .yaml before using the Raw devfile url resolver.
2023-09-06 14:15:11 +03:00
Igor Vinokur ea67092cbc
Fix failing unit tests (#553)
Signed-off-by: Igor <ivinokur@redhat.com>
2023-09-06 12:48:04 +03:00
Igor Vinokur 6edfa3910f
Apply permanetn `ref` query param to the GitLab raw file location request (#545)
A user claims that he couldn't start a workspace form GitLab repository because of the raw file location request doesn't contain the ref query parameter. Rework the way of generating the GitLab raw file location function to permanently add the ref query param.
2023-09-05 12:51:27 +03:00
Igor Vinokur da5174bf17
Duplicate creating a git-credentials secret on token fetch (#551)
Duplicate the git-credentials secret creation step on create personal access token secret. Currently this step is performed on workspace provision step but in this case the PAT secret might be initialised when the provision is finished. In order to synchronise the personal access token secret and git credentials secret creation step duplicate the git credentials secret creation step after the PAT secret creation step.
Refactor the get(scmServerUrl) function in the KubernetesPersonalAccessTokenManager class
2023-09-05 12:49:09 +03:00
Igor Vinokur afd7cad8b8
Set original message and stack trace to a Runtime Exception DTO (#550)
In order to extend the predefined error message in the dashboard, pass original message and stack trace to a Runtime Exception DTO
2023-08-30 09:35:08 +03:00
Igor Vinokur ce6ed7e9c0
Update io.fabric8.kubernetes-client version to latest (#549) 2023-08-29 16:38:31 +03:00
Igor Vinokur 7d0cfb306c
Support SSH urls (#539)
Extend each SCM provider implementation to support SSH urls.
2023-08-27 16:17:13 +03:00
Mykhailo Kuznietsov 8d19ea8046 chore: Bump to 7.74.0-SNAPSHOT in main
Signed-off-by: Mykhailo Kuznietsov <mkuznets@redhat.com>
2023-08-23 15:09:29 +02:00
Anatolii Bazko ff90b44018
fix: Improve BitBucket token scope validation (#547)
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
2023-08-22 09:17:54 +02:00
616 changed files with 7938 additions and 42599 deletions

View File

@ -11,18 +11,19 @@
# Red Hat, Inc. - initial API and implementation
# Dockerfile to bootstrap build and test in openshift-ci
FROM registry.ci.openshift.org/openshift/release:golang-1.18
# hadolint ignore=DL3002
USER 0
SHELL ["/bin/bash", "-c"]
# Install yq, kubectl, chectl cli used by olm/olm.sh script.
RUN yum install --assumeyes -d1 python3-pip httpd-tools && \
# hadolint ignore=DL3041
# Install yq, kubectl, chectl cli.
RUN yum install --assumeyes -d1 psmisc python3-pip httpd-tools nodejs && \
pip3 install --upgrade setuptools && \
pip3 install yq && \
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \
chmod +x ./kubectl && \
mv ./kubectl /usr/local/bin && \
bash <(curl -sL https://www.eclipse.org/che/chectl/) --channel=next && \
curl https://mirror.openshift.com/pub/openshift-v4/clients/ocp/4.12.4/openshift-client-linux.tar.gz | tar xvzf - -C /usr/local/bin/ oc && \
chmod ug+x /usr/local/bin/oc
bash <(curl -sL https://che-incubator.github.io/chectl/install.sh) --channel=next

19
.ci/openshift-ci/ca.crt Normal file
View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDDDCCAfSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtpbmdy
ZXNzLW9wZXJhdG9yQDE3MDI5MTczMzkwHhcNMjMxMjE4MTYzNTM4WhcNMjUxMjE3
MTYzNTM5WjAmMSQwIgYDVQQDDBtpbmdyZXNzLW9wZXJhdG9yQDE3MDI5MTczMzkw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDVfcIyqKLYcrmieDOCvAq
RKFR0PXqjl54DyfhkP7TC/rA4WMaJgYamYNNRcy4rOb+i3P1yepeVlXj+4gka41W
fh1QghqDGPpQTF7I8SDhnz3qdQymgSSkrxBWOGgJZRG3Gd50CNeh+ADdNlOxzZhJ
c1HI9/36Zp0M7RHLNwrYzKf/Scrcl3t/Ps4KHKsNtjNygnPSTjGwza5TTTAvGQ+h
3+c+bKJHZp6VFoEpubmBfCG8x+vJwBNI+YauXwti9EqFutnAbOiQ4aOvqQYINngV
OQTOg3xnifnooaR2iZPOtxPLUDMydHP9sDVNGLICpnKcFN6x5JKq1fAuwOAMRMQr
AgMBAAGjRTBDMA4GA1UdDwEB/wQEAwICpDASBgNVHRMBAf8ECDAGAQH/AgEAMB0G
A1UdDgQWBBRQfZkM6C20GT1YiTiS694vRPP2MDANBgkqhkiG9w0BAQsFAAOCAQEA
qd9ug2Bo2s3CG0qjNtk19WYYAuwkEMZU9L/FbSfmPkkOTbrZB71ofZbVan8Dx9/W
SfbkN1eJQNxd7QIDlExKEW2ufJIMCDe6haLHV8x+z3fISHg3wMUCPtadLG/exafy
agfj8PQgnJ1sbA/fKl0rqcVYuIihZ0DdMe28Yj92BFcs5+TXzVYzjyeIGonUZrCR
LtW2CxV7Ngue9pkWGsqQSlRwzp3knYfZxeQLneZcGlsSV4r9LOKIAA/MhBGgpwVc
zrh7L93jajHD1AD0sRdUQp4VVhysXVmMMSAjaLkqHsvSyJp7yKJOmrts6a274qbU
J1E6cXqtfF0NwRo2D9BouQ==
-----END CERTIFICATE-----

View File

@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# Copyright (c) 2023-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
@ -32,48 +32,105 @@ export PRIVATE_REPO_WORKSPACE_NAME=${PRIVATE_REPO_WORKSPACE_NAME:-"private-repo-
export PUBLIC_PROJECT_NAME=${PUBLIC_PROJECT_NAME:-"public-repo"}
export PRIVATE_PROJECT_NAME=${PRIVATE_PROJECT_NAME:-"private-repo"}
export YAML_FILE_NAME=${YAML_FILE_NAME:-"devfile.yaml"}
export CUSTOM_CONFIG_MAP_NAME=${CUSTOM_CONFIG_MAP_NAME:-"custom-ca-certificates"}
export GIT_SSL_CONFIG_MAP_NAME=${GIT_SSL_CONFIG_MAP_NAME:-"che-self-signed-cert"}
provisionOpenShiftOAuthUser() {
echo -e "[INFO] Provisioning Openshift OAuth user"
echo "------- [INFO] Start provisioning Openshift OAuth user -------"
htpasswd -c -B -b users.htpasswd ${OCP_ADMIN_USER_NAME} ${OCP_LOGIN_PASSWORD}
htpasswd -b users.htpasswd ${OCP_NON_ADMIN_USER_NAME} ${OCP_LOGIN_PASSWORD}
oc create secret generic htpass-secret --from-file=htpasswd="users.htpasswd" -n openshift-config
oc apply -f ".ci/openshift-ci/htpasswdProvider.yaml"
oc adm policy add-cluster-role-to-user cluster-admin ${OCP_ADMIN_USER_NAME}
echo -e "[INFO] Waiting for htpasswd auth to be working up to 5 minutes"
echo "------- [INFO] Waiting for htpasswd auth to be working up to 5 minutes -------"
CURRENT_TIME=$(date +%s)
ENDTIME=$((CURRENT_TIME + 300))
while [ "$(date +%s)" -lt $ENDTIME ]; do
if oc login -u=${OCP_ADMIN_USER_NAME} -p=${OCP_LOGIN_PASSWORD} --insecure-skip-tls-verify=false; then
break
echo "======= [INFO] OpenShift OAuth htpasswd is configured. =======
======= [INFO] Login to OCP cluster with admin user credentials is success.======="
return 0
fi
sleep 10
sleep 5
done
echo "####### [ERROR] Error occurred while waiting OpenShift OAuth htpasswd setup. Try to rerun test. #######"
exit 1
}
configureGitSelfSignedCertificate() {
echo "------- [INFO] Configure self-signed certificate for Git provider -------"
oc adm new-project ${CHE_NAMESPACE}
oc project ${CHE_NAMESPACE}
echo "------- [INFO] Create ConfigMap with the required TLS certificate -------"
oc create configmap ${CUSTOM_CONFIG_MAP_NAME} --from-file=.ci/openshift-ci/ca.crt
oc label configmap ${CUSTOM_CONFIG_MAP_NAME} app.kubernetes.io/part-of=che.eclipse.org app.kubernetes.io/component=ca-bundle
echo "------- [INFO] Create ConfigMap to support Git repositories with self-signed certificates -------"
oc create configmap ${GIT_SSL_CONFIG_MAP_NAME} --from-file=.ci/openshift-ci/ca.crt --from-literal=githost=${GIT_PROVIDER_URL}
oc label configmap ${GIT_SSL_CONFIG_MAP_NAME} app.kubernetes.io/part-of=che.eclipse.org
echo "======= [INFO] ConfigMaps are configured ======="
}
createCustomResourcesFile() {
echo "------- [INFO] Create custom resourses file -------"
cat > custom-resources.yaml <<-END
apiVersion: org.eclipse.che/v2
spec:
devEnvironments:
maxNumberOfRunningWorkspacesPerUser: 10000
maxNumberOfRunningWorkspacesPerUser: 10000
END
echo "Generated custom resources file"
echo "======= [INFO] Generated custom resources file ======="
cat custom-resources.yaml
}
patchCustomResourcesFile() {
echo "------- [INFO] Edit the custom resources file to add 'gitTrustedCertsConfigMapName' -------"
yq -y '.spec.devEnvironments.trustedCerts += {"gitTrustedCertsConfigMapName": "'${GIT_SSL_CONFIG_MAP_NAME}'"}' custom-resources.yaml -i
echo "======= [INFO] Patched custom resources file ======="
cat custom-resources.yaml
}
deployChe() {
echo "------- [INFO] Start installing Eclipse Che -------"
chectl server:deploy --cheimage=$CHE_SERVER_IMAGE \
--che-operator-cr-patch-yaml=custom-resources.yaml \
--platform=openshift \
--telemetry=off \
--batch
waitFinishDeploymentCheServer
echo "======= [INFO] Eclipse Che is successfully installed ======="
}
waitFinishDeploymentCheServer() {
CURRENT_TIME=$(date +%s)
ENDTIME=$((CURRENT_TIME + 60))
while [ "$(date +%s)" -lt $ENDTIME ]; do
podCheServerName=$(oc get pod -n ${CHE_NAMESPACE} -l component=che | grep "che" | awk '{ print $1 }')
echo "Pod Che_Server: $podCheServerName"
count=$(echo "$podCheServerName" | wc -l)
if [ $count -eq 1 ]; then
echo "------- [INFO] Only one Che Server pod is left. -------"
return 0
fi
echo "------- [INFO] Waiting until only one Che Server pod remains. -------"
sleep 5
done
echo "####### [ERROR] Error occurred while waiting for only one Che Server pod. #######"
exit 1
}
# this command starts port forwarding between the local machine and the che-host service in the OpenShift cluster.
forwardPortToService() {
echo "------- [INFO] Start forwarding between the local machine and the che-host service -------"
oc port-forward service/che-host ${CHE_FORWARDED_PORT}:8080 -n ${CHE_NAMESPACE} &
sleep 3s
}
@ -98,44 +155,40 @@ requestFactoryResolverGitRepoUrl() {
# check that factory resolver returns correct value without any PAT/OAuth setup
testFactoryResolverNoPatOAuth() {
PUBLIC_REPO_URL=$1
PRIVATE_REPO_URL=$2
echo "------- [INFO] Check factory resolver for public repository with NO PAT/OAuth setup -------"
testFactoryResolverResponse $1 200
echo "[INFO] Check factory resolver for public repository with NO PAT/OAuth setup"
if [ "$(requestFactoryResolverGitRepoUrl ${PUBLIC_REPO_URL} | grep "HTTP/1.1 200")" ]; then
echo "[INFO] Factory resolver returned 'HTTP/1.1 200' status code."
else
echo "[ERROR] Factory resolver returned wrong status code. Expected: HTTP/1.1 200."
exit 1
fi
echo "------- [INFO] Check factory resolver for private repository with NO PAT/OAuth setup -------"
testFactoryResolverResponse $2 500
}
echo "[INFO] Check factory resolver for private repository with NO PAT/OAuth setup"
if [ "$(requestFactoryResolverGitRepoUrl ${PRIVATE_REPO_URL} | grep "HTTP/1.1 400")" ]; then
echo "[INFO] Factory resolver returned 'HTTP/1.1 400' status code. Expected client side error."
else
echo "[ERROR] Factory resolver returned wrong status code. Expected 'HTTP/1.1 400'."
exit 1
fi
# check that raw devfile url factory resolver returns correct value without any PAT/OAuth setup
testFactoryResolverNoPatOAuthRaw() {
echo "------- [INFO] Check factory resolver for public repository with NO PAT/OAuth setup -------"
testFactoryResolverResponse $1 200
echo "------- [INFO] Check factory resolver for private repository with NO PAT/OAuth setup -------"
testFactoryResolverResponse $2 400
}
# check that factory resolver returns correct value with PAT/OAuth setup
testFactoryResolverWithPatOAuth() {
PUBLIC_REPO_URL=$1
PRIVATE_REPO_URL=$2
echo "------- [INFO] Check factory resolver for public repository with PAT/OAuth setup -------"
testFactoryResolverResponse $1 200
echo "[INFO] Check factory resolver for public repository with PAT/OAuth setup"
if [ "$(requestFactoryResolverGitRepoUrl ${PUBLIC_REPO_URL} | grep "HTTP/1.1 200")" ]; then
echo "[INFO] Factory resolver returned 'HTTP/1.1 200' status code."
else
echo "[ERROR] Factory resolver returned wrong status code. Expected: HTTP/1.1 200"
exit 1
fi
echo "------- [INFO] Check factory resolver for private repository with PAT/OAuth setup -------"
testFactoryResolverResponse $2 200
}
echo "[INFO] Check factory resolver for private repository with PAT/OAuth setup"
if [ "$(requestFactoryResolverGitRepoUrl ${PRIVATE_REPO_URL} | grep "HTTP/1.1 200")" ]; then
echo "[INFO] Factory resolver returned 'HTTP/1.1 200' status code."
testFactoryResolverResponse() {
URL=$1
RESPONSE_CODE=$2
if [ "$(requestFactoryResolverGitRepoUrl ${URL} | grep "HTTP/1.1 ${RESPONSE_CODE}")" ]; then
echo "======= [INFO] Factory resolver returned 'HTTP/1.1 ${RESPONSE_CODE}' status code. Expected client side response. ======="
else
echo "[ERROR] Factory resolver returned wrong status code. Expected: HTTP/1.1 200"
echo "####### [ERROR] Factory resolver returned wrong status code. Expected: HTTP/1.1 ${RESPONSE_CODE}. #######
####### Cause possible: PR code regress or service is changed. Need to investigate it. #######"
exit 1
fi
}
@ -153,12 +206,19 @@ requestProvisionNamespace() {
initUserNamespace() {
OCP_USER_NAME=$1
echo "[INFO] Initialize user namespace"
echo "------- [INFO] Initialize user namespace -------"
oc login -u=${OCP_USER_NAME} -p=${OCP_LOGIN_PASSWORD} --insecure-skip-tls-verify=false
if [ "$(requestProvisionNamespace | grep "HTTP/1.1 200")" ]; then
echo "[INFO] Request provision user namespace returned 'HTTP/1.1 200' status code."
request_result=$(requestProvisionNamespace) || true
if [ -z "$request_result" ]; then
echo "####### [ERROR] Cause possible: lost connection to pod, this is an infrastructure problem. Try to rerun the test. #######"
exit 1
elif [ "$(echo "$request_result" | grep "HTTP/1.1 200")" ]; then
echo "======= [INFO] Request provision user namespace returned 'HTTP/1.1 200' status code. User namespace is created. ======="
else
echo "[ERROR] Request provision user namespace returned wrong status code. Expected: HTTP/1.1 200"
echo "####### [ERROR] Request provision user namespace returned wrong status code. Expected: HTTP/1.1 200. #######
####### User namespace creation failed. Cause possible: PR code regression or service is changed. Need to investigate. #######"
exit 1
fi
}
@ -166,10 +226,9 @@ initUserNamespace() {
setupPersonalAccessToken() {
GIT_PROVIDER_TYPE=$1
GIT_PROVIDER_URL=$2
GIT_PROVIDER_USER_ID=$3
GIT_PROVIDER_PAT=$4
GIT_PROVIDER_PAT=$3
echo "[INFO] Setup Personal Access Token Secret"
echo "------- [INFO] Setup Personal Access Token Secret -------"
oc project ${USER_CHE_NAMESPACE}
CHE_USER_ID=$(oc get secret user-profile -o jsonpath='{.data.id}' | base64 -d)
ENCODED_PAT=$(echo -n ${GIT_PROVIDER_PAT} | base64)
@ -179,12 +238,115 @@ setupPersonalAccessToken() {
sed -i "s#che-user-id#${CHE_USER_ID}#g" pat-secret.yaml
sed -i "s#git-provider-name#${GIT_PROVIDER_TYPE}#g" pat-secret.yaml
sed -i "s#git-provider-url#${GIT_PROVIDER_URL}#g" pat-secret.yaml
sed -i "s#git-provider-user-id#${GIT_PROVIDER_USER_ID}#g" pat-secret.yaml
sed -i "s#encoded-access-token#${ENCODED_PAT}#g" pat-secret.yaml
if [ "${GIT_PROVIDER_TYPE}" == "azure-devops" ]; then
sed -i "s#''#${GIT_PROVIDER_USERNAME}#g" pat-secret.yaml
fi
cat pat-secret.yaml
oc apply -f pat-secret.yaml -n ${USER_CHE_NAMESPACE}
echo "======= [INFO] Personal Access Token is created. ======="
}
setupSSHKeyPairs() {
GIT_PRIVATE_KEY=$1
GIT_PUBLIC_KEY=$2
echo "------- [INFO] Setup SSH Key Pairs Secret "-------
oc project ${USER_CHE_NAMESPACE}
ENCODED_GIT_PRIVATE_KEY=$(echo "${GIT_PRIVATE_KEY}" | base64 -w 0)
ENCODED_GIT_PUBLIC_KEY=$(echo "${GIT_PUBLIC_KEY}" | base64 -w 0)
cat .ci/openshift-ci/ssh-secret.yaml > ssh-secret.yaml
# patch the ssh-secret.yaml file
sed -i "s#ssh_private_key#${ENCODED_GIT_PRIVATE_KEY}#g" ssh-secret.yaml
sed -i "s#ssh_public_key#${ENCODED_GIT_PUBLIC_KEY}#g" ssh-secret.yaml
cat ssh-secret.yaml
oc apply -f ssh-secret.yaml -n ${USER_CHE_NAMESPACE}
echo "======= [INFO] SSH Secret is created. ======="
}
# Only for GitLab server administrator users
createOAuthApplicationGitLabServer() {
ADMIN_ACCESS_TOKEN=$1
CHE_URL=https://$(oc get route -n ${CHE_NAMESPACE} che -o jsonpath='{.spec.host}')
echo "------- [INFO] Create OAuth Application -------"
response=$(curl -k -X POST \
${GIT_PROVIDER_URL}/api/v4/applications \
-H "PRIVATE-TOKEN: ${ADMIN_ACCESS_TOKEN}" \
-d "name=${APPLICATION_NAME}" \
-d "redirect_uri=${CHE_URL}/api/oauth/callback" \
-d "scopes=api write_repository openid")
echo "------- [INFO] Response of the created OAuth Application -------"
OAUTH_ID=$(echo "$response" | jq -r '.id')
APPLICATION_ID=$(echo "$response" | jq -r '.application_id')
APPLICATION_SECRET=$(echo "$response" | jq -r '.secret')
}
# Only for GitLab server administrator users
deleteOAuthApplicationGitLabServer() {
OAUTH_ID=$1
ADMIN_ACCESS_TOKEN=$2
echo "------- [INFO] Delete OAuth Application -------"
curl -i -k -X DELETE \
${GIT_PROVIDER_URL}/api/v4/applications/${OAUTH_ID} \
-H "PRIVATE-TOKEN: ${ADMIN_ACCESS_TOKEN}"
echo "======= [INFO] OAuth Application is deleted ======="
}
# Only for GitLab server
revokeAuthorizedOAuthApplication() {
APPLICATION_ID=$1
APPLICATION_SECRET=$2
echo "------- [INFO] Revoke authorized OAuth application -------"
oc project ${USER_CHE_NAMESPACE}
OAUTH_TOKEN_NAME=$(oc get secret | grep 'personal-access-token'| awk 'NR==1 { print $1 }')
OAUTH_TOKEN=$(oc get secret $OAUTH_TOKEN_NAME -o jsonpath='{.data.token}' | base64 -d)
curl -i -k -X POST \
${GIT_PROVIDER_URL}/oauth/revoke \
-d "client_id=${APPLICATION_ID}" \
-d "client_secret=${APPLICATION_SECRET}" \
-d "token=${OAUTH_TOKEN}"
echo "======= [INFO] Authorized OAuth application is revoked ======="
}
# Only for GitLab server
setupOAuthSecret() {
APPLICATION_ID=$1
APPLICATION_SECRET=$2
echo "------- [INFO] Setup OAuth Secret -------"
oc login -u=${OCP_ADMIN_USER_NAME} -p=${OCP_LOGIN_PASSWORD} --insecure-skip-tls-verify=false
oc project ${CHE_NAMESPACE}
SERVER_POD=$(oc get pod -l component=che | grep "che" | awk 'NR==1 { print $1 }')
ENCODED_APP_ID=$(echo -n "${APPLICATION_ID}" | base64 -w 0)
ENCODED_APP_SECRET=$(echo -n "${APPLICATION_SECRET}" | base64 -w 0)
cat .ci/openshift-ci/oauth-secret.yaml > oauth-secret.yaml
# patch the oauth-secret.yaml file
sed -i "s#git-provider-url#${GIT_PROVIDER_URL}#g" oauth-secret.yaml
sed -i "s#encoded-application-id#${ENCODED_APP_ID}#g" oauth-secret.yaml
sed -i "s#encoded-application-secret#${ENCODED_APP_SECRET}#g" oauth-secret.yaml
cat oauth-secret.yaml
oc apply -f oauth-secret.yaml -n ${CHE_NAMESPACE}
echo "------- [INFO] Wait updating deployment after create OAuth secret -------"
oc wait --for=delete pod/${SERVER_POD} --timeout=120s
}
runTestWorkspaceWithGitRepoUrl() {
@ -196,6 +358,7 @@ runTestWorkspaceWithGitRepoUrl() {
oc project ${OCP_USER_NAMESPACE}
cat .ci/openshift-ci/devworkspace-test.yaml > devworkspace-test.yaml
echo "------- [INFO] Preparing 'devworkspace-test.yaml' and run test workspace -------"
# patch the devworkspace-test.yaml file
sed -i "s#ws-name#${WS_NAME}#g" devworkspace-test.yaml
sed -i "s#project-name#${PROJECT_NAME}#g" devworkspace-test.yaml
@ -205,7 +368,7 @@ runTestWorkspaceWithGitRepoUrl() {
oc apply -f devworkspace-test.yaml -n ${OCP_USER_NAMESPACE}
oc wait -n ${OCP_USER_NAMESPACE} --for=condition=Ready dw ${WS_NAME} --timeout=360s
echo "[INFO] Test workspace is run"
echo "======= [INFO] Test workspace is run ======="
}
testProjectIsCloned() {
@ -214,46 +377,131 @@ testProjectIsCloned() {
WORKSPACE_POD_NAME=$(oc get pods -n ${OCP_USER_NAMESPACE} | grep workspace | awk '{print $1}')
if oc exec -it -n ${OCP_USER_NAMESPACE} ${WORKSPACE_POD_NAME} -- test -f /projects/${PROJECT_NAME}/${YAML_FILE_NAME}; then
echo "[INFO] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} exists."
echo "======= [INFO] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} exists. ======="
else
echo "[ERROR] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} does not exist."
echo "======= [INFO] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} is absent. ======="
return 1
fi
}
testGitCredentials() {
testGitCredentialsData() {
OCP_USER_NAMESPACE=$1
GIT_PROVIDER_PAT=$2
GIT_PROVIDER_URL=$3
echo "[INFO] Check the 'git credentials' is in a workspace"
gitCredentials="${GIT_PROVIDER_USERNAME}:${GIT_PROVIDER_PAT}"
echo "------- [INFO] Check the 'git credentials' is in a workspace -------"
hostName="${GIT_PROVIDER_URL#https://}"
if [ "${GIT_PROVIDER_TYPE}" == "azure-devops" ]; then
userName="username"
else
userName=${GIT_PROVIDER_USERNAME}
fi
gitCredentials="https://${userName}:${GIT_PROVIDER_PAT}@${hostName}"
WORKSPACE_POD_NAME=$(oc get pods -n ${OCP_USER_NAMESPACE} | grep workspace | awk '{print $1}')
if oc exec -it -n ${OCP_USER_NAMESPACE} ${WORKSPACE_POD_NAME} -- cat /.git-credentials/credentials | grep -q ${gitCredentials}; then
echo "[INFO] Git credentials file '/.git-credentials/credentials' exists and has the expected content."
echo "======= [INFO] Git credentials file '/.git-credentials/credentials' exists and has the expected content. ======="
else
echo "[ERROR] Git credentials file '/.git-credentials/credentials' does not exist or has incorrect content."
return 1
echo "####### [ERROR] Git credentials file '/.git-credentials/credentials' does not exist or has incorrect content. ######
###### Cause possible: PR code regress or service is changed. Need to investigate it. #######"
exit 1
fi
}
deleteTestWorkspace() {
WS_NAME=$1
OCP_USER_NAMESPACE=$2
echo "------- [INFO] Delete test workspace -------"
oc delete dw ${WS_NAME} -n ${OCP_USER_NAMESPACE}
}
startOAuthFactoryTest() {
CHE_URL=https://$(oc get route -n ${CHE_NAMESPACE} che -o jsonpath='{.spec.host}')
# patch oauth-factory-test.yaml
cat .ci/openshift-ci/pod-oauth-factory-test.yaml > oauth-factory-test.yaml
sed -i "s#CHE_URL#${CHE_URL}#g" oauth-factory-test.yaml
sed -i "s#CHE-NAMESPACE#${CHE_NAMESPACE}#g" oauth-factory-test.yaml
sed -i "s#OCP_USER_NAME#${OCP_NON_ADMIN_USER_NAME}#g" oauth-factory-test.yaml
sed -i "s#OCP_USER_PASSWORD#${OCP_LOGIN_PASSWORD}#g" oauth-factory-test.yaml
sed -i "s#FACTORY_REPO_URL#${PRIVATE_REPO_URL}#g" oauth-factory-test.yaml
sed -i "s#GIT_BRANCH#${GIT_REPO_BRANCH}#g" oauth-factory-test.yaml
sed -i "s#GIT_PROVIDER_TYPE#${GIT_PROVIDER_TYPE}#g" oauth-factory-test.yaml
sed -i "s#GIT_PROVIDER_USER_NAME#${GIT_PROVIDER_LOGIN}#g" oauth-factory-test.yaml
sed -i "s#GIT_PROVIDER_USER_PASSWORD#${GIT_PROVIDER_PASSWORD}#g" oauth-factory-test.yaml
echo "------- [INFO] Applying the following patched OAuth Factory Test Pod: -------"
cat oauth-factory-test.yaml
echo "[INFO] --------------------------------------------------"
oc apply -f oauth-factory-test.yaml
# wait for the pod to start
n=0
while [ $n -le 120 ]
do
PHASE=$(oc get pod -n ${CHE_NAMESPACE} ${TEST_POD_NAME} \
--template='{{ .status.phase }}')
if [[ ${PHASE} == "Running" ]]; then
echo "======= [INFO] Factory test started successfully. ======="
return
fi
sleep 5
n=$(( n+1 ))
done
echo "####### [ERROR] Failed to start Factory test. #######
###### Cause possible: an infrastructure problem, pod could not start, try to rerun the test. #######"
exit 1
}
startSmokeTest() {
CHE_URL=https://$(oc get route -n ${CHE_NAMESPACE} che -o jsonpath='{.spec.host}')
# patch che-smoke-test.yaml
cat .ci/openshift-ci/pod-che-smoke-test.yaml > che-smoke-test.yaml
sed -i "s#CHE_URL#${CHE_URL}#g" che-smoke-test.yaml
sed -i "s#CHE-NAMESPACE#${CHE_NAMESPACE}#g" che-smoke-test.yaml
sed -i "s#OCP_USER_NAME#${OCP_NON_ADMIN_USER_NAME}#g" che-smoke-test.yaml
sed -i "s#OCP_USER_PASSWORD#${OCP_LOGIN_PASSWORD}#g" che-smoke-test.yaml
echo "------- [INFO] Applying the following patched Smoke Test Pod: -------"
cat che-smoke-test.yaml
echo "[INFO] --------------------------------------------------"
oc apply -f che-smoke-test.yaml
# wait for the pod to start
n=0
while [ $n -le 120 ]
do
PHASE=$(oc get pod -n ${CHE_NAMESPACE} ${TEST_POD_NAME} \
--template='{{ .status.phase }}')
if [[ ${PHASE} == "Running" ]]; then
echo "======= [INFO] Smoke test started successfully. ======="
return
fi
sleep 5
n=$(( n+1 ))
done
echo "####### [ERROR] Failed to start Smoke test. #######
####### Cause possible: an infrastructure problem, pod could not start, try to rerun the test. #######"
exit 1
}
# Catch the finish of the job and write logs in artifacts.
catchFinish() {
local RESULT=$?
killProcessByPort
if [ "$RESULT" != "0" ]; then
set +e
collectEclipseCheLogs
set -e
fi
[[ "${RESULT}" != "0" ]] && echo "[ERROR] Job failed." || echo "[INFO] Job completed successfully."
echo "------- [INFO] Terminate the process after finish the test script. -------"
set +e
killProcessByPort
set -e
[[ "${RESULT}" != "0" ]] && echo "####### [ERROR] Job failed. #######" || echo "####### [INFO] Job completed successfully. #######"
exit $RESULT
}
@ -261,45 +509,69 @@ collectEclipseCheLogs() {
mkdir -p ${ARTIFACTS_DIR}/che-logs
# Collect all Eclipse Che logs and cluster CR
chectl server:logs -n $CHE_NAMESPACE --directory ${ARTIFACTS_DIR}/che-logs --telemetry off
oc login -u=${OCP_ADMIN_USER_NAME} -p=${OCP_LOGIN_PASSWORD} --insecure-skip-tls-verify=false
oc get checluster -o yaml -n $CHE_NAMESPACE > "${ARTIFACTS_DIR}/che-cluster.yaml"
chectl server:logs -n $CHE_NAMESPACE --directory ${ARTIFACTS_DIR}/che-logs --telemetry off
}
testClonePublicRepoNoPatOAuth() {
collectLogs() {
echo "------- [INFO] Waiting until test pod finished. -------"
oc logs -n ${CHE_NAMESPACE} ${TEST_POD_NAME} -c test -f
sleep 3
# Download artifacts
set +e
echo -------" [INFO] Collect all Eclipse Che logs and cluster CR. -------"
collectEclipseCheLogs
echo "------- [INFO] Downloading test report. -------"
mkdir -p ${ARTIFACTS_DIR}/e2e
oc rsync -n ${CHE_NAMESPACE} ${TEST_POD_NAME}:/tmp/e2e/report/ ${ARTIFACTS_DIR}/e2e -c download-reports
oc exec -n ${CHE_NAMESPACE} ${TEST_POD_NAME} -c download-reports -- touch /tmp/done
# Revoke and delete the OAuth application
if [[ ${TEST_POD_NAME} == "oauth-factory-test" ]]; then
revokeAuthorizedOAuthApplication ${APPLICATION_ID} ${APPLICATION_SECRET}
deleteOAuthApplicationGitLabServer ${OAUTH_ID} ${ADMIN_ACCESS_TOKEN}
fi
set -e
EXIT_CODE=$(oc logs -n ${CHE_NAMESPACE} ${TEST_POD_NAME} -c test | grep EXIT_CODE)
if [[ ${EXIT_CODE} != "+ EXIT_CODE=0" ]]; then
echo "####### [ERROR] GUI test failed. Job failed. #######
###### Cause possible: PR code regress or service is changed. Need to investigate it. #######"
exit 1
fi
echo "======= [INFO] Job completed successfully. ======="
}
testCloneGitRepoNoProjectExists() {
WS_NAME=$1
PROJECT_NAME=$2
GIT_REPO_URL=$3
OCP_USER_NAMESPACE=$4
runTestWorkspaceWithGitRepoUrl ${WS_NAME} ${PROJECT_NAME} ${GIT_REPO_URL} ${OCP_USER_NAMESPACE}
echo "------- [INFO] Check the private repository is NOT cloned with NO PAT/OAuth setup. -------"
testProjectIsCloned ${PROJECT_NAME} ${OCP_USER_NAMESPACE} && \
{ echo "####### [ERROR] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} should NOT be present. #######
####### Cause possible: PR code regress or service is changed. Need to investigate it. #######" && exit 1; }
echo "======= [INFO] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} is NOT present. This is EXPECTED. ======="
}
# Test that the repository is cloned when PAT, OAuth or SSH is configured
testCloneGitRepoProjectShouldExists() {
WS_NAME=$1
PROJECT_NAME=$2
GIT_REPO_URL=$3
OCP_USER_NAMESPACE=$4
runTestWorkspaceWithGitRepoUrl ${WS_NAME} ${PROJECT_NAME} ${GIT_REPO_URL} ${OCP_USER_NAMESPACE}
echo "[INFO] Check the public repository is cloned with NO PAT/OAuth setup"
testProjectIsCloned ${PROJECT_NAME} ${OCP_USER_NAMESPACE} || exit 1
deleteTestWorkspace ${WS_NAME} ${OCP_USER_NAMESPACE}
}
testClonePrivateRepoNoPatOAuth() {
WS_NAME=$1
PROJECT_NAME=$2
GIT_REPO_URL=$3
OCP_USER_NAMESPACE=$4
runTestWorkspaceWithGitRepoUrl ${WS_NAME} ${PROJECT_NAME} ${GIT_REPO_URL} ${OCP_USER_NAMESPACE}
echo "[INFO] Check the private repository is NOT cloned with NO PAT/OAuth setup"
testProjectIsCloned ${PROJECT_NAME} ${OCP_USER_NAMESPACE} && exit 1
deleteTestWorkspace ${WS_NAME} ${OCP_USER_NAMESPACE}
}
testCloneGitRepoWithSetupPat() {
WS_NAME=$1
PROJECT_NAME=$2
GIT_REPO_URL=$3
OCP_USER_NAMESPACE=$4
GIT_PROVIDER_PATH=$5
runTestWorkspaceWithGitRepoUrl ${WS_NAME} ${PROJECT_NAME} ${GIT_REPO_URL} ${OCP_USER_NAMESPACE}
testProjectIsCloned ${PROJECT_NAME} ${OCP_USER_NAMESPACE} || exit 1
testGitCredentials ${OCP_USER_NAMESPACE} ${GIT_PROVIDER_PAT}
deleteTestWorkspace ${WS_NAME} ${OCP_USER_NAMESPACE}
echo "------- [INFO] Check the repository is cloned. -------"
testProjectIsCloned ${PROJECT_NAME} ${OCP_USER_NAMESPACE} || \
{ echo "####### [ERROR] Project file /projects/${PROJECT_NAME}/${YAML_FILE_NAME} should be present. #######
###### Cause possible: PR code regress or service is changed. Need to investigate it. #######" && exit 1; }
}
setupTestEnvironment() {
@ -311,3 +583,17 @@ setupTestEnvironment() {
forwardPortToService
initUserNamespace ${OCP_USER_NAME}
}
setupTestEnvironmentOAuthFlow() {
ADMIN_ACCESS_TOKEN=$1
APPLICATION_ID=$2
APPLICATION_SECRET=$3
provisionOpenShiftOAuthUser
configureGitSelfSignedCertificate
createCustomResourcesFile
patchCustomResourcesFile
deployChe
createOAuthApplicationGitLabServer ${ADMIN_ACCESS_TOKEN} ${APPLICATION_NAME}
setupOAuthSecret ${APPLICATION_ID} ${APPLICATION_SECRET}
}

View File

@ -4,6 +4,7 @@ metadata:
name: ws-name
spec:
started: true
routingClass: che
template:
projects:
- name: project-name

View File

@ -0,0 +1,15 @@
kind: Secret
apiVersion: v1
metadata:
name: gitlab-oauth-secret
namespace: eclipse-che
labels:
app.kubernetes.io/part-of: che.eclipse.org
app.kubernetes.io/component: oauth-scm-configuration
annotations:
che.eclipse.org/oauth-scm-server: gitlab
che.eclipse.org/scm-server-endpoint: git-provider-url
type: Opaque
data:
id: encoded-application-id
secret: encoded-application-secret

View File

@ -9,8 +9,7 @@ metadata:
che.eclipse.org/che-userid: che-user-id
che.eclipse.org/scm-personal-access-token-name: git-provider-name
che.eclipse.org/scm-url: git-provider-url
che.eclipse.org/scm-userid: 'git-provider-user-id'
che.eclipse.org/scm-username: chepullreq1
che.eclipse.org/scm-organization: ''
data:
token: encoded-access-token
type: Opaque

View File

@ -0,0 +1,77 @@
apiVersion: v1
kind: Pod
metadata:
name: che-smoke-test
namespace: CHE-NAMESPACE
spec:
volumes:
- name: test-run-results
- name: ffmpeg-video
- name: dshm
emptyDir:
medium: Memory
containers:
# container containing the tests
- name: test
image: quay.io/eclipse/che-e2e:next
imagePullPolicy: Always
env:
- name: VIDEO_RECORDING
value: "true"
- name: TEST_SUITE
value: "test"
- name: TS_SELENIUM_EDITOR
value: "che-code"
- name: USERSTORY
value: "SmokeTest"
- name: NODE_TLS_REJECT_UNAUTHORIZED
value: "0"
- name: TS_SELENIUM_BASE_URL
value: "CHE_URL"
- name: TS_SELENIUM_LOG_LEVEL
value: "TRACE"
- name: TS_SELENIUM_OCP_USERNAME
value: "OCP_USER_NAME"
- name: TS_SELENIUM_OCP_PASSWORD
value: "OCP_USER_PASSWORD"
- name: TS_SELENIUM_VALUE_OPENSHIFT_OAUTH
value: "true"
- name: TS_OCP_LOGIN_PAGE_PROVIDER_TITLE
value: "htpasswd"
- name: DELETE_WORKSPACE_ON_FAILED_TEST
value: "true"
- name: TS_SELENIUM_START_WORKSPACE_TIMEOUT
value: "360000"
- name: TS_IDE_LOAD_TIMEOUT
value: "40000"
volumeMounts:
- name: test-run-results
mountPath: /tmp/e2e/report/
- name: ffmpeg-video
mountPath: /tmp/ffmpeg_report/
- name: dshm
mountPath: /dev/shm
resources:
requests:
memory: "3Gi"
cpu: "2"
limits:
memory: "4Gi"
cpu: "2"
# Download results
- name: download-reports
image: eeacms/rsync
imagePullPolicy: IfNotPresent
volumeMounts:
- name: test-run-results
mountPath: /tmp/e2e/report/
- name: ffmpeg-video
mountPath: /tmp/ffmpeg_report/
resources:
command: ["sh"]
args:
[
"-c",
"while true; if [[ -f /tmp/done ]]; then exit 0; fi; do sleep 1; done",
]
restartPolicy: Never

View File

@ -0,0 +1,89 @@
apiVersion: v1
kind: Pod
metadata:
name: oauth-factory-test
namespace: CHE-NAMESPACE
spec:
volumes:
- name: test-run-results
- name: ffmpeg-video
- name: dshm
emptyDir:
medium: Memory
containers:
# container containing the tests
- name: test
image: quay.io/eclipse/che-e2e:next
imagePullPolicy: Always
env:
- name: VIDEO_RECORDING
value: "true"
- name: TEST_SUITE
value: "test"
- name: TS_SELENIUM_EDITOR
value: "che-code"
- name: USERSTORY
value: "Factory"
- name: NODE_TLS_REJECT_UNAUTHORIZED
value: "0"
- name: TS_SELENIUM_BASE_URL
value: "CHE_URL"
- name: TS_SELENIUM_LOG_LEVEL
value: "TRACE"
- name: TS_SELENIUM_OCP_USERNAME
value: "OCP_USER_NAME"
- name: TS_SELENIUM_OCP_PASSWORD
value: "OCP_USER_PASSWORD"
- name: TS_SELENIUM_VALUE_OPENSHIFT_OAUTH
value: "true"
- name: TS_SELENIUM_FACTORY_GIT_REPO_URL
value: "FACTORY_REPO_URL"
- name: TS_SELENIUM_FACTORY_GIT_REPO_BRANCH
value: "GIT_BRANCH"
- name: TS_SELENIUM_FACTORY_GIT_PROVIDER
value: "GIT_PROVIDER_TYPE"
- name: TS_SELENIUM_GIT_PROVIDER_OAUTH
value: "true"
- name: TS_SELENIUM_GIT_PROVIDER_USERNAME
value: "GIT_PROVIDER_USER_NAME"
- name: TS_SELENIUM_GIT_PROVIDER_PASSWORD
value: "GIT_PROVIDER_USER_PASSWORD"
- name: TS_OCP_LOGIN_PAGE_PROVIDER_TITLE
value: "htpasswd"
- name: DELETE_WORKSPACE_ON_FAILED_TEST
value: "true"
- name: TS_SELENIUM_START_WORKSPACE_TIMEOUT
value: "360000"
- name: TS_IDE_LOAD_TIMEOUT
value: "40000"
volumeMounts:
- name: test-run-results
mountPath: /tmp/e2e/report/
- name: ffmpeg-video
mountPath: /tmp/ffmpeg_report/
- name: dshm
mountPath: /dev/shm
resources:
requests:
memory: "3Gi"
cpu: "2"
limits:
memory: "4Gi"
cpu: "2"
# Download results
- name: download-reports
image: eeacms/rsync
imagePullPolicy: IfNotPresent
volumeMounts:
- name: test-run-results
mountPath: /tmp/e2e/report/
- name: ffmpeg-video
mountPath: /tmp/ffmpeg_report/
resources:
command: ["sh"]
args:
[
"-c",
"while true; if [[ -f /tmp/done ]]; then exit 0; fi; do sleep 1; done",
]
restartPolicy: Never

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Secret
metadata:
name: git-ssh-key
annotations:
controller.devfile.io/mount-as: subpath
controller.devfile.io/mount-path: /etc/ssh/
labels:
controller.devfile.io/mount-to-devworkspace: "true"
controller.devfile.io/watch-secret: "true"
type: Opaque
data:
dwo_ssh_key: ssh_private_key
dwo_ssh_key.pub: ssh_public_key
ssh_config: aG9zdCAqCiAgSWRlbnRpdHlGaWxlIC9ldGMvc3NoL2R3b19zc2hfa2V5CiAgU3RyaWN0SG9zdEtleUNoZWNraW5nID0gbm8K

View File

@ -0,0 +1,38 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_RAW_PATH_URL=${PUBLIC_REPO_RAW_PATH_URL:-"https://dev.azure.com/chepullreq1/che-pr-public/_apis/git/repositories/public-repo/items?path=/devfile.yaml"}
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://dev.azure.com/chepullreq1/che-pr-private/_apis/git/repositories/private-repo/items?path=/devfile.yaml"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
testFactoryResolverResponse ${PUBLIC_REPO_RAW_PATH_URL} 200
testFactoryResolverResponse ${PRIVATE_REPO_RAW_PATH_URL} 500
testCloneGitRepoNoProjectExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,40 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_SSH_URL=${PUBLIC_REPO_SSH_URL:-"git@ssh.dev.azure.com:v3/chepullreq1/che-pr-public/public-repo"}
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@ssh.dev.azure.com:v3/chepullreq1/che-pr-private/private-repo"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
setupSSHKeyPairs "${AZURE_PRIVATE_KEY}" "${AZURE_PUBLIC_KEY}"
testFactoryResolverResponse ${PUBLIC_REPO_SSH_URL} 200
testFactoryResolverResponse ${PRIVATE_REPO_SSH_URL} 500
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,35 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://chepullreq1@dev.azure.com/chepullreq1/che-pr-public/_git/public-repo"}
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://dev.azure.com/chepullreq1/che-pr-private/_git/private-repo"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,59 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://chepullreq1@dev.azure.com/chepullreq1/che-pr-public/_git/public-repo"}
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://dev.azure.com/chepullreq1/che-pr-private/_git/private-repo"}
export GIT_PROVIDER_TYPE=${GIT_PROVIDER_TYPE:-"azure-devops"}
export GIT_PROVIDER_URL=${GIT_PROVIDER_URL:-"https://dev.azure.com"}
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@ssh.dev.azure.com:v3/chepullreq1/che-pr-private/private-repo"}
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://dev.azure.com/chepullreq1/che-pr-private/_apis/git/repositories/private-repo/items?path=/devfile.yaml"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
setupPersonalAccessToken ${GIT_PROVIDER_TYPE} ${GIT_PROVIDER_URL} ${AZURE_PAT}
requestProvisionNamespace
testFactoryResolverWithPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
echo "------- [INFO] Check clone public repository with PAT setup -------"
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
testGitCredentialsData ${USER_CHE_NAMESPACE} ${AZURE_PAT} ${GIT_PROVIDER_URL}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
echo "------- [INFO] Check clone private repository with PAT setup -------"
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
testGitCredentialsData ${USER_CHE_NAMESPACE} ${AZURE_PAT} ${GIT_PROVIDER_URL}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
echo "------- [INFO] Check clone private repository by raw devfile URL with PAT setup -------"
testFactoryResolverResponse ${PRIVATE_REPO_RAW_PATH_URL} 200
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
setupSSHKeyPairs "${AZURE_PRIVATE_KEY}" "${AZURE_PUBLIC_KEY}"
echo "------- [INFO] Check clone private repository by SSH URL with PAT setup -------"
testFactoryResolverResponse ${PRIVATE_REPO_SSH_URL} 200
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,37 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_RAW_PATH_URL=${PUBLIC_REPO_RAW_PATH_URL:-"https://bitbucket.org/chepullreq/public-repo/raw/746000bd63a54eaf8ea8aba9dfe6620e5c6c61d7/devfile.yaml"}
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://bitbucket.org/chepullreq/private-repo/raw/80b183d27c6c533462128b0c092208aad73b2906/devfile.yaml"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
testFactoryResolverNoPatOAuthRaw ${PUBLIC_REPO_RAW_PATH_URL} ${PRIVATE_REPO_RAW_PATH_URL}
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,38 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_SSH_URL=${PUBLIC_REPO_SSH_URL:-"git@bitbucket.org:chepullreq/public-repo.git"}
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@bitbucket.org:chepullreq/private-repo.git"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
setupSSHKeyPairs "${BITBUCKET_PRIVATE_KEY}" "${BITBUCKET_PUBLIC_KEY}"
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_SSH_URL} ${PRIVATE_REPO_SSH_URL}
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -16,6 +16,8 @@ set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://chepullreq1@bitbucket.org/chepullreq/public-repo.git"}
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://chepullreq1@bitbucket.org/chepullreq/private-repo.git"}
@ -27,5 +29,7 @@ trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
testClonePublicRepoNoPatOAuth ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
testClonePrivateRepoNoPatOAuth ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,32 @@
#!/bin/bash
#
# Copyright (c) 2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export TEST_POD_NAME=${TEST_POD_NAME:-"che-smoke-test"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "collectLogs" EXIT SIGINT
provisionOpenShiftOAuthUser
createCustomResourcesFile
deployChe
startSmokeTest

View File

@ -0,0 +1,45 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_SSH_URL=${PUBLIC_REPO_SSH_URL:-"git@gitea.com:chepullreq1/public-repo.git"}
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@gitea.com:chepullreq1/private-repo.git"}
export PUBLIC_REPO_RAW_PATH_URL=${PUBLIC_REPO_RAW_PATH_URL:-"https://gitea.com/chepullreq1/public-repo/raw/branch/main/devfile.yaml"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
setupSSHKeyPairs "${GITEA_PRIVATE_KEY}" "${GITEA_PUBLIC_KEY}"
testFactoryResolverResponse ${PUBLIC_REPO_SSH_URL} 200
testFactoryResolverResponse ${PRIVATE_REPO_SSH_URL} 200
testFactoryResolverResponse ${PUBLIC_REPO_RAW_PATH_URL} 200
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoNoProjectExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,33 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_RAW_PATH_URL:-"https://${GITEA_PAT}@gitea.com/chepullreq1/private-repo/raw/branch/main/devfile.yaml"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
testFactoryResolverResponse ${PRIVATE_REPO_RAW_PATH_URL} 200
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,38 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_RAW_PATH_URL=${PUBLIC_REPO_RAW_PATH_URL:-"https://raw.githubusercontent.com/chepullreq1/public-repo/main/devfile.yaml"}
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://raw.githubusercontent.com/chepullreq1/private-repo/main/devfile.yaml"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
testFactoryResolverNoPatOAuthRaw ${PUBLIC_REPO_RAW_PATH_URL} ${PRIVATE_REPO_RAW_PATH_URL}
testCloneGitRepoNoProjectExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,38 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_SSH_URL=${PUBLIC_REPO_SSH_URL:-"git@github.com:chepullreq1/public-repo.git"}
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@github.com:chepullreq1/private-repo.git"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
setupSSHKeyPairs "${GITHUB_PRIVATE_KEY}" "${GITHUB_PUBLIC_KEY}"
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_SSH_URL} ${PRIVATE_REPO_SSH_URL}
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -16,6 +16,8 @@ set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://github.com/chepullreq1/public-repo.git"}
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://github.com/chepullreq1/private-repo.git"}
@ -27,5 +29,7 @@ trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
testClonePublicRepoNoPatOAuth ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
testClonePrivateRepoNoPatOAuth ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -16,10 +16,14 @@ set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://github.com/chepullreq1/public-repo.git"}
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://github.com/chepullreq1/private-repo.git"}
export GIT_PROVIDER_TYPE=${GIT_PROVIDER_TYPE:-"github"}
export GIT_PROVIDER_URL=${GIT_PROVIDER_URL:-"https://github.com"}
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://raw.githubusercontent.com/chepullreq1/private-repo/main/devfile.yaml"}
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@github.com:chepullreq1/private-repo.git"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
@ -28,10 +32,28 @@ source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
setupPersonalAccessToken ${GIT_PROVIDER_TYPE} ${GIT_PROVIDER_URL} ${GITHUB_USER_ID} ${GITHUB_PAT}
setupPersonalAccessToken ${GIT_PROVIDER_TYPE} ${GIT_PROVIDER_URL} ${GITHUB_PAT}
requestProvisionNamespace
testFactoryResolverWithPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
echo "[INFO] Check clone public repository with PAT setup"
testCloneGitRepoWithSetupPat ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE} ${GITHUB_PAT}
echo "[INFO] Check clone private repository with PAT setup"
testCloneGitRepoWithSetupPat ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE} ${GITHUB_PAT}
echo "------- [INFO] Check clone public repository with PAT setup -------"
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
testGitCredentialsData ${USER_CHE_NAMESPACE} ${GITHUB_PAT} ${GIT_PROVIDER_URL}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
echo "------- [INFO] Check clone private repository with PAT setup -------"
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
testGitCredentialsData ${USER_CHE_NAMESPACE} ${GITHUB_PAT} ${GIT_PROVIDER_URL}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
echo "------- [INFO] Check clone private repository by raw devfile URL with PAT setup -------"
testFactoryResolverResponse ${PRIVATE_REPO_RAW_PATH_URL} 200
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
setupSSHKeyPairs "${GITHUB_PRIVATE_KEY}" "${GITHUB_PUBLIC_KEY}"
echo "------- [INFO] Check clone private repository by SSH URL with PAT setup -------"
testFactoryResolverResponse ${PRIVATE_REPO_SSH_URL} 200
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,37 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_RAW_PATH_URL=${PUBLIC_REPO_RAW_PATH_URL:-"https://gitlab.com/chepullreq1/public-repo/-/raw/main/devfile.yaml"}
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://gitlab.com/chepullreq1/private-repo/-/raw/main/devfile.yaml"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
testFactoryResolverNoPatOAuthRaw ${PUBLIC_REPO_RAW_PATH_URL} ${PRIVATE_REPO_RAW_PATH_URL}
testCloneGitRepoNoProjectExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,39 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_SSH_URL=${PUBLIC_REPO_SSH_URL:-"git@gitlab.com:chepullreq1/public-repo.git"}
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@gitlab.com:chepullreq1/private-repo.git"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
setupSSHKeyPairs "${GITLAB_PRIVATE_KEY}" "${GITLAB_PUBLIC_KEY}"
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_SSH_URL} ${PRIVATE_REPO_SSH_URL}
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -16,6 +16,8 @@ set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://gitlab.com/chepullreq1/public-repo.git"}
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://gitlab.com/chepullreq1/private-repo.git"}
@ -27,5 +29,7 @@ trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
testFactoryResolverNoPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
testClonePublicRepoNoPatOAuth ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
testClonePrivateRepoNoPatOAuth ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
testCloneGitRepoNoProjectExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

View File

@ -0,0 +1,39 @@
#!/bin/bash
#
# Copyright (c) 2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# exit immediately when a command fails
set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export TEST_POD_NAME=${TEST_POD_NAME:-"oauth-factory-test"}
export GIT_PROVIDER_TYPE=${GIT_PROVIDER_TYPE:-"gitlab"}
export GIT_PROVIDER_URL=${GIT_PROVIDER_URL:-"https://gitlab-gitlab-system.apps.git.crw-qe.com"}
export GIT_PROVIDER_LOGIN=${GIT_PROVIDER_LOGIN:-"admin-user"}
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://gitlab-gitlab-system.apps.git.crw-qe.com/admin-user/private-repo.git"}
export GIT_REPO_BRANCH=${PRIVATE_REPO_BRANCH:-"main"}
export APPLICATION_NAME=${APPLICATION_NAME:-"TestApp"}
export OAUTH_ID=""
export APPLICATION_ID=""
export APPLICATION_SECRET=""
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "${SCRIPT_DIR}"/common.sh
trap "collectLogs" EXIT SIGINT
setupTestEnvironmentOAuthFlow ${ADMIN_ACCESS_TOKEN} ${APPLICATION_NAME} ${APPLICATION_ID} ${APPLICATION_SECRET}
startOAuthFactoryTest

View File

@ -16,10 +16,14 @@ set -ex
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
echo "======= [INFO] OpenShift CI infrastructure is ready. Running test. ======="
export PUBLIC_REPO_URL=${PUBLIC_REPO_URL:-"https://gitlab.com/chepullreq1/public-repo.git"}
export PRIVATE_REPO_URL=${PRIVATE_REPO_URL:-"https://gitlab.com/chepullreq1/private-repo.git"}
export GIT_PROVIDER_TYPE=${GIT_PROVIDER_TYPE:-"gitlab"}
export GIT_PROVIDER_URL=${GIT_PROVIDER_URL:-"https://gitlab.com"}
export PRIVATE_REPO_SSH_URL=${PRIVATE_REPO_SSH_URL:-"git@gitlab.com:chepullreq1/private-repo.git"}
export PRIVATE_REPO_RAW_PATH_URL=${PRIVATE_REPO_URL:-"https://gitlab.com/chepullreq1/private-repo/-/raw/main/devfile.yaml"}
# import common test functions
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
@ -28,10 +32,28 @@ source "${SCRIPT_DIR}"/common.sh
trap "catchFinish" EXIT SIGINT
setupTestEnvironment ${OCP_NON_ADMIN_USER_NAME}
setupPersonalAccessToken ${GIT_PROVIDER_TYPE} ${GIT_PROVIDER_URL} ${GITLAB_USER_ID} ${GITLAB_PAT}
setupPersonalAccessToken ${GIT_PROVIDER_TYPE} ${GIT_PROVIDER_URL} ${GITLAB_PAT}
requestProvisionNamespace
testFactoryResolverWithPatOAuth ${PUBLIC_REPO_URL} ${PRIVATE_REPO_URL}
echo "[INFO] Check clone public repository with PAT setup"
testCloneGitRepoWithSetupPat ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE} ${GITLAB_PAT}
echo "[INFO] Check clone private repository with PAT setup"
testCloneGitRepoWithSetupPat ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE} ${GITLAB_PAT}
echo "------- [INFO] Check clone public repository with PAT setup -------"
testCloneGitRepoProjectShouldExists ${PUBLIC_REPO_WORKSPACE_NAME} ${PUBLIC_PROJECT_NAME} ${PUBLIC_REPO_URL} ${USER_CHE_NAMESPACE}
testGitCredentialsData ${USER_CHE_NAMESPACE} ${GITLAB_PAT} ${GIT_PROVIDER_URL}
deleteTestWorkspace ${PUBLIC_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
echo "------- [INFO] Check clone private repository with PAT setup -------"
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_URL} ${USER_CHE_NAMESPACE}
testGitCredentialsData ${USER_CHE_NAMESPACE} ${GITLAB_PAT} ${GIT_PROVIDER_URL}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
echo "------- [INFO] Check clone private repository by raw devfile URL with PAT setup -------"
testFactoryResolverResponse ${PRIVATE_REPO_RAW_PATH_URL} 200
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_RAW_PATH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}
setupSSHKeyPairs "${GITLAB_PRIVATE_KEY}" "${GITLAB_PUBLIC_KEY}"
echo "------- [INFO] Check clone private repository by SSH URL with PAT setup -------"
testFactoryResolverResponse ${PRIVATE_REPO_SSH_URL} 200
testCloneGitRepoProjectShouldExists ${PRIVATE_REPO_WORKSPACE_NAME} ${PRIVATE_PROJECT_NAME} ${PRIVATE_REPO_SSH_URL} ${USER_CHE_NAMESPACE}
deleteTestWorkspace ${PRIVATE_REPO_WORKSPACE_NAME} ${USER_CHE_NAMESPACE}

5
.github/CODEOWNERS vendored
View File

@ -1,11 +1,8 @@
# Global Owners
* @l0rd @ibuziuk @vinokurig @nickboldt @tolusha
* @SDawley @ibuziuk @vinokurig @tolusha
# che.properties file is quasi-documentation, so in future we might grant access to this
# assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/** @osslate
# workspace runtime infrastructure implementations
infrastructures/** @amisevsk
# deploy
deploy/** @tolusha @dkwon17

View File

@ -31,23 +31,23 @@ jobs:
cache: 'maven'
- name: Login to docker.io
if: github.event_name == 'pull_request'
uses: docker/login-action@v2
uses: redhat-actions/podman-login@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
registry: docker.io
- name: Login to quay.io
if: github.event_name == 'pull_request'
uses: docker/login-action@v2
uses: redhat-actions/podman-login@v1
with:
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
registry: quay.io
- name: Build with Maven
run: mvn -B clean install -U -Pintegration
- name: Build docker images
- name: Build images
if: github.event_name == 'pull_request'
run: ./dockerfiles/build.sh --tag:${{ env.PR_IMAGE_TAG }}
- name: Push docker images
run: ./build/build.sh --tag:${{ env.PR_IMAGE_TAG }}
- name: Push images
if: github.event_name == 'pull_request'
run: docker push quay.io/eclipse/che-server:${{ env.PR_IMAGE_TAG }}
run: podman push quay.io/eclipse/che-server:${{ env.PR_IMAGE_TAG }}

View File

@ -29,37 +29,28 @@ jobs:
java-version: '11'
cache: 'maven'
- name: Login to docker.io
uses: docker/login-action@v2
uses: redhat-actions/podman-login@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
registry: docker.io
- name: Login to quay.io
uses: docker/login-action@v2
uses: redhat-actions/podman-login@v1
with:
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
registry: quay.io
- name: Build with Maven
run: mvn -B clean install -U -Pintegration
- name: Build docker images
- name: Build images
id: build
run: |
echo "short_sha1=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
./dockerfiles/build.sh --tag:next --sha-tag
./build/build.sh --tag:next --sha-tag
- name: Push docker images
run: |
docker push quay.io/eclipse/che-endpoint-watcher:next
docker push quay.io/eclipse/che-endpoint-watcher:${{ steps.build.outputs.short_sha1 }}
docker push quay.io/eclipse/che-keycloak:next
docker push quay.io/eclipse/che-keycloak:${{ steps.build.outputs.short_sha1 }}
docker push quay.io/eclipse/che-postgres:next
docker push quay.io/eclipse/che-postgres:${{ steps.build.outputs.short_sha1 }}
docker push quay.io/eclipse/che-server:next
docker push quay.io/eclipse/che-server:${{ steps.build.outputs.short_sha1 }}
podman push quay.io/eclipse/che-server:next
podman push quay.io/eclipse/che-server:${{ steps.build.outputs.short_sha1 }}
- name: Create failure MM message
if: ${{ failure() }}
run: |

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2020 Red Hat, Inc.
# Copyright (c) 2020-2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
@ -88,11 +88,10 @@ jobs:
run: |
sudo apt-get update -y || true
# install more dependencies
sudo apt-get -y -q install wget curl bash git
sudo apt-get -y -q install wget curl bash git
java -version
# want git >=2.24, hub >=2
hub --version # hub reports git version too
git --version
gh --version
# want >=5
bash --version

8
.gitignore vendored
View File

@ -1,3 +1,5 @@
.repository/
# Eclipse #
###################
@ -11,10 +13,6 @@ test-output/
maven-eclipse.xml
.factorypath
# Theia #
##################
.theia/
# Idea #
##################
*.iml
@ -48,8 +46,6 @@ maven-eclipse.xml
*.war
*.ear
# Logs and databases #
######################
*.log

82
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,82 @@
## Developing with Eclipse Che
This project contains a [devfile v2](https://github.com/eclipse-che/che-server/blob/main/devfile.yaml) located in the project's root directory.
With this devfile you can perform the following tasks:
- Build project sources with maven.
- Build a container image.
- Push your changes to GitHub.
### Starting a Workspace within Eclipse Che
To start a new workspace within Eclipse Che, navigate to the following URL:
```sh
{CHE-HOST}/#https://github.com/eclipse-che/che-server
```
### Running Devfile Tasks for Downloading Dependencies and Building the Project
For VS Code, execute tasks defined in the devfile with these steps:
1. Open the command palette (Ctrl/Cmd + Shift + P).
2. Execute the `Tasks: Run Task` command.
3. Select the `devfile` folder and select the `1. Build sources` task to build the project sources with maven.
4. Follow steps 1 and 2 again, select the `1. Build image` task to build a container image.
5. In the workspace terminal, tag the **che-server** image with your account: `podman tag quay.io/eclipse/che-server:next <docker registry>/<your account>/che-server:next`.
6. Push the **che-server** image to your account: `podman push <docker registry>/<your account>/che-server:next`.
# Local build requirements
- Apache Maven 3.9 or later
- JDK 11
- Podman or Docker (required for running integration tests)
A Che workspace environment allows to build the image internally, using the workspace terminal.
# Start and debug
1. Deploy Che to a [Red Hat OpenShift](https://www.eclipse.org/che/docs/stable/administration-guide/installing-che-on-openshift-using-cli/) or [Minikube](https://www.eclipse.org/che/docs/stable/administration-guide/installing-che-on-minikube/) cluster by using a previously built image: `chectl server:start --platform=<openshift / minikube> --cheimage=<docker registry>/<your account>/che-server:next`.
2. Enable local debugging of the Eclipse Che server: `chectl server:debug`.
3. In your IDE, create a new Remote JVM Debug configuration on `localhost:8000`.
4. Hit a breakpoint in the code and activate the debug configuration.
# Contributing an SCM provider
An SCM provider support has to be provided by adding new maven modules to the wsmaster directory.
## Implementing che-core-api-oauth-<SCM provider name> module
This module is responsible for Oauth requests to the SCM provider and contans next implementations:
1. `<SCM provider name>OAuthAuthenticator` contains specific implementation of Oauth token requestand authentication endpoint.
2. `<SCM provider name>OAuthAuthenticatorProvider` a provider of the `OAuthAuthenticator`.
## Implementing coresponding che-core-api-factory-<SCM provider name> module
This module is responsible for API operations of the specific SCM provider.
1. `<SCM provider name>ApiClient` contains all necessary HTTP API calls like `getUser()`.
2. `<SCM provider name>AuthorisingFileContentProvider` overrides the common `AuthorisingFileContentProvider` to define the specific `isPublicRepository()` function.
3. `<SCM provider name>FactoryParameterResolver` validates SCM URL if it corresponds to the SCM provider. Also Provides specific Factory Parameters resolver for the SCM repository.
4. `<SCM provider name>PersonalAccessTokenFetcher` fetches Personal Access Token from the SCM provider by reqesting the OAuth API of the provider. Validates the token by comparing the token access scopes with the predefined scope list.
5. `<SCM provider name>FileResolver` Implementation of a resolver that can return particular file content from specified SCM repository.
6. `<SCM provider name>URLParser` Parses the string representation of the URL to an SCM specific object
7. `<SCM provider name>UserDataFetcher` Implementation of a resolver that can return particular file content from specified SCM repository.
# CI
There are several [GitHub Actions](https://github.com/eclipse-che/che-server/actions) workflows implemented for this repository:
- [![build-next](https://github.com/eclipse-che/che-server/actions/workflows/next-build.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/next-build.yml)
Builds Maven artifacts, builds container images and pushes them to [quay.io](https://quay.io/organization/eclipse) on each commit to [`main`](https://github.com/eclipse-che/che-server/tree/main) branch.
- [![Release Che Server](https://github.com/eclipse-che/che-server/actions/workflows/release.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/release.yml)
Builds Maven artifacts and container images. Images are public and pushed to [quay.io](https://quay.io/organization/eclipse). See [RELEASE.md](https://github.com/eclipse-che/che-server/blob/master/RELEASE.md) for more information about this workflow.
- [![Release Changelog](https://github.com/eclipse-che/che-server/actions/workflows/release-changelog.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/release-changelog.yml)
Creates a GitHub release which will include a generated changelog.
- [![Update Che docs variables](https://github.com/eclipse-che/che-server/actions/workflows/che-properties-docs-update.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/che-properties-docs-update.yml/badge.svg)
Runs on each commit to [`main`](https://github.com/eclipse-che/che-server/tree/main) branch.
- [![build-pr-check](https://github.com/eclipse-che/che-server/actions/workflows/build-pr-check.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/build-pr-check.yml)
Builds Maven artifacts and container images. This workflow is used as a check for all pull requests that are submitted to this project.
- [![Sonar](https://github.com/eclipse-che/che-server/actions/workflows/sonar.yaml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/sonar.yaml)
Runs Sonar against the main branch. The result can be seen [here](https://sonarcloud.io/dashboard?id=org.eclipse.che%3Ache-server).
- [![Try in Web IDE](https://github.com/eclipse-che/che-server/actions/workflows/try-in-web-ide.yaml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/try-in-web-ide.yaml)
Used as a check for pull requests that are submitted to this project.
Downstream builds can be found at the link below, which is _internal to Red Hat_. Stable builds can be found by replacing the 3.x with a specific version like 3.2.
- [server_3.x](https://main-jenkins-csb-crwqe.apps.ocp-c1.prod.psi.redhat.com/job/DS_CI/job/server_3.x/)
# Report issues
Issues are tracked on the main Eclipse Che Repository: https://github.com/eclipse/che/issues

View File

@ -1,6 +1,6 @@
# What is Che server
Che Server provides an API for managing Kubernetes namespaces, and to retrieve devfile content from repositories,
hosted on GitHub, GitLab, Bitbucket, and Microsoft Azure Repos.
Che Server provides an API for managing Kubernetes namespaces and to retrieve devfile content from repositories,
hosted on GitHub, GitLab, Bitbucket and Microsoft Azure Repos.
# Project structure
Che Server is mostly a Java web application deployed on an Apache Tomcat server in a container. Che Server uses the following modules:
@ -24,49 +24,6 @@ Che Server is mostly a Java web application deployed on an Apache Tomcat server
Other modules are deprecated and will be removed in the future.
# Build requirements
- Apache Maven 3.6.3 or later
- JDK 11
- Podman or Docker (required for running integration tests)
# Sources build
Run `mvn clean install` to build. Activate a faster profile build by adding `-Pfast`.
# Image build and push
1. Go to the `dockerfiles` directory.
2. Run `./build.sh`.
3. Tag the **che-server** image with your account: `docker tag quay.io/eclipse/che-server:next <docker registry>/<your account>/che-server:next`.
4. Push the **che-server** image to your account: `docker push <docker registry>/<your account>/che-server:next`.
# Debug
1. Deploy Che to a [Red Hat OpenShift](https://www.eclipse.org/che/docs/stable/administration-guide/installing-che-on-openshift-using-cli/) or [Minikube](https://www.eclipse.org/che/docs/stable/administration-guide/installing-che-on-minikube/) cluster by using a previously built image: `chectl server:start --platform=<openshift / minikube> --cheimage=<docker registry>/<your account>/che-server:next`.
2. Enable local debugging of the Eclipse Che server: `chectl server:debug`.
3. In your IDE, create a new Remote JVM Debug configuration on `localhost:8000`.
4. Hit a breakpoint in the code and activate the debug configuration.
# CI
There are several [GitHub Actions](https://github.com/eclipse-che/che-server/actions) workflows implemented for this repository:
- [![build-next](https://github.com/eclipse-che/che-server/actions/workflows/next-build.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/next-build.yml)
Builds Maven artifacts, builds container images and pushes them to [quay.io](https://quay.io/organization/eclipse) on each commit to [`main`](https://github.com/eclipse-che/che-server/tree/main) branch.
- [![Release Che Server](https://github.com/eclipse-che/che-server/actions/workflows/release.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/release.yml)
Builds Maven artifacts and container images. Images are public and pushed to [quay.io](https://quay.io/organization/eclipse). See [RELEASE.md](https://github.com/eclipse-che/che-server/blob/master/RELEASE.md) for more information about this workflow.
- [![Release Changelog](https://github.com/eclipse-che/che-server/actions/workflows/release-changelog.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/release-changelog.yml)
Creates a GitHub release which will include a generated changelog.
- [![Update Che docs variables](https://github.com/eclipse-che/che-server/actions/workflows/che-properties-docs-update.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/che-properties-docs-update.yml/badge.svg)
Runs on each commit to [`main`](https://github.com/eclipse-che/che-server/tree/main) branch.
- [![build-pr-check](https://github.com/eclipse-che/che-server/actions/workflows/build-pr-check.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/build-pr-check.yml)
Builds Maven artifacts and container images. This workflow is used as a check for all pull requests that are submitted to this project.
- [![Sonar](https://github.com/eclipse-che/che-server/actions/workflows/sonar.yaml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/sonar.yaml)
Runs Sonar against the main branch. The result can be seen [here](https://sonarcloud.io/dashboard?id=org.eclipse.che%3Ache-server).
- [![Try in Web IDE](https://github.com/eclipse-che/che-server/actions/workflows/try-in-web-ide.yaml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/try-in-web-ide.yaml)
Used as a check for pull requests that are submitted to this project.
Downstream builds can be found at the link below, which is _internal to Red Hat_. Stable builds can be found by replacing the 3.x with a specific version like 3.2.
- [server_3.x](https://main-jenkins-csb-crwqe.apps.ocp-c1.prod.psi.redhat.com/job/DS_CI/job/server_3.x/)
# License
- [Eclipse Public License 2.0](LICENSE)
@ -76,6 +33,6 @@ Downstream builds can be found at the link below, which is _internal to Red Hat_
The Eclipse Che community is globally reachable through public chat rooms, mailing list and weekly calls.
See the Eclipse Che Documentation about [how you can join our community](https://www.eclipse.org/che/docs/stable/overview/introduction-to-eclipse-che/#_joining_the_community).
## Report issues
## Builds
Issues are tracked on the main Eclipse Che Repository: https://github.com/eclipse/che/issues
* [![release latest stable](https://github.com/eclipse-che/che-server/actions/workflows/release.yml/badge.svg)](https://github.com/eclipse-che/che-server/actions/workflows/release.yml)

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
Copyright (c) 2012-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
@ -17,7 +17,7 @@
<parent>
<artifactId>che-assembly-parent</artifactId>
<groupId>org.eclipse.che</groupId>
<version>7.73.0-SNAPSHOT</version>
<version>7.86.0-SNAPSHOT</version>
</parent>
<artifactId>assembly-che-tomcat</artifactId>
<packaging>jar</packaging>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
Copyright (c) 2012-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
@ -17,7 +17,7 @@
<parent>
<artifactId>che-assembly-parent</artifactId>
<groupId>org.eclipse.che</groupId>
<version>7.73.0-SNAPSHOT</version>
<version>7.86.0-SNAPSHOT</version>
</parent>
<artifactId>assembly-main</artifactId>
<packaging>pom</packaging>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
Copyright (c) 2012-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
@ -17,7 +17,7 @@
<parent>
<artifactId>che-assembly-parent</artifactId>
<groupId>org.eclipse.che</groupId>
<version>7.73.0-SNAPSHOT</version>
<version>7.86.0-SNAPSHOT</version>
</parent>
<artifactId>assembly-root-war</artifactId>
<packaging>war</packaging>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
Copyright (c) 2012-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
@ -17,7 +17,7 @@
<parent>
<artifactId>che-assembly-parent</artifactId>
<groupId>org.eclipse.che</groupId>
<version>7.73.0-SNAPSHOT</version>
<version>7.86.0-SNAPSHOT</version>
</parent>
<artifactId>assembly-swagger-war</artifactId>
<packaging>war</packaging>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
Copyright (c) 2012-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
@ -17,7 +17,7 @@
<parent>
<artifactId>che-assembly-parent</artifactId>
<groupId>org.eclipse.che</groupId>
<version>7.73.0-SNAPSHOT</version>
<version>7.86.0-SNAPSHOT</version>
</parent>
<artifactId>assembly-wsmaster-war</artifactId>
<packaging>war</packaging>
@ -91,10 +91,6 @@
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-account</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-auth</artifactId>
@ -107,6 +103,10 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-auth-bitbucket</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-auth-github</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-auth-gitlab</artifactId>
@ -155,10 +155,6 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-logger</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-metrics</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-ssh</artifactId>
@ -195,18 +191,6 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-schedule</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-db</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-db-vendor-h2</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-db-vendor-postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-logback</artifactId>
@ -351,10 +335,6 @@
<groupId>org.everrest</groupId>
<artifactId>everrest-integration-guice</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.jgroups</groupId>
<artifactId>jgroups</artifactId>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2023 Red Hat, Inc.
* Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
@ -26,7 +26,6 @@ import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.SigningKeyResolver;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.eclipse.che.api.core.notification.RemoteSubscriptionStorage;
import org.eclipse.che.api.core.rest.CheJsonProvider;
import org.eclipse.che.api.core.rest.MessageBodyAdapter;
@ -36,6 +35,7 @@ import org.eclipse.che.api.factory.server.FactoryAcceptValidator;
import org.eclipse.che.api.factory.server.FactoryCreateValidator;
import org.eclipse.che.api.factory.server.FactoryEditValidator;
import org.eclipse.che.api.factory.server.FactoryParametersResolver;
import org.eclipse.che.api.factory.server.RawDevfileUrlFactoryParameterResolver;
import org.eclipse.che.api.factory.server.ScmFileResolver;
import org.eclipse.che.api.factory.server.ScmService;
import org.eclipse.che.api.factory.server.azure.devops.AzureDevOpsFactoryParametersResolver;
@ -47,11 +47,11 @@ import org.eclipse.che.api.factory.server.bitbucket.BitbucketServerScmFileResolv
import org.eclipse.che.api.factory.server.git.ssh.GitSshFactoryParametersResolver;
import org.eclipse.che.api.factory.server.git.ssh.GitSshScmFileResolver;
import org.eclipse.che.api.factory.server.github.GithubFactoryParametersResolver;
import org.eclipse.che.api.factory.server.github.GithubFactoryParametersResolverSecond;
import org.eclipse.che.api.factory.server.github.GithubScmFileResolver;
import org.eclipse.che.api.factory.server.github.GithubScmFileResolverSecond;
import org.eclipse.che.api.factory.server.gitlab.GitlabFactoryParametersResolver;
import org.eclipse.che.api.factory.server.gitlab.GitlabScmFileResolver;
import org.eclipse.che.api.factory.server.scm.OAuthTokenFetcher;
import org.eclipse.che.api.metrics.WsMasterMetricsModule;
import org.eclipse.che.api.system.server.ServiceTermination;
import org.eclipse.che.api.system.server.SystemModule;
import org.eclipse.che.api.user.server.NotImplementedTokenValidator;
@ -84,13 +84,10 @@ import org.eclipse.che.api.workspace.server.spi.provision.env.WorkspaceNameEnvVa
import org.eclipse.che.api.workspace.server.spi.provision.env.WorkspaceNamespaceNameEnvVarProvider;
import org.eclipse.che.api.workspace.server.wsplugins.ChePluginsApplier;
import org.eclipse.che.commons.observability.deploy.ExecutorWrapperModule;
import org.eclipse.che.core.db.DBTermination;
import org.eclipse.che.core.db.schema.SchemaInitializer;
import org.eclipse.che.core.tracing.metrics.TracingMetricsModule;
import org.eclipse.che.inject.DynaModule;
import org.eclipse.che.multiuser.api.authentication.commons.token.HeaderRequestTokenExtractor;
import org.eclipse.che.multiuser.api.authentication.commons.token.RequestTokenExtractor;
import org.eclipse.che.multiuser.api.permission.server.AdminPermissionInitializer;
import org.eclipse.che.multiuser.api.permission.server.PermissionChecker;
import org.eclipse.che.multiuser.api.permission.server.PermissionCheckerImpl;
import org.eclipse.che.multiuser.api.workspace.activity.MultiUserWorkspaceActivityModule;
@ -104,7 +101,6 @@ import org.eclipse.che.multiuser.permission.user.UserServicePermissionsFilter;
import org.eclipse.che.security.PBKDF2PasswordEncryptor;
import org.eclipse.che.security.PasswordEncryptor;
import org.eclipse.che.security.oauth.EmbeddedOAuthAPI;
import org.eclipse.che.security.oauth.GitLabModule;
import org.eclipse.che.security.oauth.OAuthAPI;
import org.eclipse.che.security.oauth.OpenShiftOAuthModule;
import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientConfigFactory;
@ -126,7 +122,6 @@ import org.eclipse.che.workspace.infrastructure.openshift.OpenShiftInfrastructur
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
import org.eclipse.che.workspace.infrastructure.openshift.multiuser.oauth.KeycloakProviderConfigFactory;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.flywaydb.core.internal.util.PlaceholderReplacer;
/** @author andrew00x */
@DynaModule
@ -142,18 +137,10 @@ public class WsMasterModule extends AbstractModule {
}
// db related components modules
install(new org.eclipse.che.account.api.AccountModule());
install(new org.eclipse.che.api.ssh.server.jpa.SshJpaModule());
install(new org.eclipse.che.api.core.jsonrpc.impl.JsonRpcModule());
install(new org.eclipse.che.api.core.websocket.impl.WebSocketModule());
// db configuration
bind(SchemaInitializer.class)
.to(org.eclipse.che.core.db.schema.impl.flyway.FlywaySchemaInitializer.class);
bind(org.eclipse.che.core.db.DBInitializer.class).asEagerSingleton();
bind(PlaceholderReplacer.class)
.toProvider(org.eclipse.che.core.db.schema.impl.flyway.PlaceholderReplacerProvider.class);
// factory
bind(FactoryAcceptValidator.class)
.to(org.eclipse.che.api.factory.server.impl.FactoryAcceptValidatorImpl.class);
@ -169,6 +156,9 @@ public class WsMasterModule extends AbstractModule {
Multibinder<FactoryParametersResolver> factoryParametersResolverMultibinder =
Multibinder.newSetBinder(binder(), FactoryParametersResolver.class);
factoryParametersResolverMultibinder.addBinding().to(GithubFactoryParametersResolver.class);
factoryParametersResolverMultibinder
.addBinding()
.to(GithubFactoryParametersResolverSecond.class);
factoryParametersResolverMultibinder
.addBinding()
.to(BitbucketServerAuthorizingFactoryParametersResolver.class);
@ -177,11 +167,15 @@ public class WsMasterModule extends AbstractModule {
factoryParametersResolverMultibinder
.addBinding()
.to(AzureDevOpsFactoryParametersResolver.class);
factoryParametersResolverMultibinder
.addBinding()
.to(RawDevfileUrlFactoryParameterResolver.class);
factoryParametersResolverMultibinder.addBinding().to(GitSshFactoryParametersResolver.class);
Multibinder<ScmFileResolver> scmFileResolverResolverMultibinder =
Multibinder.newSetBinder(binder(), ScmFileResolver.class);
scmFileResolverResolverMultibinder.addBinding().to(GithubScmFileResolver.class);
scmFileResolverResolverMultibinder.addBinding().to(GithubScmFileResolverSecond.class);
scmFileResolverResolverMultibinder.addBinding().to(BitbucketScmFileResolver.class);
scmFileResolverResolverMultibinder.addBinding().to(GitlabScmFileResolver.class);
scmFileResolverResolverMultibinder.addBinding().to(BitbucketServerScmFileResolver.class);
@ -205,9 +199,7 @@ public class WsMasterModule extends AbstractModule {
install(new DevfileModule());
bind(WorkspaceEntityProvider.class);
bind(org.eclipse.che.api.workspace.server.TemporaryWorkspaceRemover.class);
bind(org.eclipse.che.api.workspace.server.WorkspaceService.class);
bind(org.eclipse.che.api.devfile.server.DevfileService.class);
bind(org.eclipse.che.api.devfile.server.UserDevfileEntityProvider.class);
install(new FactoryModuleBuilder().build(ServersCheckerFactory.class));
@ -274,10 +266,6 @@ public class WsMasterModule extends AbstractModule {
terminationMultiBinder
.addBinding()
.to(org.eclipse.che.api.system.server.CronThreadPullTermination.class);
terminationMultiBinder
.addBinding()
.to(org.eclipse.che.api.workspace.server.hc.probe.ProbeSchedulerTermination.class);
bind(DBTermination.class);
final Map<String, String> persistenceProperties = new HashMap<>();
persistenceProperties.put(PersistenceUnitProperties.TARGET_SERVER, "None");
@ -293,8 +281,9 @@ public class WsMasterModule extends AbstractModule {
install(new FactoryModuleBuilder().build(PassThroughProxyProvisionerFactory.class));
installDefaultSecureServerExposer(infrastructure);
install(new org.eclipse.che.security.BitbucketModule());
install(new GitLabModule());
install(new org.eclipse.che.security.oauth.GitLabModule());
install(new org.eclipse.che.security.oauth.AzureDevOpsModule());
install(new org.eclipse.che.security.oauth.GithubModule());
configureMultiUserMode(persistenceProperties, infrastructure);
@ -319,7 +308,6 @@ public class WsMasterModule extends AbstractModule {
}
if (Boolean.valueOf(System.getenv("CHE_METRICS_ENABLED"))) {
install(new org.eclipse.che.core.metrics.MetricsModule());
install(new WsMasterMetricsModule());
install(new InfrastructureMetricsModule());
} else {
install(new org.eclipse.che.core.metrics.NoopMetricsModule());
@ -360,9 +348,6 @@ public class WsMasterModule extends AbstractModule {
persistenceProperties.put(
PersistenceUnitProperties.EXCEPTION_HANDLER_CLASS,
"org.eclipse.che.core.db.postgresql.jpa.eclipselink.PostgreSqlExceptionHandler");
bind(DataSource.class).toProvider(org.eclipse.che.core.db.JndiDataSourceProvider.class);
install(new org.eclipse.che.multiuser.api.permission.server.jpa.SystemPermissionsJpaModule());
install(
new org.eclipse.che.multiuser.permission.workspace.server.WorkspaceApiPermissionsModule());
@ -409,10 +394,8 @@ public class WsMasterModule extends AbstractModule {
bind(TokenValidator.class).to(NotImplementedTokenValidator.class);
bind(ProfileDao.class).to(JpaProfileDao.class);
bind(OAuthAPI.class).to(EmbeddedOAuthAPI.class).asEagerSingleton();
bind(OAuthTokenFetcher.class).to(EmbeddedOAuthAPI.class).asEagerSingleton();
}
bind(AdminPermissionInitializer.class).asEagerSingleton();
install(new MachineAuthModule());
// User and profile - use profile from keycloak and other stuff is JPA

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2012-2023 Red Hat, Inc.
# Copyright (c) 2012-2024 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
@ -91,10 +91,6 @@ che.workspace.server.liveness_probes=wsagent/http,exec-agent/http,terminal,theia
# The default is: 10MB=10485760.
che.workspace.startup_debug_log_limit_bytes=10485760
# If set to `true`, 'stop-workspace' role with the edit privileges is granted to the 'che' ServiceAccount if OpenShift OAuth is enabled.
# This configuration is mainly required for workspace idling when the OpenShift OAuth is enabled.
che.workspace.stop.role.enabled=true
# Specifies whether {prod-short} is deployed with DevWorkspaces enabled.
# This property is set by the {prod-short} Operator if it also installed the support for DevWorkspaces.
# This property is used to advertise this fact to the {prod-short} dashboard.
@ -145,22 +141,42 @@ che.oauth.azure.devops.redirecturis=https://${CHE_HOST}/api/oauth/callback
# Location of the file with GitHub client id.
che.oauth2.github.clientid_filepath=NULL
# Configuration of the GitHub OAuth2 client. Used to obtain personal access tokens.
# Location of the file with GitHub client id (The second GitHub instance).
che.oauth2.github.clientid_filepath_2=NULL
# Location of the file with GitHub client secret.
che.oauth2.github.clientsecret_filepath=NULL
# Location of the file with GitHub client secret (The second GitHub instance).
che.oauth2.github.clientsecret_filepath_2=NULL
# GitHub OAuth authorization URI.
che.oauth.github.authuri= https://github.com/login/oauth/authorize
# GitHub OAuth authorization URI (The second GitHub instance).
che.oauth.github.authuri_2= https://github.com/login/oauth/authorize
# GitHub OAuth token URI.
che.oauth.github.tokenuri= https://github.com/login/oauth/access_token
# GitHub OAuth token URI (The second GitHub instance).
che.oauth.github.tokenuri_2= https://github.com/login/oauth/access_token
# GitHub server address.
# Prerequisite: OAuth 2 integration is configured on the GitHub server.
che.integration.github.oauth_endpoint=NULL
# GitHub server address.
# Prerequisite: OAuth 2 integration is configured on the GitHub server (The second GitHub instance).
che.integration.github.oauth_endpoint_2=NULL
# GitHub server disable subdomain isolation flag.
che.integration.github.disable_subdomain_isolation=false
# GitHub server disable subdomain isolation flag (The second GitHub instance).
che.integration.github.disable_subdomain_isolation_2=false
# GitHub OAuth redirect URIs.
# Separate multiple values with comma, for example: URI,URI,URI.
che.oauth.github.redirecturis= http://localhost:${CHE_PORT}/api/oauth/callback
@ -643,3 +659,16 @@ che.oauth2.gitlab.clientid_filepath=NULL
# Location of the file with GitLab client secret.
che.oauth2.gitlab.clientsecret_filepath=NULL
### Advanced authorization
# Comma separated list of users allowed to access Che.
che.infra.kubernetes.advanced_authorization.allow_users=NULL
# Comma separated list of groups of users allowed to access Che.
che.infra.kubernetes.advanced_authorization.allow_groups=NULL
# Comma separated list of users denied to access Che.
che.infra.kubernetes.advanced_authorization.deny_users=NULL
# Comma separated list of groups of users denied to access Che.
che.infra.kubernetes.advanced_authorization.deny_groups=NULL

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* Copyright (c) 2012-2024 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
@ -37,6 +37,7 @@ import org.reflections.scanners.FieldAnnotationsScanner;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.scanners.MethodParameterScanner;
import org.testng.Assert;
import org.testng.annotations.Ignore;
import org.testng.annotations.Test;
public class IntegrityConfigurationTest {
@ -125,6 +126,7 @@ public class IntegrityConfigurationTest {
}
@Test
@Ignore
public void shouldNotDeclareUnused() {
Reflections reflections =
new Reflections(

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
Copyright (c) 2012-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
@ -17,7 +17,7 @@
<parent>
<artifactId>che-server</artifactId>
<groupId>org.eclipse.che</groupId>
<version>7.73.0-SNAPSHOT</version>
<version>7.86.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>che-assembly-parent</artifactId>

View File

@ -1,5 +1,6 @@
#!/bin/bash
# Copyright (c) 2017 Red Hat, Inc.
#
# Copyright (c) 2017-2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
@ -14,6 +15,7 @@ IMAGE_ALIASES=${IMAGE_ALIASES:-}
ERROR=${ERROR:-}
DIR=${DIR:-}
SHA_TAG=${SHA_TAG:-}
BUILDER=${BUILDER:-}
skip_tests() {
if [ $SKIP_TESTS = "true" ]; then
@ -48,6 +50,7 @@ init() {
ARGS=""
OPTIONS=""
DOCKERFILE=""
BUILD_COMMAND="build"
BUILD_ARGS=""
while [ $# -gt 0 ]; do
@ -103,6 +106,37 @@ build() {
DIR=$(cd "$(dirname "$0")"; pwd)
fi
BUILD_COMAMAND="build"
if [ -z $BUILDER ]; then
echo "BUILDER is not specified, trying with podman"
BUILDER=$(command -v podman || true)
if [[ ! -x $BUILDER ]]; then
echo "[WARNING] podman is not installed, trying with buildah"
BUILDER=$(command -v buildah || true)
if [[ ! -x $BUILDER ]]; then
echo "[WARNING] buildah is not installed, trying with docker"
BUILDER=$(command -v docker || true)
if [[ ! -x $BUILDER ]]; then
echo "[ERROR] This script requires podman, buildah or docker to be installed. Must abort!"; exit 1
fi
else
BUILD_COMMAND="bud"
fi
fi
else
if [[ ! -x $(command -v "$BUILDER" || true) ]]; then
echo "Builder $BUILDER is missing. Aborting."; exit 1
fi
if [[ $BUILDER =~ "docker" || $BUILDER =~ "podman" ]]; then
if [[ ! $($BUILDER ps) ]]; then
echo "Builder $BUILDER is not functioning. Aborting."; exit 1
fi
fi
if [[ $BUILDER =~ "buildah" ]]; then
BUILD_COMMAND="bud"
fi
fi
# If Dockerfile is empty, build all Dockerfiles
if [ -z ${DOCKERFILE} ]; then
DOCKERFILES_TO_BUILD="$(ls ${DIR}/Dockerfile*)"
@ -137,26 +171,26 @@ build_image() {
-e "s;\${BUILD_PREFIX};${PREFIX};" \
-e "s;\${BUILD_TAG};${TAG};" \
> ${DIR}/.Dockerfile
cd "${DIR}" && docker build -f ${DIR}/.Dockerfile -t ${IMAGE_NAME} ${BUILD_ARGS} .
cd "${DIR}" && "${BUILDER}" "${BUILD_COMMAND}" -f ${DIR}/.Dockerfile -t ${IMAGE_NAME} ${BUILD_ARGS} .
DOCKER_BUILD_STATUS=$?
rm ${DIR}/.Dockerfile
if [ $DOCKER_BUILD_STATUS -eq 0 ]; then
printf "Build of ${BLUE}${IMAGE_NAME} ${GREEN}[OK]${NC}\n"
if [ ! -z "${SHA_TAG}" ]; then
SHA_IMAGE_NAME=${ORGANIZATION}/${PREFIX}-${NAME}:${SHA_TAG}
docker tag ${IMAGE_NAME} ${SHA_IMAGE_NAME}
"${BUILDER}" tag ${IMAGE_NAME} ${SHA_IMAGE_NAME}
DOCKER_TAG_STATUS=$?
if [ $DOCKER_TAG_STATUS -eq 0 ]; then
printf "Re-tagging with SHA based tag ${BLUE}${SHA_IMAGE_NAME} ${GREEN}[OK]${NC}\n"
else
printf "${RED}Failure when tagging docker image ${SHA_IMAGE_NAME}${NC}\n"
exit 1
fi
fi
fi
if [ ! -z "${IMAGE_ALIASES}" ]; then
for TMP_IMAGE_NAME in ${IMAGE_ALIASES}
do
docker tag ${IMAGE_NAME} ${TMP_IMAGE_NAME}:${TAG}
"${BUILDER}" tag ${IMAGE_NAME} ${TMP_IMAGE_NAME}:${TAG}
DOCKER_TAG_STATUS=$?
if [ $DOCKER_TAG_STATUS -eq 0 ]; then
printf " /alias ${BLUE}${TMP_IMAGE_NAME}:${TAG}${NC} ${GREEN}[OK]${NC}\n"
@ -174,32 +208,6 @@ build_image() {
fi
}
check_docker() {
if ! docker ps > /dev/null 2>&1; then
output=$(docker ps)
printf "${RED}Docker not installed properly: ${output}${NC}\n"
exit 1
fi
}
docker_exec() {
if has_docker_for_windows_client; then
MSYS_NO_PATHCONV=1 docker.exe "$@"
else
"$(which docker)" "$@"
fi
}
has_docker_for_windows_client() {
GLOBAL_HOST_ARCH=$(docker version --format {{.Client}})
if [[ "${GLOBAL_HOST_ARCH}" = *"windows"* ]]; then
return 0
else
return 1
fi
}
get_full_path() {
echo "$(cd "$(dirname "${1}")"; pwd)/$(basename "$1")"
}
@ -227,3 +235,27 @@ get_mount_path() {
CLEAN_PATH=$(get_clean_path "${POSIX_PATH}")
echo $CLEAN_PATH
}
# grab assembly
DIR="$(cd "$(dirname "$0")"; pwd)/dockerfiles"
if [ ! -d "${DIR}/../../assembly/assembly-main/target" ]; then
echo "${ERROR}Have you built assembly/assemby-main in ${DIR}/../assembly/assembly-main 'mvn clean install'?"
exit 2
fi
# Use of folder
BUILD_ASSEMBLY_DIR=$(echo "${DIR}"/../../assembly/assembly-main/target/eclipse-che-*/eclipse-che-*/)
LOCAL_ASSEMBLY_DIR="${DIR}"/eclipse-che
if [ -d "${LOCAL_ASSEMBLY_DIR}" ]; then
rm -r "${LOCAL_ASSEMBLY_DIR}"
fi
echo "Copying assembly ${BUILD_ASSEMBLY_DIR} --> ${LOCAL_ASSEMBLY_DIR}"
cp -r "${BUILD_ASSEMBLY_DIR}" "${LOCAL_ASSEMBLY_DIR}"
init --name:server "$@"
build
#cleanUp
rm -rf ${DIR}/eclipse-che

View File

@ -10,7 +10,7 @@
#
# https://access.redhat.com/containers/?tab=tags#/registry.access.redhat.com/ubi8-minimal
FROM registry.access.redhat.com/ubi8-minimal:8.8-1037
FROM registry.access.redhat.com/ubi8-minimal:8.9-1161
USER root
ENV CHE_HOME=/home/user/eclipse-che
ENV JAVA_HOME=/usr/lib/jvm/jre

View File

@ -0,0 +1,40 @@
# Copyright (c) 2018-2023 Red Hat, Inc.
# This program and the accompanying materials are made
# available under the terms of the Eclipse Public License 2.0
# which is available at https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# Red Hat, Inc. - initial API and implementation
#
# https://access.redhat.com/containers/?tab=tags#/registry.access.redhat.com/ubi8-minimal
FROM ubi8-minimal:8.9-1161
USER root
ENV CHE_HOME=/home/user/devspaces
ENV JAVA_HOME=/usr/lib/jvm/jre
RUN microdnf install java-11-openjdk-headless tar gzip shadow-utils findutils && \
microdnf update -y && \
microdnf -y clean all && rm -rf /var/cache/yum && echo "Installed Packages" && rpm -qa | sort -V && echo "End Of Installed Packages" && \
adduser -G root user && mkdir -p /home/user/devspaces
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
# see fetch-artifacts-pnc.yaml
COPY artifacts/assembly-main.tar.gz /tmp/assembly-main.tar.gz
RUN tar xzf /tmp/assembly-main.tar.gz --strip-components=1 -C /home/user/devspaces; rm -f /tmp/assembly-main.tar.gz
# this should fail if the startup script is not found in correct path /home/user/devspaces/tomcat/bin/catalina.sh
RUN mkdir /logs /data && \
chmod 0777 /logs /data && \
chgrp -R 0 /home/user /logs /data && \
chown -R user /home/user && \
chmod -R g+rwX /home/user && \
find /home/user -type d -exec chmod 777 {} \; && \
java -version && echo -n "Server startup script in: " && \
find /home/user/devspaces -name catalina.sh | grep -z /home/user/devspaces/tomcat/bin/catalina.sh
USER user
# append Brew metadata here

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
Copyright (c) 2012-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
@ -17,7 +17,7 @@
<parent>
<artifactId>che-core-parent</artifactId>
<groupId>org.eclipse.che.core</groupId>
<version>7.73.0-SNAPSHOT</version>
<version>7.86.0-SNAPSHOT</version>
</parent>
<artifactId>che-core-api-core</artifactId>
<packaging>jar</packaging>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* Copyright (c) 2012-2023 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
@ -11,7 +11,10 @@
*/
package org.eclipse.che.api.core.rest;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toList;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
@ -19,6 +22,7 @@ import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import javax.inject.Singleton;
import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
@ -42,11 +46,18 @@ public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException>
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
final String utcTime = dateFormat.format(new Date());
final String errorMessage = format("Internal Server Error occurred, error time: %s", utcTime);
String message = exception.getMessage();
final String errorMessage =
isNullOrEmpty(message)
? format("Internal Server Error occurred, error time: %s", utcTime)
: message;
LOG.error(errorMessage, exception);
ServiceError serviceError = DtoFactory.newDto(ServiceError.class).withMessage(errorMessage);
List<String> trace =
stream(exception.getStackTrace()).map(StackTraceElement::toString).collect(toList());
ServiceError serviceError =
DtoFactory.newDto(ServiceError.class).withMessage(errorMessage).withTrace(trace);
return Response.serverError()
.entity(DtoFactory.getInstance().toJson(serviceError))
.type(MediaType.APPLICATION_JSON)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* Copyright (c) 2012-2023 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
@ -11,6 +11,7 @@
*/
package org.eclipse.che.api.core.rest.shared.dto;
import java.util.List;
import org.eclipse.che.dto.shared.DTO;
/**
@ -30,8 +31,12 @@ public interface ServiceError {
*/
String getMessage();
List<String> getTrace();
ServiceError withMessage(String message);
ServiceError withTrace(List<String> trace);
/**
* Set error message.
*

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
Copyright (c) 2012-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
@ -17,7 +17,7 @@
<parent>
<artifactId>che-core-parent</artifactId>
<groupId>org.eclipse.che.core</groupId>
<version>7.73.0-SNAPSHOT</version>
<version>7.86.0-SNAPSHOT</version>
</parent>
<artifactId>che-core-api-dto-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
Copyright (c) 2012-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
@ -17,7 +17,7 @@
<parent>
<artifactId>che-core-parent</artifactId>
<groupId>org.eclipse.che.core</groupId>
<version>7.73.0-SNAPSHOT</version>
<version>7.86.0-SNAPSHOT</version>
</parent>
<artifactId>che-core-api-dto</artifactId>
<packaging>jar</packaging>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
Copyright (c) 2012-2024 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
@ -17,7 +17,7 @@
<parent>
<artifactId>che-core-parent</artifactId>
<groupId>org.eclipse.che.core</groupId>
<version>7.73.0-SNAPSHOT</version>
<version>7.86.0-SNAPSHOT</version>
</parent>
<artifactId>che-core-api-model</artifactId>
<packaging>jar</packaging>

View File

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-core-parent</artifactId>
<groupId>org.eclipse.che.core</groupId>
<version>7.73.0-SNAPSHOT</version>
</parent>
<artifactId>che-core-db-vendor-h2</artifactId>
<name>Che Core :: Commons :: DB :: Vendor H2</name>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-db</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>jakarta.persistence</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,40 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.h2.jpa.eclipselink;
import java.sql.SQLException;
import org.eclipse.che.core.db.jpa.DuplicateKeyException;
import org.eclipse.che.core.db.jpa.IntegrityConstraintViolationException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.ExceptionHandler;
/**
* Rethrows vendor specific exceptions as common exceptions. See <a
* href="http://www.h2database.com/javadoc/org/h2/api/ErrorCode.html">H2 error codes</a>.
*
* @author Yevhenii Voevodin
*/
public class H2ExceptionHandler implements ExceptionHandler {
public Object handleException(RuntimeException exception) {
if (exception instanceof DatabaseException && exception.getCause() instanceof SQLException) {
final SQLException sqlEx = (SQLException) exception.getCause();
switch (sqlEx.getErrorCode()) {
case 23505:
throw new DuplicateKeyException(exception.getMessage(), exception);
case 23506:
throw new IntegrityConstraintViolationException(exception.getMessage(), exception);
}
}
throw exception;
}
}

View File

@ -1,47 +0,0 @@
/*
* Copyright (c) 2012-2023 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.h2.jpa.eclipselink;
import static com.google.common.base.MoreObjects.firstNonNull;
import org.eclipse.che.core.db.JNDIDataSourceFactory;
public class H2SQLJndiDataSourceFactory extends JNDIDataSourceFactory {
private static final String DEFAULT_USERNAME = "username";
private static final String DEFAULT_PASSWORD = "password";
private static final String DEFAULT_URL = "jdbc:h2:file:/data/h2";
private static final String DEFAULT_DRIVER__CLASS__NAME = "org.h2.Driver";
private static final String DEFAULT_MAX__TOTAL = "20";
private static final String DEFAULT_MAX__IDLE = "2";
private static final String DEFAULT_MAX__WAIT__MILLIS = "-1";
public H2SQLJndiDataSourceFactory() throws Exception {
super(
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_USERNAME")), DEFAULT_USERNAME),
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_PASSWORD")), DEFAULT_PASSWORD),
firstNonNull(nullStringToNullReference(System.getenv("CHE_JDBC_H2_URL")), DEFAULT_URL),
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_DRIVER__CLASS__NAME")),
DEFAULT_DRIVER__CLASS__NAME),
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__TOTAL")), DEFAULT_MAX__TOTAL),
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__IDLE")), DEFAULT_MAX__IDLE),
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__WAIT__MILLIS")),
DEFAULT_MAX__WAIT__MILLIS));
;
}
}

View File

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-core-parent</artifactId>
<groupId>org.eclipse.che.core</groupId>
<version>7.73.0-SNAPSHOT</version>
</parent>
<artifactId>che-core-db-vendor-mysql</artifactId>
<name>Che Core :: Commons :: DB :: Vendor MySQL</name>
<dependencies>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-db</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>jakarta.persistence</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,40 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.mysql.jpa.eclipselink;
import java.sql.SQLException;
import org.eclipse.che.core.db.jpa.DuplicateKeyException;
import org.eclipse.che.core.db.jpa.IntegrityConstraintViolationException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.ExceptionHandler;
/**
* Rethrows vendor specific exceptions as common exceptions. See <a
* href="https://dev.mysql.com/doc/refman/8.0/en/error-messages-server.html">MySQL error codes</a>.
*
* @author Barry Dresdner
*/
public class MySqlExceptionHandler implements ExceptionHandler {
@Override
public Object handleException(RuntimeException exception) {
if (exception instanceof DatabaseException && exception.getCause() instanceof SQLException) {
final SQLException sqlEx = (SQLException) exception.getCause();
switch (sqlEx.getErrorCode()) {
case 1062:
throw new DuplicateKeyException(exception.getMessage(), exception);
case 1452:
throw new IntegrityConstraintViolationException(exception.getMessage(), exception);
}
}
throw exception;
}
}

View File

@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-core-parent</artifactId>
<groupId>org.eclipse.che.core</groupId>
<version>7.73.0-SNAPSHOT</version>
</parent>
<artifactId>che-core-db-vendor-postgresql</artifactId>
<name>Che Core :: Commons :: DB :: Vendor PostgreSQL</name>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-db</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>jakarta.persistence</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.postgresql;
import static com.google.common.base.MoreObjects.firstNonNull;
import org.eclipse.che.core.db.JNDIDataSourceFactory;
/**
* Environment params based JNDI data source factory for Postgres.
*
* @author Sergii Kabashniuk
*/
public class PostgreSQLJndiDataSourceFactory extends JNDIDataSourceFactory {
private static final String DEFAULT_USERNAME = "pgche";
private static final String DEFAULT_PASSWORD = "pgchepassword";
private static final String DEFAULT_URL = "jdbc:postgresql://postgres:5432/dbche";
private static final String DEFAULT_DRIVER__CLASS__NAME = "org.postgresql.Driver";
private static final String DEFAULT_MAX__TOTAL = "20";
private static final String DEFAULT_MAX__IDLE = "2";
private static final String DEFAULT_MAX__WAIT__MILLIS = "-1";
public PostgreSQLJndiDataSourceFactory() throws Exception {
super(
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_USERNAME")), DEFAULT_USERNAME),
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_PASSWORD")), DEFAULT_PASSWORD),
firstNonNull(nullStringToNullReference(System.getenv("CHE_JDBC_URL")), DEFAULT_URL),
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_DRIVER__CLASS__NAME")),
DEFAULT_DRIVER__CLASS__NAME),
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__TOTAL")), DEFAULT_MAX__TOTAL),
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__IDLE")), DEFAULT_MAX__IDLE),
firstNonNull(
nullStringToNullReference(System.getenv("CHE_JDBC_MAX__WAIT__MILLIS")),
DEFAULT_MAX__WAIT__MILLIS));
}
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.postgresql.jpa.eclipselink;
import java.sql.SQLException;
import org.eclipse.che.core.db.jpa.DuplicateKeyException;
import org.eclipse.che.core.db.jpa.IntegrityConstraintViolationException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.ExceptionHandler;
/**
* Rethrows vendor specific exceptions as common exceptions. See <a
* href="https://www.postgresql.org/docs/9.4/static/errcodes-appendix.html">PostgreSQL error
* codes</a>.
*
* @author Yevhenii Voevodin
* @author Sergii Kabashniuk
*/
public class PostgreSqlExceptionHandler implements ExceptionHandler {
public Object handleException(RuntimeException exception) {
if (exception instanceof DatabaseException && exception.getCause() instanceof SQLException) {
final SQLException sqlEx = (SQLException) exception.getCause();
switch (sqlEx.getSQLState()) {
case "23505":
throw new DuplicateKeyException(exception.getMessage(), exception);
case "23503":
throw new IntegrityConstraintViolationException(exception.getMessage(), exception);
}
}
throw exception;
}
}

View File

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2023 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>che-core-parent</artifactId>
<groupId>org.eclipse.che.core</groupId>
<version>7.73.0-SNAPSHOT</version>
</parent>
<artifactId>che-core-db</artifactId>
<name>Che Core :: Commons :: DB</name>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-persist</artifactId>
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-util</artifactId>
</dependency>
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-jdbc</artifactId>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-inject</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.extension</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>jakarta.persistence</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-lang</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db;
/**
* Defines common database error codes which should be used throughout the application in preference
* to vendor specific error codes.
*
* @author Yevhenii Voevodin
*/
public enum DBErrorCode {
/** When database error can't be described with one of the other values of this enumeration. */
UNDEFINED(-1),
/**
* When any of the unique constraints is violated e.g. duplicate key or unique index violation.
*/
DUPLICATE_KEY(1),
/** When entity referenced foreign key does not exist */
INTEGRITY_CONSTRAINT_VIOLATION(2);
private final int code;
DBErrorCode(int code) {
this.code = code;
}
/** Returns the code of this error. */
public int getCode() {
return code;
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.persistence.EntityManagerFactory;
import org.eclipse.che.core.db.jpa.JpaInitializer;
import org.eclipse.che.core.db.jpa.eclipselink.GuiceEntityListenerInjectionManager;
import org.eclipse.che.core.db.schema.SchemaInitializationException;
import org.eclipse.che.core.db.schema.SchemaInitializer;
import org.eclipse.persistence.internal.sessions.AbstractSession;
/**
* Initializes database components.
*
* <p>Those components which require any persistence operations on their bootstrap have to depend on
* this component. For example:
*
* <pre>
* class StackExistsChecker {
*
* &#064;@Inject
* &#064;SuppressWarnings("unused")
* private DBInitializer dbInitializer;
*
* &#064;PostConstruct
* public void check() {
* ....
* }
* }
* </pre>
*
* In this way it is guaranteed that all database related components will be appropriately
* initialized before {@code check} method is executed.
*
* @author Yevhenii Voevodin
*/
@Singleton
public class DBInitializer {
/**
* when value for this key true, then its mean that db is initialized at first time, otherwise db
* was previously initialized
*/
public static final String BARE_DB_INIT_PROPERTY_NAME = "bare_database_init";
private final Map<String, String> initProperties;
@Inject
public DBInitializer(SchemaInitializer schemaInitializer, JpaInitializer jpaInitializer)
throws SchemaInitializationException {
// schema must be initialized before any other component that may interact with database
initProperties = ImmutableMap.copyOf(schemaInitializer.init());
// jpa initialization goes next
jpaInitializer.init();
}
@Inject
public void setUpInjectionManager(
GuiceEntityListenerInjectionManager injManager, EntityManagerFactory emFactory) {
final AbstractSession session = emFactory.unwrap(AbstractSession.class);
session.setInjectionManager(injManager);
}
/** Returns map of properties which represents state of database while initialization process */
public Map<String, String> getInitProperties() {
return initProperties;
}
/**
* Returns true only if database was initialized at first time otherwise false would be returned
*/
public boolean isBareInit() {
return Boolean.parseBoolean(initProperties.get(BARE_DB_INIT_PROPERTY_NAME));
}
}

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db;
import com.google.inject.Inject;
import com.google.inject.persist.PersistService;
import java.lang.reflect.Field;
import javax.inject.Singleton;
import javax.persistence.EntityManagerFactory;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.coordination.jgroups.JGroupsRemoteConnection;
import org.eclipse.persistence.sessions.coordination.CommandManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Stops {@link PersistService} when a system is ready to shutdown.
*
* @author Anton Korneta
*/
@Singleton
public class DBTermination {
private static final Logger LOG = LoggerFactory.getLogger(DBTermination.class);
private final PersistService persistService;
private final EntityManagerFactory emFactory;
@Inject
public DBTermination(PersistService persistService, EntityManagerFactory emFactory) {
this.persistService = persistService;
this.emFactory = emFactory;
}
/** Stops {@link PersistService}. Any DB operations are impossible after that. */
public void terminate() {
try {
LOG.info("Stopping persistence service.");
fixJChannelClosing(emFactory);
persistService.stop();
} catch (RuntimeException ex) {
LOG.error("Failed to stop persistent service. Cause: " + ex.getMessage());
}
}
/**
* This method is hack that changes value of {@link JGroupsRemoteConnection#isLocal} to false.
* This is needed to close the JGroups EclipseLinkCommandChannel and as result gracefully stop of
* the system.<br>
* For more details see {@link JGroupsRemoteConnection#closeInternal()}
*
* <p>The corresponding eclipse-link extension issue
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=534148
*/
private void fixJChannelClosing(EntityManagerFactory emFactory) {
try {
final AbstractSession session = emFactory.unwrap(AbstractSession.class);
CommandManager commandManager = session.getCommandManager();
if (commandManager == null) {
// not cluster mode
return;
}
final JGroupsRemoteConnection conn =
(JGroupsRemoteConnection) commandManager.getTransportManager().getConnectionToLocalHost();
final Field isLocal = conn.getClass().getDeclaredField("isLocal");
isLocal.setAccessible(true);
isLocal.set(conn, false);
} catch (IllegalAccessException | NoSuchFieldException ex) {
LOG.error(
"Failed to change JGroupsRemoteConnection#isLocal. This may prevent the graceful stop of "
+ "the system because EclipseLinkCommandChannel will not be closed. Cause: "
+ ex.getMessage());
}
}
}

View File

@ -1,79 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db;
import static org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory.createDataSource;
import static org.eclipse.che.core.db.TracingDataSource.wrapWithTracingIfEnabled;
import java.util.Hashtable;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import javax.sql.DataSource;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Abstract JNDI factory that constructs {@link BasicDataSource} objects from the given params.
* Should not be used directly and must be subclassed to provide instantiation params from needful
* source.
*
* @author Sergii Kabashniuk
*/
public abstract class JNDIDataSourceFactory implements ObjectFactory {
private static final Logger LOG = LoggerFactory.getLogger(JNDIDataSourceFactory.class);
private final DataSource dataSource;
public JNDIDataSourceFactory(
String userName,
String password,
String url,
String driverClassName,
String maxTotal,
String maxIdle,
String maxWaitMillis)
throws Exception {
Properties poolConfigurationProperties = new Properties();
poolConfigurationProperties.setProperty("username", userName);
poolConfigurationProperties.setProperty("password", password);
poolConfigurationProperties.setProperty("url", url);
poolConfigurationProperties.setProperty("driverClassName", driverClassName);
poolConfigurationProperties.setProperty("maxTotal", maxTotal);
poolConfigurationProperties.setProperty("maxIdle", maxIdle);
poolConfigurationProperties.setProperty("maxWaitMillis", maxWaitMillis);
dataSource = wrapWithTracingIfEnabled(createDataSource(poolConfigurationProperties));
}
@Override
public Object getObjectInstance(
Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
LOG.info(
"This={} obj={} name={} Context={} environment={}", this, obj, name, nameCtx, environment);
return dataSource;
}
/**
* Util method to convert string {@code "NULL"} to null reference. Allows to set string {@code
* "NULL"} as a value of the property instead of making sure it is unset as it is done in {@link
* org.eclipse.che.inject.CheBootstrap}
*
* @param value value to transform if needed
* @return null or passed value
*/
protected static String nullStringToNullReference(String value) {
return "NULL".equals(value) ? null : value;
}
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db;
import com.google.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
/**
* Provides data source based on jndi resource name.
*
* @author Yevhenii Voevodin
*/
public class JndiDataSourceProvider implements Provider<DataSource> {
@Inject
@Named("jndi.datasource.name")
private String name;
@Override
public DataSource get() {
try {
final InitialContext context = new InitialContext();
return (DataSource) context.lookup(name);
} catch (NamingException x) {
throw new IllegalStateException(x.getLocalizedMessage(), x);
}
}
}

View File

@ -1,106 +0,0 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db;
import com.google.common.annotations.Beta;
import io.opentracing.contrib.jdbc.ConnectionInfo;
import io.opentracing.contrib.jdbc.TracingConnection;
import io.opentracing.contrib.jdbc.parser.URLParser;
import io.opentracing.util.GlobalTracer;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
import javax.sql.DataSource;
import org.slf4j.LoggerFactory;
/**
* Adding tracing support for existing @{@link javax.sql.DataSource}. DbType and DbUser information
* omitted in traces. Traced are made only if active span exists. Prerequisites of using this class
* is that @{@link io.opentracing.Tracer} should be set in @{@link io.opentracing.util.GlobalTracer}
*
* @author Sergii Kabashniuk
*/
@Beta
public class TracingDataSource implements DataSource {
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(TracingDataSource.class);
private final DataSource delegate;
private final ConnectionInfo connectionInfo;
public TracingDataSource(DataSource delegate) {
this.delegate = delegate;
try (Connection connection = delegate.getConnection()) {
connectionInfo = URLParser.parser(connection.getMetaData().getURL());
LOG.debug(
"URL {} connectionInfo {}",
connection.getMetaData().getURL(),
connectionInfo.getPeerService());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public Connection getConnection() throws SQLException {
return new TracingConnection(
delegate.getConnection(), connectionInfo, true, null, GlobalTracer.get());
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return new TracingConnection(
delegate.getConnection(username, password), connectionInfo, true, null, GlobalTracer.get());
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return delegate.unwrap(iface);
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return delegate.isWrapperFor(iface);
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return delegate.getLogWriter();
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
delegate.setLogWriter(out);
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
delegate.setLoginTimeout(seconds);
}
@Override
public int getLoginTimeout() throws SQLException {
return delegate.getLoginTimeout();
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return delegate.getParentLogger();
}
public static DataSource wrapWithTracingIfEnabled(DataSource dataSource) {
return Boolean.valueOf(System.getenv("CHE_DB_TRACING_ENABLED"))
? new TracingDataSource(dataSource)
: dataSource;
}
}

View File

@ -1,38 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.cascade;
/**
* Context that is used only for sharing the state of the cascading operation among subscribers.
*
* @author Anton Korneta
* @author Sergii Leshchenko
*/
public class CascadeContext {
private Exception cause;
/** Returns the cause which has changed the state of the context. */
public Exception getCause() {
return cause;
}
/** Returns the state of the context. */
public boolean isFailed() {
return cause != null;
}
/** Sets the context into failed state. */
public CascadeContext fail(Exception cause) {
this.cause = cause;
return this;
}
}

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.cascade;
import org.eclipse.che.api.core.notification.EventSubscriber;
import org.eclipse.che.core.db.cascade.event.CascadeEvent;
/**
* Receives events and puts exceptions in the context to perform rollback operation if it is
* necessary.
*
* @author Anton Korneta
* @author Sergii Leschenko
*/
public abstract class CascadeEventSubscriber<T extends CascadeEvent> implements EventSubscriber<T> {
@Override
public void onEvent(T event) {
if (!event.getContext().isFailed()) {
try {
onCascadeEvent(event);
} catch (Exception ex) {
event.getContext().fail(ex);
}
}
}
/**
* Receives notification about cascade event.
*
* <p>If the method throws an exception it will be set to context to break event publishing and
* rethrow exception. Event is responsible for rethrowing or wrapping original exception.
*
* @see CascadeEvent#propagateException()
*/
public abstract void onCascadeEvent(T event) throws Exception;
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.cascade.event;
import org.eclipse.che.core.db.cascade.CascadeContext;
/**
* Special event type which is needed only for notification in the process which can require cascade
* operation.
*
* <p>Publisher should invoke {@link #propagateException()} to get cause of event canceling.
*
* <p>Rollback of operation must be performed when subscriber throws {@link Exception} during event
* processing.
*
* <p>Usage example:
*
* <pre>
* EventService bus = new EventService();
* bus.subscribe(new CascadeEventSubscriber&lt;MyEvent&gt;() {
* &#64;Override
* public void onCascadeEvent(MyEvent event) throws Exception {
* if (event.getEntityName().startsWith("reserved")) {
* throw new ConflictException("Entity name can't start with `reserved`.");
* }
* }
* });
* bus.publish(new MyEvent(...)).propagateException();
* </pre>
*
* @author Anton Korneta
* @author Sergii Leschenko
*/
public abstract class CascadeEvent {
protected final CascadeContext context = new CascadeContext();
public CascadeContext getContext() {
return context;
}
/**
* Propagates exception if subscriber throws it while event processing otherwise do nothing
*
* @throws Exception when any subscriber throws {@link Exception}
*/
public void propagateException() throws Exception {
if (context.isFailed()) {
throw context.getCause();
}
}
}

View File

@ -1,38 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.cascade.event;
import org.eclipse.che.api.core.ConflictException;
import org.eclipse.che.api.core.ServerException;
/**
* Cascade event about an entity persisting.
*
* <p>{@link ConflictException} or {@link ServerException} can be rethrown during exception
* propagating.
*
* @author Sergii Leschenko
*/
public abstract class PersistEvent extends CascadeEvent {
@Override
public void propagateException() throws ConflictException, ServerException {
if (context.isFailed()) {
try {
throw context.getCause();
} catch (ConflictException | ServerException e) {
throw e;
} catch (Exception e) {
throw new ServerException(e.getLocalizedMessage(), e);
}
}
}
}

View File

@ -1,36 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.cascade.event;
import org.eclipse.che.api.core.ServerException;
/**
* Cascade event about an entity removing.
*
* <p>{@link ServerException} can be rethrown during exception propagating.
*
* @author Sergii Leschenko
*/
public abstract class RemoveEvent extends CascadeEvent {
@Override
public void propagateException() throws ServerException {
if (context.isFailed()) {
try {
throw context.getCause();
} catch (ServerException e) {
throw e;
} catch (Exception e) {
throw new ServerException(e.getLocalizedMessage(), e);
}
}
}
}

View File

@ -1,39 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.cascade.event;
import org.eclipse.che.api.core.ConflictException;
import org.eclipse.che.api.core.NotFoundException;
import org.eclipse.che.api.core.ServerException;
/**
* Cascade event about an entity updating.
*
* <p>{@link NotFoundException}, {@link ConflictException} or {@link ServerException} can be
* rethrown during exception propagating.
*
* @author Sergii Leschenko
*/
public abstract class UpdateEvent extends CascadeEvent {
@Override
public void propagateException() throws NotFoundException, ConflictException, ServerException {
if (context.isFailed()) {
try {
throw context.getCause();
} catch (NotFoundException | ConflictException | ServerException e) {
throw e;
} catch (Exception e) {
throw new ServerException(e.getLocalizedMessage(), e);
}
}
}
}

View File

@ -1,34 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.jpa;
import javax.persistence.RollbackException;
import org.eclipse.che.core.db.DBErrorCode;
/**
* Extends the standard {@link RollbackException} with an error code from {@link DBErrorCode}.
*
* @author Yevhenii Voevodin
*/
public class DetailedRollbackException extends RollbackException {
private DBErrorCode code;
public DetailedRollbackException(String message, Throwable cause, DBErrorCode code) {
super(message, cause);
this.code = code;
}
public DBErrorCode getCode() {
return code;
}
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.jpa;
import org.eclipse.che.core.db.DBErrorCode;
/**
* Thrown when data couldn't be updated/stored due to unique constrain violation.
*
* @author Yevhenii Voevodin
* @see DBErrorCode#DUPLICATE_KEY
*/
public class DuplicateKeyException extends DetailedRollbackException {
public DuplicateKeyException(String message, Throwable cause) {
super(message, cause, DBErrorCode.DUPLICATE_KEY);
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.jpa;
import org.eclipse.che.core.db.DBErrorCode;
/**
* Throws during inserts/updates entity that restricted by referential integrity and given
* insert/update refers to non-existing entity.
*
* @author Anton Korneta
* @see DBErrorCode#INTEGRITY_CONSTRAINT_VIOLATION
*/
public class IntegrityConstraintViolationException extends DetailedRollbackException {
public IntegrityConstraintViolationException(String message, Throwable cause) {
super(message, cause, DBErrorCode.INTEGRITY_CONSTRAINT_VIOLATION);
}
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.jpa;
import com.google.inject.ImplementedBy;
import org.eclipse.che.core.db.jpa.guice.GuiceJpaInitializer;
/**
* Initializes jpa components.
*
* @author Yevhenii Voevodin
*/
@ImplementedBy(GuiceJpaInitializer.class)
public interface JpaInitializer {
/** Initialized jpa components. */
void init();
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.jpa.eclipselink;
import com.google.inject.Inject;
import com.google.inject.Injector;
import javax.naming.NamingException;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.cdi.InjectionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Allows to use dependency injection in entity listeners.
*
* <p>Example:
*
* <pre>
* class WorkspaceEntityListener {
*
* &#064;Inject EventBus bus; <- EventBus will be injected by Guice
*
* &#064;PreRemove
* public void preRemove(Workspace workspace) {
* bus.post(new BeforeWorkspaceRemovedEvent(workspace));
* }
* }
*
* &#064;Entity
* &#064;EntityListeners(WorkspaceEntityListener.class)
* class Workspace {
* // ...
* }
* </pre>
*
* @author Yevhenii Voevodin
*/
public class GuiceEntityListenerInjectionManager implements InjectionManager {
private static final Logger LOG =
LoggerFactory.getLogger(GuiceEntityListenerInjectionManager.class);
@Inject private Injector injector;
@Override
public Object createManagedBeanAndInjectDependencies(Class entityListenerClass)
throws NamingException {
try {
return injector.getInstance(entityListenerClass);
} catch (RuntimeException x) {
LOG.error(x.getLocalizedMessage(), x);
throw new NamingException(x.getLocalizedMessage());
}
}
@Override
public void cleanUp(AbstractSession session) {
// EntityListener objects are managed by Guice, nothing to cleanup
}
}

View File

@ -1,40 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.jpa.guice;
import com.google.inject.persist.PersistService;
import javax.inject.Inject;
import org.eclipse.che.core.db.jpa.JpaInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Should be bound as eager singleton. See <a
* href="https://github.com/google/guice/wiki/JPA">doc</a>
*
* @author Yevhenii Voevodin
* @author Anton Korneta
*/
public class GuiceJpaInitializer implements JpaInitializer {
private static final Logger LOG = LoggerFactory.getLogger(GuiceJpaInitializer.class);
@Inject private PersistService persistService;
public void init() {
try {
persistService.start();
} catch (Exception x) {
LOG.error(x.getLocalizedMessage(), x);
}
}
}

View File

@ -1,28 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema;
/**
* Thrown when any schema initialization/migration problem occurs.
*
* @author Yevhenii Voevodin
*/
public class SchemaInitializationException extends Exception {
public SchemaInitializationException(String message, Throwable cause) {
super(message, cause);
}
public SchemaInitializationException(String message) {
super(message);
}
}

View File

@ -1,31 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema;
import java.util.Map;
/**
* Initializes database schema or migrates an old version of it to a new one.
*
* @author Yevhenii Voevodin
*/
public interface SchemaInitializer {
/**
* Initializes database schema or migrates an old schema to a new one.
*
* @return initialization properties
* @throws SchemaInitializationException thrown when any error occurs during schema
* initialization/migration
*/
Map<String, String> init() throws SchemaInitializationException;
}

View File

@ -1,210 +0,0 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import static java.lang.String.format;
import static java.util.stream.Collectors.toList;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteSource;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.api.MigrationType;
import org.flywaydb.core.api.MigrationVersion;
import org.flywaydb.core.api.resolver.BaseMigrationResolver;
import org.flywaydb.core.api.resolver.ResolvedMigration;
import org.flywaydb.core.internal.dbsupport.DbSupport;
import org.flywaydb.core.internal.resolver.ResolvedMigrationImpl;
import org.flywaydb.core.internal.resolver.sql.SqlMigrationExecutor;
import org.flywaydb.core.internal.util.Location;
import org.flywaydb.core.internal.util.PlaceholderReplacer;
import org.flywaydb.core.internal.util.scanner.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Resolves SQL migrations from the configured locations, allows overriding of default scripts with
* vendor specific ones.
*
* <ul>
* Migration scripts must follow the next rules:
* <li>It must be placed in the project dir directory e.g. <i>5.0.1</i>
* <li>Project dir directory must be placed in dedicated directory e.g. <i>resources/sql</i>
* <li>Migration/Initialization script name must start with a number e.g <i>1.init.sql</i>, this
* number indicates the subversion of the database migration, e.g. for dir <i>5.0.0</i> and
* migration script <i>1.init.sql</i> database migration dir will be <i>5.0.0.1</i>
* <li>If a file is not a part of migration it shouldn't end with migration prefix e.g.
* <i>.sql</i> then resolver will ignore it
* </ul>
*
* <p>For the structure:
*
* <pre>
* resources/
* sql/
* 5.0.0/
* 1.init.sql
* 5.0.0-M1/
* 1.rename_fields.sql
* 2.add_workspace_constraint.sql
* postgresql/
* 2.add_workspace_constraint.sql
* 5.0.1/
* 1.stacks_migration.sql
* </pre>
*
* And configuration:
*
* <pre>
* prefix - ""
* suffix - ".sql"
* separator - "."
* locations - "classpath:sql"
* </pre>
*
* <ul>
* 4 database migrations will be resolved
* <li>5.0.0.1 - initialization script based on file <i>sql/5.0.0/1.init.sql</i>
* <li>5.0.0.1.1 - modification script based on file <i>sql/5.0.0-M1/1.rename_fields.sql</i>
* <li>5.0.0.1.2 - modification script(if postgresql is current provider) based on file
* <i>sql/5.0.0-M1/postgresql/2.add_workspace_constraint.sql</i>
* <li>5.0.1.1 - modification script based on file <i>sql/5.0.1/1.stacks_migrations.sql</i>
* </ul>
*
* <p>It is also possible to configure several locations then all of those locations will be
* analyzed for migration scripts existence. For example:
*
* <p>For the structure:
*
* <pre>
* che/
* resources/
* che-schema/
* 5.0.0/
* 1.init.sql
* another-project/
* resources/
* custom-schema/
* 5.0.0/
* 2.init_additional_tables.sql
* </pre>
*
* And configuration:
*
* <pre>
* prefix - ""
* suffix - ".sql"
* separator - "."
* locations - "classpath:che-schema, classpath:custom-schema"
* </pre>
*
* <ul>
* 2 database migrations will be resolved
* <li>5.0.0.1 - initialization script based on file <i>che-schema/5.0.0/1.init.sql</i>
* <li>5.0.0.2 - modification script based on file
* <i>custom-schema/5.0.0/2.init_additional_tables.sql</i>
* </ul>
*
* @author Yevhenii Voevodin
*/
public class CustomSqlMigrationResolver extends BaseMigrationResolver {
private static final Logger LOG = LoggerFactory.getLogger(CustomSqlMigrationResolver.class);
private final String vendorName;
private final ResourcesFinder finder;
private final VersionResolver versionResolver;
private final SqlScriptCreator scriptsCreator;
private final DbSupport dbSupport;
private final PlaceholderReplacer placeholderReplacer;
public CustomSqlMigrationResolver(
String dbProviderName, DbSupport dbSupport, PlaceholderReplacer placeholderReplacer) {
this.vendorName = dbProviderName;
this.dbSupport = dbSupport;
this.placeholderReplacer = placeholderReplacer;
this.finder = new ResourcesFinder();
this.versionResolver = new VersionResolver();
this.scriptsCreator = new SqlScriptCreator();
}
@Override
public Collection<ResolvedMigration> resolveMigrations() {
try {
return resolveSqlMigrations();
} catch (IOException | SQLException x) {
throw new RuntimeException(x.getLocalizedMessage(), x);
}
}
private List<ResolvedMigration> resolveSqlMigrations() throws IOException, SQLException {
LOG.info(
"Searching for SQL scripts in locations {}",
Arrays.toString(flywayConfiguration.getLocations()));
final Map<Location, List<Resource>> allResources = finder.findResources(flywayConfiguration);
LOG.debug("Found scripts: {}", allResources);
final Map<String, Map<String, SqlScript>> scriptsInDir = new HashMap<>();
for (Location location : allResources.keySet()) {
final List<Resource> resources = allResources.get(location);
for (Resource resource : resources) {
final SqlScript newScript = scriptsCreator.createScript(location, resource);
if (!scriptsInDir.containsKey(newScript.dir)) {
scriptsInDir.put(newScript.dir, new HashMap<>(4));
}
final Map<String, SqlScript> existingScripts = scriptsInDir.get(newScript.dir);
final SqlScript existingScript = existingScripts.get(newScript.name);
if (existingScript == null) {
existingScripts.put(newScript.name, newScript);
} else if (Objects.equals(existingScript.vendor, newScript.vendor)) {
throw new FlywayException(
format(
"More than one script with name '%s' is registered for "
+ "database vendor '%s', script '%s' conflicts with '%s'",
newScript.name, existingScript.vendor, newScript, existingScript));
} else if (vendorName.equals(newScript.vendor)) {
existingScripts.put(newScript.name, newScript);
}
}
}
final Map<MigrationVersion, ResolvedMigration> migrations = new HashMap<>();
for (SqlScript script :
scriptsInDir.values().stream()
.flatMap(scripts -> scripts.values().stream())
.collect(toList())) {
final ResolvedMigrationImpl migration = new ResolvedMigrationImpl();
migration.setVersion(versionResolver.resolve(script, flywayConfiguration));
migration.setScript(script.resource.getLocation());
migration.setPhysicalLocation(script.resource.getLocationOnDisk());
migration.setType(MigrationType.SQL);
migration.setDescription(script.name);
migration.setChecksum(
ByteSource.wrap(script.resource.loadAsBytes()).hash(Hashing.crc32()).asInt());
migration.setExecutor(
new SqlMigrationExecutor(
dbSupport, script.resource, placeholderReplacer, flywayConfiguration));
if (migrations.put(migration.getVersion(), migration) != null) {
throw new FlywayException("Two migrations with the same version detected");
}
}
return new ArrayList<>(migrations.values());
}
}

View File

@ -1,122 +0,0 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import static org.eclipse.che.core.db.DBInitializer.BARE_DB_INIT_PROPERTY_NAME;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import javax.sql.DataSource;
import org.eclipse.che.core.db.schema.SchemaInitializationException;
import org.eclipse.che.core.db.schema.SchemaInitializer;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.internal.dbsupport.DbSupport;
import org.flywaydb.core.internal.dbsupport.DbSupportFactory;
import org.flywaydb.core.internal.metadatatable.MetaDataTable;
import org.flywaydb.core.internal.metadatatable.MetaDataTableImpl;
import org.flywaydb.core.internal.util.PlaceholderReplacer;
/**
* <a href="https://flywaydb.org/">Flyway</a> based schema initializer.
*
* @author Yevhenii Voevodin
*/
public class FlywaySchemaInitializer implements SchemaInitializer {
private final DataSource dataSource;
private final String[] locations;
private final String scriptsPrefix;
private final String scriptsSuffix;
private final String versionSeparator;
private final boolean baselineOnMigrate;
private final String baselineVersion;
private final PlaceholderReplacer placeholderReplacer;
/**
* Creates a new instance of flyway schema initializer.
*
* @param scriptsLocations the locations where to search migration scripts, if locations is not
* prefixed or prefixed with <i>classpath:</i> then initializer will try to find scripts in
* classpath using {@code Thread.currentThread().}{@link Thread#getContextClassLoader()
* getContextClassLoader()}
* @param scriptsPrefix prefix of migration scripts e.g. 'v' or empty string
* @param scriptsSuffix suffix of migration scripts e.g. '.sql'
* @param versionSeparator separate version from the other part of script name e.g. '.' or '__'
* @param baselineOnMigrate whether to ignore scripts up to the version configured by {@code
* baselineVersion}
* @param baselineVersion up to this version all the scripts ignored, unless schema is initialized
* first time, note that scripts with version equal to baseline version are also ignored
* @param dataSource data source used for migrations
* @param placeholderReplacer used to replace variables in script with configured values
*/
@Inject
public FlywaySchemaInitializer(
@Named("db.schema.flyway.scripts.locations") String[] scriptsLocations,
@Named("db.schema.flyway.scripts.prefix") String scriptsPrefix,
@Named("db.schema.flyway.scripts.suffix") String scriptsSuffix,
@Named("db.schema.flyway.scripts.version_separator") String versionSeparator,
@Named("db.schema.flyway.baseline.enabled") boolean baselineOnMigrate,
@Named("db.schema.flyway.baseline.version") String baselineVersion,
DataSource dataSource,
PlaceholderReplacer placeholderReplacer) {
this.dataSource = dataSource;
this.locations = scriptsLocations;
this.scriptsPrefix = scriptsPrefix;
this.scriptsSuffix = scriptsSuffix;
this.versionSeparator = versionSeparator;
this.baselineOnMigrate = baselineOnMigrate;
this.baselineVersion = baselineVersion;
this.placeholderReplacer = placeholderReplacer;
}
/** Creates a new flyway based initializer with default values. */
public FlywaySchemaInitializer(DataSource dataSource, String... locations) {
this(locations, "", ".sql", "__", false, "", dataSource, PlaceholderReplacer.NO_PLACEHOLDERS);
}
@Override
public Map<String, String> init() throws SchemaInitializationException {
final Map<String, String> initResult = new HashMap<>();
try (final Connection conn = dataSource.getConnection()) {
final Flyway flyway = new Flyway();
flyway.setDataSource(dataSource);
flyway.setLocations(locations);
flyway.setClassLoader(Thread.currentThread().getContextClassLoader());
final DbSupport dbSupport = DbSupportFactory.createDbSupport(conn, true);
final MetaDataTable mt =
new MetaDataTableImpl(
dbSupport,
dbSupport.getOriginalSchema().getTable(flyway.getTable()),
flyway.getInstalledBy());
initResult.put(BARE_DB_INIT_PROPERTY_NAME, String.valueOf(!mt.hasAppliedMigrations()));
final String productName = conn.getMetaData().getDatabaseProductName().toLowerCase();
flyway.setResolvers(
new CustomSqlMigrationResolver(productName, dbSupport, placeholderReplacer));
flyway.setSkipDefaultResolvers(true);
flyway.setBaselineOnMigrate(baselineOnMigrate);
if (baselineOnMigrate) {
flyway.setBaselineVersionAsString(baselineVersion);
}
flyway.setSqlMigrationSeparator(versionSeparator);
flyway.setSqlMigrationSuffix(scriptsSuffix);
flyway.setSqlMigrationPrefix(scriptsPrefix);
flyway.migrate();
} catch (SQLException | RuntimeException x) {
throw new SchemaInitializationException(x.getLocalizedMessage(), x);
}
return initResult;
}
}

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import javax.inject.Inject;
import javax.inject.Provider;
import org.eclipse.che.inject.ConfigurationProperties;
import org.flywaydb.core.internal.util.PlaceholderReplacer;
/**
* Placeholder replacer that uses configuration properties.
*
* @author Yevhenii Voevodin
*/
public class PlaceholderReplacerProvider implements Provider<PlaceholderReplacer> {
private final PlaceholderReplacer replacer;
@Inject
public PlaceholderReplacerProvider(ConfigurationProperties properties) {
replacer = new PlaceholderReplacer(properties.getProperties(".*"), "${", "}");
}
@Override
public PlaceholderReplacer get() {
return replacer;
}
}

View File

@ -1,57 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import static com.google.common.collect.Lists.newArrayList;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.flywaydb.core.api.configuration.FlywayConfiguration;
import org.flywaydb.core.internal.util.Location;
import org.flywaydb.core.internal.util.scanner.Resource;
import org.flywaydb.core.internal.util.scanner.classpath.ClassPathScanner;
import org.flywaydb.core.internal.util.scanner.filesystem.FileSystemScanner;
/**
* Searches for sql scripts in given places.
*
* @author Yevhenii Voevodin
*/
class ResourcesFinder {
/**
* Finds script resources in configured {@link FlywayConfiguration#getLocations()}.
*
* @param configuration flyway configuration to find scripts
* @return found scripts or an empty list if nothing found
* @throws IOException when any io error occurs during scripts look up
*/
Map<Location, List<Resource>> findResources(FlywayConfiguration configuration)
throws IOException {
final String prefix = configuration.getSqlMigrationPrefix();
final String suffix = configuration.getSqlMigrationSuffix();
final ClassPathScanner cpScanner = new ClassPathScanner(configuration.getClassLoader());
final FileSystemScanner fsScanner = new FileSystemScanner();
final Map<Location, List<Resource>> resources = new HashMap<>();
for (String rawLocation : configuration.getLocations()) {
final Location location = new Location(rawLocation);
if (location.isClassPath()) {
resources.put(location, newArrayList(cpScanner.scanForResources(location, prefix, suffix)));
} else {
resources.put(location, newArrayList(fsScanner.scanForResources(location, prefix, suffix)));
}
}
return resources;
}
}

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import java.util.Objects;
import org.flywaydb.core.internal.util.Location;
import org.flywaydb.core.internal.util.scanner.Resource;
/**
* Data object for holding information about sql script.
*
* @author Yevhenii Voevodin
*/
class SqlScript {
final Resource resource;
final Location location;
final String dir;
final String vendor;
final String name;
SqlScript(Resource resource, Location location, String dir, String vendor, String name) {
this.resource = resource;
this.location = location;
this.name = name;
this.vendor = vendor;
this.dir = dir;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof SqlScript)) {
return false;
}
final SqlScript that = (SqlScript) obj;
return Objects.equals(resource, that.resource)
&& Objects.equals(location, that.location)
&& Objects.equals(dir, that.dir)
&& Objects.equals(vendor, that.vendor)
&& Objects.equals(name, that.name);
}
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + Objects.hashCode(resource);
hash = 31 * hash + Objects.hashCode(location);
hash = 31 * hash + Objects.hashCode(dir);
hash = 31 * hash + Objects.hashCode(vendor);
hash = 31 * hash + Objects.hashCode(name);
return hash;
}
@Override
public String toString() {
return "SqlScript{"
+ "resource="
+ resource
+ ", location="
+ location
+ ", dir='"
+ dir
+ '\''
+ ", vendor='"
+ vendor
+ '\''
+ ", name='"
+ name
+ '\''
+ '}';
}
}

View File

@ -1,55 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import static java.lang.String.format;
import java.io.File;
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.internal.util.Location;
import org.flywaydb.core.internal.util.scanner.Resource;
/**
* Creates new {@link SqlScript} instance from given resource.
*
* @author Yevhenii Voevodin
*/
class SqlScriptCreator {
/**
* Create a new instance of script based on location and resource.
*
* @param location root location of the given resource
* @param resource script resource
* @return a new instance of sql script based on location and resource
* @throws FlywayException when script can't be created from the resource
*/
SqlScript createScript(Location location, Resource resource) {
final String separator = location.isClassPath() ? "/" : File.separator;
// '/root-location/5.0.0-M7/v1__init.sql' -> '5.0.0-M7/v1__init.sql'
final String relLocation = resource.getLocation().substring(location.getPath().length() + 1);
final String[] paths = relLocation.split(separator);
// 5.0.0-M1/v1__init.sql
if (paths.length == 2) {
return new SqlScript(resource, location, paths[0], null, paths[1]);
}
// 5.0.0-M1/postgresql/v1__init.sql
if (paths.length == 3) {
return new SqlScript(resource, location, paths[0], paths[1], paths[2]);
}
throw new FlywayException(
format(
"Sql script location must be either in 'location-root/version-dir' "
+ "or in 'location-root/version-dir/provider-name', but script '%s' is not in root '%s'",
resource.getLocation(), location.getPath()));
}
}

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.api.MigrationVersion;
import org.flywaydb.core.api.configuration.FlywayConfiguration;
/**
* Creates versions for scripts depending on the provided data.
*
* <ul>
* A few examples:
* <li>5.0.0-M7/v1__init.sql => 5.0.0.7.1
* <li>5.0.0-M8/v2.1__modify.sql => 5.0.0.8.2.1
* </ul>
*
* @author Yevhenii Voevodin
*/
class VersionResolver {
private static final Pattern NOT_VERSION_CHARS_PATTERN = Pattern.compile("[^0-9.]");
private final Map<String, String> normalizedDirs = new HashMap<>();
/**
* Creates migration version based on script data.
*
* @param script script for which to resolve the version
* @param configuration flyway configuration used for resolution parameters
*/
MigrationVersion resolve(SqlScript script, FlywayConfiguration configuration) {
String normalizedDir = normalizedDirs.get(script.dir);
if (normalizedDir == null) {
// 5.0.0-M1 -> 5.0.0.M1 -> 5.0.0.1
normalizedDir =
NOT_VERSION_CHARS_PATTERN.matcher(script.dir.replace("-", ".")).replaceAll("");
normalizedDirs.put(script.dir, normalizedDir);
}
// separate version from the other part of the name
final int sepIdx = script.name.indexOf(configuration.getSqlMigrationSeparator());
if (sepIdx == -1) {
throw new FlywayException(
format(
"sql script name '%s' is not valid, name must contain '%s'",
script.name, configuration.getSqlMigrationSeparator()));
}
// check whether part before separator is not empty
String version = script.name.substring(0, sepIdx);
if (version.isEmpty()) {
throw new FlywayException(
format(
"sql script name '%s' is not valid, name must provide version like "
+ "'%s4%smigration_description.sql",
configuration.getSqlMigrationPrefix(),
script.name,
configuration.getSqlMigrationSeparator()));
}
// extract sql script version without prefix
final String prefix = configuration.getSqlMigrationPrefix();
if (!isNullOrEmpty(prefix) && script.name.startsWith(prefix)) {
version = version.substring(prefix.length());
}
return MigrationVersion.fromVersion(normalizedDir + '.' + version);
}
}

View File

@ -1,123 +0,0 @@
/*
* Copyright (c) 2012-2021 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db;
import static org.mockito.Mockito.lenient;
import static org.testng.Assert.assertEquals;
import com.google.common.collect.ImmutableMap;
import io.opentracing.contrib.jdbc.TracingConnection;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(value = {MockitoTestNGListener.class})
public class TracingDataSourceTest {
@Mock DataSource dataSource;
@Mock Connection connection;
@Mock DatabaseMetaData databaseMetaData;
@BeforeMethod
@AfterMethod
public void cleanup() throws Exception {
HashMap<String, String> newEnv = new HashMap<>(System.getenv());
newEnv.remove("CHE_DB_TRACING_ENABLED");
setEnv(newEnv);
lenient().when(dataSource.getConnection()).thenReturn(connection);
lenient().when(connection.getMetaData()).thenReturn(databaseMetaData);
}
@Test
public void shouldBeAbleToGetConnection() throws SQLException {
TracingDataSource ds = new TracingDataSource(dataSource);
Connection actual = ds.getConnection();
assertEquals(actual.getClass(), TracingConnection.class);
Mockito.verify(dataSource, Mockito.times(2)).getConnection();
}
@Test
public void shouldBeAbleToGetConnectionWithEmailAndPassword() throws SQLException {
TracingDataSource ds = new TracingDataSource(dataSource);
Connection actual = ds.getConnection("user", "password");
assertEquals(actual.getClass(), TracingConnection.class);
Mockito.verify(dataSource).getConnection(Mockito.eq("user"), Mockito.eq("password"));
}
@Test
public void shouldBeAbleTogetTracingDataSource() throws Exception {
setEnv(ImmutableMap.of("CHE_DB_TRACING_ENABLED", "true"));
DataSource actual = TracingDataSource.wrapWithTracingIfEnabled(dataSource);
assertEquals(actual.getClass(), TracingDataSource.class);
}
@Test
public void shouldNotWrapDatasourceIfEnvSetToFalseØ() throws Exception {
setEnv(ImmutableMap.of("CHE_DB_TRACING_ENABLED", "false"));
DataSource actual = TracingDataSource.wrapWithTracingIfEnabled(dataSource);
assertEquals(actual, dataSource);
}
@Test
public void shouldNotWrapDatasourceIfEnvIsNotSet() throws Exception {
DataSource actual = TracingDataSource.wrapWithTracingIfEnabled(dataSource);
assertEquals(actual, dataSource);
}
protected static void setEnv(Map<String, String> newenv) throws Exception {
try {
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
theEnvironmentField.setAccessible(true);
Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
env.putAll(newenv);
Field theCaseInsensitiveEnvironmentField =
processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
theCaseInsensitiveEnvironmentField.setAccessible(true);
Map<String, String> cienv =
(Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
cienv.putAll(newenv);
} catch (NoSuchFieldException e) {
Class[] classes = Collections.class.getDeclaredClasses();
Map<String, String> env = System.getenv();
for (Class cl : classes) {
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Object obj = field.get(env);
Map<String, String> map = (Map<String, String>) obj;
map.clear();
map.putAll(newenv);
}
}
}
}
}

View File

@ -1,353 +0,0 @@
/*
* Copyright (c) 2012-2023 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import java.io.IOException;
import java.io.StringReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import javax.sql.DataSource;
import org.eclipse.che.commons.lang.IoUtil;
import org.eclipse.che.core.db.schema.SchemaInitializationException;
import org.eclipse.che.core.db.schema.SchemaInitializer;
import org.flywaydb.core.internal.util.PlaceholderReplacer;
import org.h2.jdbcx.JdbcDataSource;
import org.h2.tools.RunScript;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* Tests {@link FlywaySchemaInitializer}.
*
* @author Yevhenii Voevodin
*/
public class FlywaySchemaInitializerTest {
private static final String SCRIPTS_ROOT = "flyway/sql";
private JdbcDataSource dataSource;
@BeforeMethod
public void setUp() throws URISyntaxException {
dataSource = new JdbcDataSource();
dataSource.setUrl("jdbc:h2:mem:flyway_test;DB_CLOSE_DELAY=-1");
}
@AfterMethod
public void cleanup() throws SQLException, URISyntaxException {
try (Connection conn = dataSource.getConnection()) {
RunScript.execute(conn, new StringReader("SHUTDOWN"));
}
IoUtil.deleteRecursive(targetDir().resolve(Paths.get(SCRIPTS_ROOT)).toFile());
}
@Test
public void initializesSchemaWhenDatabaseIsEmpty() throws Exception {
createScript("1.0/1__init.sql", "CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));");
createScript(
"1.0/2__add_data.sql",
"INSERT INTO test VALUES(1, 'test1');"
+ "INSERT INTO test VALUES(2, 'test2');"
+ "INSERT INTO test VALUES(3, 'test3');");
createScript("2.0/1__add_more_data.sql", "INSERT INTO test VALUES(4, 'test4');");
createScript(
"2.0/postgresql/1__add_more_data.sql", "INSERT INTO test VALUES(4, 'postgresql-data');");
final SchemaInitializer initializer = FlywayInitializerBuilder.from(dataSource).build();
initializer.init();
assertEquals(
queryEntities(),
Sets.newHashSet(
new TestEntity(1, "test1"),
new TestEntity(2, "test2"),
new TestEntity(3, "test3"),
new TestEntity(4, "test4")));
// second init must do nothing, so there are no conflicts
initializer.init();
}
@Test(expectedExceptions = SchemaInitializationException.class)
public void failsIfBaseLineIsNotConfiguredProperly() throws Exception {
execQuery(
"CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));"
+ "INSERT INTO test VALUES(1, 'test1');"
+ "INSERT INTO test VALUES(2, 'test2');"
+ "INSERT INTO test VALUES(3, 'test3');");
createScript("1.0/1__init.sql", "CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));");
FlywayInitializerBuilder.from(dataSource)
.setBaselineOnMigrate(true)
.setBaselineVersion("1.0")
.build()
.init();
}
@Test
public void executesOnlyThoseMigrationsWhichGoAfterBaseline() throws Exception {
createScript("1.0/1__init.sql", "CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));");
createScript(
"2.0/1__add_data.sql",
"INSERT INTO test VALUES(1, 'test1');"
+ "INSERT INTO test VALUES(2, 'test2');"
+ "INSERT INTO test VALUES(3, 'test3');");
final FlywaySchemaInitializer initializer =
FlywayInitializerBuilder.from(dataSource)
.setBaselineOnMigrate(true)
.setBaselineVersion("1.0.1")
.build();
initializer.init();
assertEquals(
queryEntities(),
Sets.newHashSet(
new TestEntity(1, "test1"), new TestEntity(2, "test2"), new TestEntity(3, "test3")));
// second init must do nothing, so there are no conflicts
initializer.init();
}
@Test
public void initializesSchemaWhenDatabaseIsEmptyAndBaselineIsConfigured() throws Exception {
createScript("1.0/1__init.sql", "CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));");
createScript(
"2.0/1__add_data.sql",
"INSERT INTO test VALUES(1, 'test1');"
+ "INSERT INTO test VALUES(2, 'test2');"
+ "INSERT INTO test VALUES(3, 'test3');");
final FlywaySchemaInitializer initializer =
FlywayInitializerBuilder.from(dataSource)
.setBaselineOnMigrate(true)
.setBaselineVersion("1.0.1")
.build();
initializer.init();
assertEquals(
queryEntities(),
Sets.newHashSet(
new TestEntity(1, "test1"), new TestEntity(2, "test2"), new TestEntity(3, "test3")));
// second init must do nothing, so there are no conflicts
initializer.init();
}
@Test
public void selectsProviderSpecificScriptsInPreferenceToDefaultOnes() throws Exception {
createScript("1.0/1__init.sql", "CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));");
createScript("2.0/1__add_data.sql", "INSERT INTO test VALUES(1, 'default data');");
createScript("2.0/h2/1__add_data.sql", "INSERT INTO test VALUES(1, 'h2 data');");
final FlywaySchemaInitializer initializer = FlywayInitializerBuilder.from(dataSource).build();
initializer.init();
assertEquals(queryEntities(), Sets.newHashSet(new TestEntity(1, "h2 data")));
// second init must do nothing, so there are no conflicts
initializer.init();
}
@Test
public void replacesVariablesWhenPlaceholderReplacerIsConfigured() throws Exception {
createScript(
"1.0/1__init.sql",
"CREATE TABLE test (id INT, text TEXT, PRIMARY KEY (id));"
+ "INSERT INTO test VALUES(1, '${variable}');");
FlywayInitializerBuilder.from(dataSource)
.setReplacer(new PlaceholderReplacer(ImmutableMap.of("variable", "test"), "${", "}"))
.build()
.init();
assertEquals(queryEntities(), Sets.newHashSet(new TestEntity(1, "test")));
}
private Set<TestEntity> queryEntities() throws SQLException {
final Set<TestEntity> entities = new HashSet<>();
try (Connection conn = dataSource.getConnection()) {
final ResultSet result = RunScript.execute(conn, new StringReader("SELECT * FROM test"));
while (result.next()) {
entities.add(new TestEntity(result.getLong("id"), result.getString("text")));
}
}
return entities;
}
private ResultSet execQuery(String query) throws SQLException {
try (Connection conn = dataSource.getConnection()) {
return RunScript.execute(conn, new StringReader(query));
}
}
private static Path createScript(String relativePath, String content)
throws URISyntaxException, IOException {
return createFile(
targetDir().resolve(Paths.get(SCRIPTS_ROOT)).resolve(relativePath).toString(), content);
}
private static Path createFile(String filepath, String content)
throws URISyntaxException, IOException {
final Path path = targetDir().resolve(Paths.get(filepath));
if (!Files.exists(path.getParent())) {
Files.createDirectories(path.getParent());
}
Files.write(path, content.getBytes(StandardCharsets.UTF_8));
return path;
}
private static Path targetDir() throws URISyntaxException {
final URL url = Thread.currentThread().getContextClassLoader().getResource(".");
assertNotNull(url);
return Paths.get(url.toURI()).getParent();
}
private static class TestEntity {
final long id;
final String text;
private TestEntity(long id, String text) {
this.id = id;
this.text = text;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof TestEntity)) {
return false;
}
final TestEntity that = (TestEntity) obj;
return id == that.id && Objects.equals(text, that.text);
}
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + Long.hashCode(id);
hash = 31 * hash + Objects.hashCode(text);
return hash;
}
@Override
public String toString() {
return "TestEntity{" + "id=" + id + ", text='" + text + '\'' + '}';
}
}
private static class FlywayInitializerBuilder {
public static FlywayInitializerBuilder from(DataSource dataSource) {
try {
final String scriptsRoot = targetDir().resolve(Paths.get(SCRIPTS_ROOT)).toString();
return new FlywayInitializerBuilder()
.setDataSource(dataSource)
.setScriptsPrefix("")
.setScriptsSuffix(".sql")
.setVersionSeparator("__")
.setReplacer(PlaceholderReplacer.NO_PLACEHOLDERS)
.setBaselineOnMigrate(false)
.addLocation("filesystem:" + scriptsRoot);
} catch (Exception x) {
throw new RuntimeException(x.getMessage(), x);
}
}
private DataSource dataSource;
private List<String> locations;
private String scriptsPrefix;
private String scriptsSuffix;
private String versionSeparator;
private boolean baselineOnMigrate;
private String baselineVersion;
private PlaceholderReplacer replacer;
public FlywayInitializerBuilder setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
return this;
}
public FlywayInitializerBuilder setReplacer(PlaceholderReplacer replacer) {
this.replacer = replacer;
return this;
}
public FlywayInitializerBuilder addLocation(String location) {
if (locations == null) {
locations = new ArrayList<>();
}
locations.add(location);
return this;
}
public FlywayInitializerBuilder setScriptsPrefix(String scriptsPrefix) {
this.scriptsPrefix = scriptsPrefix;
return this;
}
public FlywayInitializerBuilder setScriptsSuffix(String scriptsSuffix) {
this.scriptsSuffix = scriptsSuffix;
return this;
}
public FlywayInitializerBuilder setVersionSeparator(String versionSeparator) {
this.versionSeparator = versionSeparator;
return this;
}
public FlywayInitializerBuilder setBaselineOnMigrate(boolean baselineOnMigrate) {
this.baselineOnMigrate = baselineOnMigrate;
return this;
}
public FlywayInitializerBuilder setBaselineVersion(String baselineVersion) {
this.baselineVersion = baselineVersion;
return this;
}
public FlywaySchemaInitializer build() {
if (locations == null) {
throw new IllegalStateException("locations required");
}
return new FlywaySchemaInitializer(
locations.toArray(new String[locations.size()]),
scriptsPrefix,
scriptsSuffix,
versionSeparator,
baselineOnMigrate,
baselineVersion,
dataSource,
replacer);
}
}
}

View File

@ -1,162 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import static com.google.common.collect.Sets.newHashSet;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.configuration.FlywayConfiguration;
import org.flywaydb.core.internal.util.Location;
import org.flywaydb.core.internal.util.scanner.Resource;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* Tests {@link ResourcesFinder}.
*
* @author Yevhenii Voevodin
*/
public class ResourcesFinderTest {
private final List<Path> cleanAfter = new ArrayList<>();
private final Flyway flyway = new Flyway();
@BeforeMethod
public void setUpDefaults() {
flyway.setSqlMigrationSuffix(".sql");
flyway.setSqlMigrationPrefix("");
}
@AfterMethod
public void cleanup() throws IOException {
for (Path path : cleanAfter) {
Files.delete(path);
}
cleanAfter.clear();
}
@Test
public void findsScriptsInClassPath() throws Exception {
flyway.setLocations("classpath:finder-sql-files");
cleanAfter.addAll(
createFiles(
"finder-sql-files/1.0/1.sql",
"finder-sql-files/1.0/2.sql",
"finder-sql-files/2.0/1.sql",
"finder-sql-files/2.0/postgresql/1.sql"));
final Set<String> locations = findResources(flyway).get("classpath:finder-sql-files");
assertEquals(
locations,
newHashSet(
"finder-sql-files/1.0/1.sql",
"finder-sql-files/1.0/2.sql",
"finder-sql-files/2.0/1.sql",
"finder-sql-files/2.0/postgresql/1.sql"));
}
@Test
public void findsScriptsOnFileSystem() throws Exception {
final List<Path> paths =
createFiles(
"finder-sql-files/1.0/1.sql",
"finder-sql-files/1.0/2.sql",
"finder-sql-files/2.0/1.sql",
"finder-sql-files/2.0/postgresql/1.sql");
cleanAfter.addAll(paths);
final Path finderSqlFiles = paths.get(0).getParent().getParent();
final String fsLocation = "filesystem:" + finderSqlFiles.toAbsolutePath();
flyway.setLocations(fsLocation);
final Set<String> locations = findResources(flyway).get(fsLocation);
assertEquals(
locations,
newHashSet(
finderSqlFiles.resolve("1.0").resolve("1.sql").toString(),
finderSqlFiles.resolve("1.0").resolve("2.sql").toString(),
finderSqlFiles.resolve("2.0").resolve("1.sql").toString(),
finderSqlFiles.resolve("2.0").resolve("postgresql").resolve("1.sql").toString()));
}
@Test
public void findsFileSystemAndClassPathScripts() throws Exception {
final List<Path> paths =
createFiles(
"finder-fs-sql-files/1.0/1.sql",
"finder-fs-sql-files/2.0/2.sql",
"finder-cp-sql-files/1.0/2.sql",
"finder-cp-sql-files/2.0/postgresql/1.sql");
cleanAfter.addAll(paths);
final Path finderFsSqlFiles = paths.get(0).getParent().getParent();
final String fsLocation = "filesystem:" + finderFsSqlFiles.toAbsolutePath();
final String cpLocation = "classpath:finder-cp-sql-files";
flyway.setLocations(fsLocation, cpLocation);
final Map<String, Set<String>> locations = findResources(flyway);
assertEquals(
locations.get(fsLocation),
newHashSet(
finderFsSqlFiles.resolve("1.0").resolve("1.sql").toString(),
finderFsSqlFiles.resolve("2.0").resolve("2.sql").toString()));
assertEquals(
locations.get(cpLocation),
newHashSet("finder-cp-sql-files/1.0/2.sql", "finder-cp-sql-files/2.0/postgresql/1.sql"));
}
private static Map<String, Set<String>> findResources(FlywayConfiguration configuration)
throws IOException {
final Map<Location, List<Resource>> resources =
new ResourcesFinder().findResources(configuration);
final Map<String, Set<String>> locations = new HashMap<>();
for (Map.Entry<Location, List<Resource>> entry : resources.entrySet()) {
locations.put(
entry.getKey().toString(),
entry.getValue().stream().map(Resource::getLocation).collect(Collectors.toSet()));
}
return locations;
}
private static List<Path> createFiles(String... paths) throws URISyntaxException, IOException {
final URL url = Thread.currentThread().getContextClassLoader().getResource(".");
assertNotNull(url);
final Path classesDir = Paths.get(url.toURI());
final List<Path> createdFiles = new ArrayList<>(paths.length);
for (String stringPath : paths) {
final Path path = classesDir.resolve(Paths.get(stringPath));
if (!Files.exists(path.getParent())) {
Files.createDirectories(path.getParent());
}
Files.write(path, path.toString().getBytes(StandardCharsets.UTF_8));
createdFiles.add(path);
}
return createdFiles;
}
}

View File

@ -1,67 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.internal.util.Location;
import org.flywaydb.core.internal.util.scanner.Resource;
import org.flywaydb.core.internal.util.scanner.filesystem.FileSystemResource;
import org.testng.annotations.Test;
/**
* Tests {@link SqlScriptCreator}.
*
* @author Yevhenii Voevodin
*/
public class SqlScriptCreatorTest {
@Test
public void createsScript() throws Exception {
final Location location = new Location("filesystem:schema");
final Resource resource = new FileSystemResource("schema/5.0.0-M7/v1__init.sql");
final SqlScriptCreator scriptsCreator = new SqlScriptCreator();
final SqlScript script = scriptsCreator.createScript(location, resource);
assertEquals(script.name, "v1__init.sql");
assertEquals(script.location, location);
assertEquals(script.dir, "5.0.0-M7");
assertEquals(script.resource.getLocation(), resource.getLocation());
assertNull(script.vendor);
}
@Test
public void createsVendorScript() throws Exception {
final Location location = new Location("filesystem:schema");
final Resource resource = new FileSystemResource("schema/5.0.0-M7/postgresql/v1__init.sql");
final SqlScriptCreator scriptsCreator = new SqlScriptCreator();
final SqlScript script = scriptsCreator.createScript(location, resource);
assertEquals(script.name, "v1__init.sql");
assertEquals(script.location, location);
assertEquals(script.dir, "5.0.0-M7");
assertEquals(script.resource.getLocation(), resource.getLocation());
assertEquals(script.vendor, "postgresql");
}
@Test(expectedExceptions = FlywayException.class)
public void failsToCreateResourceWhenPathIsInvalid() throws Exception {
final Location location = new Location("filesystem:schema");
final Resource resource = new FileSystemResource("schema/v1__init.sql");
new SqlScriptCreator().createScript(location, resource);
}
}

View File

@ -1,88 +0,0 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.core.db.schema.impl.flyway;
import static org.testng.Assert.assertEquals;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.api.MigrationVersion;
import org.flywaydb.core.internal.util.Location;
import org.flywaydb.core.internal.util.scanner.filesystem.FileSystemResource;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* Tests {@link VersionResolver}.
*
* @author Yevhenii Voevodin
*/
public class VersionResolverTest {
private final Flyway flyway = new Flyway();
private final VersionResolver resolver = new VersionResolver();
@BeforeMethod
public void setUpDefaults() {
flyway.setSqlMigrationSuffix(".sql");
flyway.setSqlMigrationPrefix("");
flyway.setSqlMigrationSeparator("__");
}
@Test(dataProvider = "validScripts")
public void resolvesVersion(String dir, String name, String expectedVersion) {
final SqlScript script =
new SqlScript(
new FileSystemResource("sql/" + dir + "/" + name),
new Location("filesystem:sql"),
dir,
null,
name);
assertEquals(resolver.resolve(script, flyway), MigrationVersion.fromVersion(expectedVersion));
}
@Test(dataProvider = "invalidScripts", expectedExceptions = FlywayException.class)
public void failsToResolveVersions(String dir, String name) throws Exception {
final SqlScript script =
new SqlScript(
new FileSystemResource("sql/" + dir + "/" + name),
new Location("filesystem:sql"),
dir,
null,
name);
resolver.resolve(script, flyway);
}
@DataProvider
public static Object[][] invalidScripts() {
return new String[][] {
{"1.0", "2016-11-11__init.sql"},
{"1.0", "one__init.sql"},
{"1.0", "__init.sql"},
{"1.0", "version1__script.sql"},
{"1.0", "1..1__script.sql"},
{"5..0.0", "1__init.sql"}
};
}
@DataProvider
public static Object[][] validScripts() {
return new Object[][] {
{"5.0.0-M7", "1__init.sql", "5.0.0.7.1"},
{"5.0.0-M7", "1.1__init_sub_tables.sql", "5.0.0.7.1.1"},
{"6.0", "0.1__specific_update.sql", "6.0.0.1"},
{"1.0", "1__simple.sql", "1.0.1"}
};
}
}

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2012-2018 Red Hat, Inc.
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
Red Hat, Inc. - initial API and implementation
-->
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n</pattern>
</encoder>
</appender>
<appender name="file" class="ch.qos.logback.core.FileAppender">
<File>target/log/codenvy.log</File>
<encoder>
<pattern>%-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n</pattern>
</encoder>
</appender>
<root level="ERROR">
<appender-ref ref="stdout"/>
<appender-ref ref="file"/>
</root>
</configuration>

View File

@ -1,18 +0,0 @@
--
-- Copyright (c) 2012-2018 Red Hat, Inc.
-- This program and the accompanying materials are made
-- available under the terms of the Eclipse Public License 2.0
-- which is available at https://www.eclipse.org/legal/epl-2.0/
--
-- SPDX-License-Identifier: EPL-2.0
--
-- Contributors:
-- Red Hat, Inc. - initial API and implementation
--
CREATE TABLE test (
id INT,
text TEXT,
PRIMARY KEY (id)
);

View File

@ -1,15 +0,0 @@
--
-- Copyright (c) 2012-2018 Red Hat, Inc.
-- This program and the accompanying materials are made
-- available under the terms of the Eclipse Public License 2.0
-- which is available at https://www.eclipse.org/legal/epl-2.0/
--
-- SPDX-License-Identifier: EPL-2.0
--
-- Contributors:
-- Red Hat, Inc. - initial API and implementation
--
INSERT INTO test VALUES(1, 'test1');
INSERT INTO test VALUES(2, 'test2');
INSERT INTO test VALUES(3, 'test3');

View File

@ -1,12 +0,0 @@
--
-- Copyright (c) 2012-2018 Red Hat, Inc.
-- This program and the accompanying materials are made
-- available under the terms of the Eclipse Public License 2.0
-- which is available at https://www.eclipse.org/legal/epl-2.0/
--
-- SPDX-License-Identifier: EPL-2.0
--
-- Contributors:
-- Red Hat, Inc. - initial API and implementation
--

Some files were not shown because too many files have changed in this diff Show More