-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an ability to try Workspace.Next features #9774
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, looks good to me 👍
I'll clone your changes locally and review in details.
* Should be set/read from {@link Workspace#getAttributes}. | ||
* | ||
* <p/>Value is comma separated list of features in a format: | ||
* '< feature1Name >/< feature1Version >,< feature2Name >/< feature2Version >' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is /
symbol chosen as a separator of name and version? Wouldn't :
symbol more conventional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is better to ask @skabashnyuk - it is Feature API that declares format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The format is still under discussion. I do like :
Fill free to comment. #9895
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like examples specified by the shared link contain :
as separator but Feature API is implemented with /
LOG.error( | ||
"Response doesn't contain any data, though it was expected to contain some."); | ||
throw new IOException( | ||
"Internal server error. Unexpected response body received."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say that empty response body
would be more accurate message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does message Response contains an empty body, though it was expected to contain data
looks better to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the message will contain that this response is from "Feature API" then it would be even more clear and helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
@@ -270,6 +270,8 @@ items: | |||
configMapKeyRef: | |||
key: CHE_INFRA_KUBERNETES_SERVER__STRATEGY | |||
name: che | |||
- name: CHE_WORKSPACE_FEATURE_API | |||
value: "http://feature-api-service:3000" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it better to move a value to the config map?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, will update this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job. Please ping me one more time when PR won't be WIP.
"Features format is illegal. Problematic feature entry:" + feature); | ||
} | ||
String key = featureAndVersion[0] + '/' + featureAndVersion[1]; | ||
if (featuresNameVersion.containsKey(key)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you can use feature
here instead of contacting separated values.
String parameterKey = | ||
serviceName + "/" + serviceVersion + "/${" + cheServiceParameter.getName() + "}"; | ||
parameters.putIfAbsent(parameterKey, new ArrayList<>()); | ||
List<String> cheServiceParameters = parameters.get(parameterKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parameters.putIfAbsent(parameterKey, new ArrayList<>());
List<String> cheServiceParameters = parameters.get(parameterKey);
May be rewritten in Java 8 style
List<String> cheServiceParameters = parameters.computeIfAbsent(parameterKey, (key) -> new ArrayList<>());
|
||
/** | ||
* Returns map where key is concatenation of service name, version and parameter name separated by slash symbol. | ||
* < serviceName/serviceVersion/parameter > to < parameterValue > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it's outdated format since the format is < serviceName/serviceVersion/${parameter} >
. Am I right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, thanks for pointing it out
String envVarValue = envVar.getValue(); | ||
String parameterKey = serviceKey + '/' + envVarValue; | ||
List<String> remove = parameters.remove(parameterKey); | ||
if (remove != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just idea to discuss, maybe we should set empty value if there is not the corresponding parameter value in a feature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe, I'm not sure here
// for now we match whole env variable value against '${<parameter name>}' | ||
service.getSpec() | ||
.getContainers() | ||
.forEach(container -> container.getEnv() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it would be better(maybe not =)) to rewrite it in the following manner
service.getSpec()
.getContainers()
.stream()
.flatMap(c -> c.getEnv().stream())
.forEach(envVar -> {...});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now this code throws an exception, so I can't do like that. Actually, this code looked like that before)
/** | ||
* Applies Workspace.Next configuration to an internal runtime object that represents workspace | ||
* runtime configuration on an infrastructure level. | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it may be helpful to add a note that implementations must be bound with map binder and maybe add an example of binding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure that class should know what DI container is used and declare it. I'll think about it.
@@ -270,6 +270,8 @@ items: | |||
configMapKeyRef: | |||
key: CHE_INFRA_KUBERNETES_SERVER__STRATEGY | |||
name: che | |||
- name: CHE_WORKSPACE_FEATURE_API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it makes sense to add the same configuration into OS deployment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't check workspace next on OS infra, so don't want to add it for the time
@Override | ||
public void apply(InternalEnvironment internalEnvironment, Collection<CheService> cheServices) | ||
throws InfrastructureException { | ||
KubernetesEnvironment kubernetesEnvironment = (KubernetesEnvironment) internalEnvironment; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes sense to move this line lower since it is not needed to cast environment if Che services list is empty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ur right, thanks
io.fabric8.kubernetes.api.model.Container container = | ||
new ContainerBuilder() | ||
.withImage(image) | ||
.withName(Names.generateName("")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it makes sense to add some meaningful prefix like "tooling"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
Signed-off-by: Oleksandr Garagatyi <[email protected]>
Signed-off-by: Oleksandr Garagatyi <[email protected]>
Add missing override annotations. Cleanup the code. Use existing getters instead of a field to prevent bugs with inheritance. Move public methods to the beggining of classes. Fix incorrect javadocs and misleading parameters names. Add a comment that explains why a compiler warning should be ignored. Signed-off-by: Oleksandr Garagatyi <[email protected]>
Signed-off-by: Oleksandr Garagatyi <[email protected]>
Signed-off-by: Oleksandr Garagatyi <[email protected]>
Signed-off-by: Oleksandr Garagatyi <[email protected]>
…l environment Signed-off-by: Oleksandr Garagatyi <[email protected]>
0c95ef6
to
b6cef3c
Compare
@sleshchenko I've updated PR with fixes, unit tests and rebased it against master to resolve conflicts. Please, take a look one more time. @l0rd @skabashnyuk Looks like this PR is not successful in acquiring new code reviewers, so I'll merge it as soon as @sleshchenko approves it unless other reviews appear. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job 👍
} | ||
} | ||
|
||
private void validateFeature(CheFeature feature, String name, String version) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just proposal. Maybe it would be better to move validation private methods to new Validator
class to make this class a bit smaller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not want to create a separate class for that. At least for now.
} | ||
} | ||
|
||
private void requireEqual(String version, String version1, String error, String... errorArgs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you used Refactor
functionality and it's why the arguments are named version
and version1
. Am I right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like, I don't really remember, to be honest.
return; | ||
} | ||
KubernetesEnvironment kubernetesEnvironment = (KubernetesEnvironment) internalEnvironment; | ||
Map<String, Pod> pods = ((KubernetesEnvironment) internalEnvironment).getPods(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you don't need to cast it for the second time and you can reuse kubernetesEnvironment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks
|
||
|
||
@Mock | ||
Pod pod; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like unformatted. Please don't forget to execute mvn fmt:format
before merge.
Also, I would make these variable private. It doesn't really matter while it is test class but still.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
app: feature-api | ||
name: feature-api | ||
data: | ||
CHE_REGISTRY_UPDATE_INTERVAL: "60" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it value in seconds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
@@ -0,0 +1,85 @@ | |||
--- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to have few words in Deploy Che.md
about deploying feature-api
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
Signed-off-by: Oleksandr Garagatyi <[email protected]>
4be4dfb
to
8c4be34
Compare
ci-build |
Build # 4548 - FAILED Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/4548/ to view the results. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry my review comes really late. That's a great PR and the code is clean and easy to read/review but I think we should still discuss if a Container
should have a list of Servers
.
@@ -33,3 +33,7 @@ and clean redeploy of Che. | |||
- Create namespace `che`: `kubectl create namespace che` | |||
- Deploy Che: `kubectl --namespace=che apply -f che-kubernetes.yaml` | |||
- Check Che pod status until it become `Running`: `kubectl get --namespace=che pods` | |||
|
|||
### Workspace Next: | |||
There is a file `wsnext/feature-api.yaml` which contains kubesrb service needed to test Workspace Next on kubernetes infrastructure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may want to s/kubesrb/kubesrv/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks
private List<EnvVar> env = new ArrayList<EnvVar>(); | ||
private ResourceRequirements resources = null; | ||
private List<Command> commands = new ArrayList<Command>(); | ||
private List<Server> servers = new ArrayList<Server>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't remember that Container
had a list of servers as an attribute in the original model. And I don't think that we should do that:
- A
CheService
that has a list ofContainer
and eachContainer
has a list ofServers
is something difficult to understand (what's the difference between aCheService
and aServer
?) - Moreover one of workspace.next goals was to extract the list servers that originally ran in on container into multiple containers (sidecars). So it doesn't make sense to have a list of
Server
for eachContainer
.
I would suggest to move higher (at CheService
level) the attributes of the Server
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I clearly see servers field in one of the model versions, in particular, #9292 (comment).
what's the difference between a CheService and a Server
As we discussed before usage of Service word is confusing and brings misunderstanding like this one.
Moreover one of workspace.next goals was to extract the list servers that originally ran in on container into multiple containers (sidecars). So it doesn't make sense to have a list of Server for each Container.
It make sense. We should, probably, discuss it with @skabashnyuk.
I would suggest to move higher (at CheService level) the attributes of the Server.
I don't own Workspace.Next model, so I would discuss it with Sergii first. In any case I think it makes sense to do that in a separate PR.
import java.util.List; | ||
import java.util.Objects; | ||
|
||
public class Container { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be more consistent to call it CheContainer
(as CheService
or CheFeature
)? In the issue where the model is described it is called Container
but that's weird. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe. I reused already generated files by Swagger model because I don't want to bring new changes that I would have to redo after regeneration of the model classes.
So, I believe, it is rather a suggestion for @skabashnyuk
Signed-off-by: Oleksandr Garagatyi <[email protected]>
Signed-off-by: Oleksandr Garagatyi <[email protected]>
2caf07a
to
2fcdcf1
Compare
ci-build |
Build # 4549 - FAILED Please check console output at https://ci.codenvycorp.com/job/che-pullrequests-build/4549/ to view the results. |
ci-build |
Build success. https://ci.codenvycorp.com/job/che-pullrequests-build/4550/ |
This PR is designed to be reviewed in a commit by commit manner.
It is in WIP state because not all the unit tests are finished.
What does this PR do?
Add an ability to try Workspace.Next features.
To try it out user needs to add an attribute to a workspace with name
features
and a list of features as a value.An example of value:
"org.eclipse.che.che-theia-hello/0.0.1,org.eclipse.che.che-theia-ssh/0.0.1"
This PR contains code to use Workspace.Next with the kubernetes recipe only.
Support of other recipes should be added additionally.
What issues does this PR fix or reference?
Release Notes
Docs PR