-
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 property machine.docker.local_node_host.external #2402
Conversation
Can one of the admins verify this patch? |
Nice work! Excited to have this get into master. I reviewed the changes for the che-launcher and they all look good. |
@garagatyi - this resolves a big inconvenience that users have with Docker for Mac. This eliminates a painful setup of the loopback alias on Macs. Your +1 here will be helpful. |
In my opinion changing API for that workaround is not a good way to go. It will add pain sooner or later. |
@garagatyi can you please be more specific? Where do you want to run this |
Add iptables rules in che-server container. Configure che-server in such a way that localhost is host in servers provided by Che API. So all traffic from che-server container to localhost with ports 32000-xxxxx will go through IPTables redirection to IP of xhyve where ports of all containers are available. |
Ok thanks for clarifying @garagatyi. I understand now. It's a smart solution :-) I will test that tomorrow. |
Bingo! I've struggled to apply the IP tables rules but I've finally found the following command that work if executed inside
|
I've created a new PR to address the Docker for Mac problem: eclipse-che/che-dockerfiles#12 @garagatyi I will let you choose which one of these 2 PR is more suitable but let me explain why I believe we should keep this one and close eclipse-che/che-dockerfiles#12. Apart some concerns with the iptables solution I also think that changing the Server class, adding an internal url attribute, is not just a patch to solve the Docker for Mac issue but a solution for a recurring problem. In the current model there is only one address to reach the wsagent server. That same address is used by the browser and the wsmaster. In the diagram I've called this address "Post Office". Depending on the platform the "Post Office" can be |
I tend to agree with Mario that having the internal sokution is more optimal for the longer term. And that we can continue to layer in the iptables solution where necessary. Great graphic :) |
I've updated the PR. I've added a new ServerProperties class where I moved servers "servers": {
"4401/tcp": {
"ref": "wsagent",
"protocol": "http",
"address": "localhost:32929",
"url": "http://localhost:32929/wsagent/ext",
"port": "32929",
"properties": {
"internalUrl": "http://192.168.65.2:32929/wsagent/ext",
"internalAddress": "192.168.65.2:32929",
"path": "/wsagent/ext"
}
}
} @garagatyi please review |
I like it also |
I am ok with this approach. I want to target this for M2 - solving this problem simplifies a lot of scenarios for us with Mac. |
* Internal address of the server in form <b>host:port</b> | ||
* Used by wsmaster to communicate with the server | ||
*/ | ||
String getInternalAddress(); |
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 all fields in that object are nullable.
String getPath(); | ||
|
||
/** | ||
* Internal address of the server in form <b>host:port</b> |
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.
Line break by entering 'enter' key doesn't work in javadocs. Please add dot and <p/>
or <br/>
@@ -25,25 +25,35 @@ | |||
String getRef(); | |||
|
|||
/** | |||
* Address of the server in form <b>host:port</b> | |||
* External address of the server in form <b>host:port</b> |
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.
Line break by entering 'enter' key doesn't work in javadocs. Please add dot and <p/>
or <br/>
import org.eclipse.che.api.core.model.machine.ServerProperties; | ||
|
||
/** | ||
* Describe development machine server instance. |
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.
Line break by entering 'enter' key doesn't work in javadocs. Please add <p/>
or <br/>
private final Map<String, ServerConfImpl> serversConf; | ||
|
||
@Inject | ||
public DockerInstanceRuntimeInfo(@Assisted ContainerInfo containerInfo, | ||
@Assisted String containerHost, | ||
@Assisted String containerExternalHostname, |
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 named assisted injection doesn't work when several arguments have the same class
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.
Also please check what will happen if someone provide null value as one of these parameters. I believe nullable annotation should be declared somewhere.
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've changed to named assisted injection and checked if containerExternalHostname
is null and set it to containerHost
in that case.
*/ | ||
String getAddress(); | ||
|
||
/** | ||
* Port of the server, e.g. 8080 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure should this port contain 8080
or 8080/tcp
.
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.
And it is external port. Please explain that in javadocs.
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's 8080
, the protocol is not there:
"port": "32929"
public String getPort() { return port; } | ||
|
||
@Override | ||
public ServerProperties getProperties() { return properties; }; |
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.
Please add equals/hashcode/toString methods
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.
Done
public String getInternalUrl() { | ||
return internalUrl; | ||
} | ||
} |
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.
Please add equals/hashcode/toString methods
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.
Done
private final String internalAddress; | ||
private final String internalUrl; | ||
|
||
public DevMachineServerProperties(ServerProperties dto) { |
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.
Argument doesn't have to be DTO object. Please rename parameter to not confuse developers.
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.
Done
|
||
/** | ||
* Describe development machine server instance. | ||
* {@link ServerProperties} |
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.
Curly brackets are used when link is inlined into description. When it is used as a separate tag it has the same syntax as @author
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.
Done
private final Map<String, ServerConfImpl> serversConf; | ||
|
||
@Inject | ||
public DockerInstanceRuntimeInfo(@Assisted ContainerInfo containerInfo, | ||
@Assisted String containerHost, | ||
@Assisted String containerExternalHostname, |
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.
Also please check what will happen if someone provide null value as one of these parameters. I believe nullable annotation should be declared somewhere.
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.
Overall solution is good. Code requires some cleanups and fixes.
null, | ||
null)); | ||
externalPort, | ||
new ServerPropertiesImpl(null, internalHostname + ":" + externalPort, 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.
Please ensure that null value won't be treated as string "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.
After fixup externalHostname
, internalHostname
and externalPorts
can never be null
.
dockerNodeHost != null ? dockerNodeHost : (System.getenv(CHE_DOCKER_MACHINE_HOST) != null ? | ||
System.getenv(CHE_DOCKER_MACHINE_HOST) : | ||
containerHost), | ||
dockerNodeExternalHostname != null ? dockerNodeInternalHostname : ( |
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 believe that new policy of environment variables vs property usage in Che is that environment variable has priority over property.
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.
Fixed. Env variables are now evaluated first.
"32103", | ||
new ServerPropertiesImpl("some/path4", | ||
CONTAINER_HOST + ":32103", | ||
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.
Please add tests for all new use cases, e.g. internal/external addresses are configired with properties, env variables, both null, both not-null, some is null other not.
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.
Added a couple of tests
verify(descriptor).getProperties(); | ||
verify(descriptor2).getInternalUrl(); | ||
} | ||
|
||
} |
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.
Please add trailing new line at the end of file
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.
Please add trailing new line at the end of file
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.
Fixed
@@ -10,24 +10,8 @@ | |||
*******************************************************************************/ | |||
package org.eclipse.che.api.machine.server; | |||
|
|||
import org.eclipse.che.api.core.model.machine.MachineLimits; |
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.
Wildcard imports are forbidden in Che
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.
Wildcard imports are forbidden in Che
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 for forgetting that. I've fixed it.
} | ||
|
||
public ServerImpl(Server server) { | ||
this(server.getRef(), server.getProtocol(), server.getAddress(), server.getPath(), server.getUrl()); | ||
this(server.getRef(), server.getProtocol(), server.getAddress(), server.getUrl(), server.getPort(), (ServerPropertiesImpl) server.getProperties()); |
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 better to avoid casting here as it prevents class cast exception. Please rewrite first constructor instead.
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.
Fixed
@@ -24,14 +24,7 @@ | |||
import org.eclipse.che.api.core.rest.shared.dto.ServiceError; | |||
import org.eclipse.che.api.environment.server.MachineProcessManager; | |||
import org.eclipse.che.api.environment.server.MachineServiceLinksInjector; | |||
import org.eclipse.che.api.machine.server.model.impl.CommandImpl; |
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.
Please do not use wildcard imports
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.
Please do not use wildcard imports
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.
Fixed
@Override | ||
public String getInternalUrl() { | ||
return descriptor.getInternalUrl(); | ||
} |
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.
Please add equals/hashcode/toString methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class still needs equals/hashcode/toString methods
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.
Class https://github.com/eclipse/che/blob/master/plugins/plugin-machine/che-plugin-machine-ext-client/src/main/java/org/eclipse/che/ide/extension/machine/client/perspective/widgets/machine/appliance/server/Server.java had no equals method. Should I add equals/hashcode/toString to existing classes too?
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.
At least add it in classes added by 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.
I've added for both.
* This address is used by the browser to communicate with the server and | ||
* corresponds to the internal address if not explicitly set. | ||
* Can be set using property machine.docker.local_node_host.external or | ||
* environment variable CHE_DOCKER_MACHINE_HOST_EXTERNAL | ||
*/ | ||
String getAddress(); |
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.
Now this method returns both host and port of the server. Are you going to change the behavior in this PR?
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.
No I'm not:
"address": "localhost:32929"
Is that ok?
Looks like I'm not fully understand new server object. I'll take a look again tomorrow and ask you if something is not clear. |
@garagatyi I've commited the fixes you have suggested:
|
@Override | ||
public String getInternalUrl() { | ||
return descriptor.getInternalUrl(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class still needs equals/hashcode/toString methods
verify(descriptor).getProperties(); | ||
verify(descriptor2).getInternalUrl(); | ||
} | ||
|
||
} |
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.
Please add trailing new line at the end of file
@@ -10,24 +10,8 @@ | |||
*******************************************************************************/ | |||
package org.eclipse.che.api.machine.server; | |||
|
|||
import org.eclipse.che.api.core.model.machine.MachineLimits; |
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.
Wildcard imports are forbidden in Che
@@ -24,14 +24,7 @@ | |||
import org.eclipse.che.api.core.rest.shared.dto.ServiceError; | |||
import org.eclipse.che.api.environment.server.MachineProcessManager; | |||
import org.eclipse.che.api.environment.server.MachineServiceLinksInjector; | |||
import org.eclipse.che.api.machine.server.model.impl.CommandImpl; |
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.
Please do not use wildcard imports
@@ -145,6 +145,7 @@ public MachineRuntimeInfoImpl getRuntime() { | |||
try { | |||
final ContainerInfo containerInfo = docker.inspectContainer(container); | |||
machineRuntime = new MachineRuntimeInfoImpl(dockerMachineFactory.createMetadata(containerInfo, | |||
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.
For me it looks like this argument is always null. Did I miss something?
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.
Feel free to add more details to your questions if that was not what you meant. I think you are wondering how Server.url
is ever set if this parameter is always null
. It should be set using property machine.docker.local_node_host.external
but it looks as it's always null.
Property machine.docker.local_node_host.external
is injected in LocalDockerModule
objects that are binded to DockerInstanceRuntimeInfo
in LocalDockerModule
.
Therefore method DockerInstance.getRuntime()
is not used by the API to get the machine runtime. That explains why Server.url
is correctly returned by the 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.
Let me explain how I understand what is happening with these changes. Please correct me if I'm mistaken.
DockerInstance always pass null as external host. DockerInstanceRuntimeInfo doesn't change that. LocalDockerInstanceRuntimeInfo uses assisted injection, so this null is passed here too.
So I don't see how another than null value can be accepted by DockerInstanceRuntimeInfo.
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.
As discussed on Slack I've cleaned-up LocalDockerInstanceRuntimeInfo
class and made it easier to read.
@@ -36,14 +42,15 @@ | |||
String getProtocol(); | |||
|
|||
/** | |||
* Path to access the server. | |||
* Url of the server, e.g. http://localhost:8080 |
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.
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, interesting
6dafbc5
to
a35ccae
Compare
import org.eclipse.che.api.machine.server.model.impl.MachineSourceImpl; | ||
import org.eclipse.che.api.machine.server.model.impl.ServerImpl; | ||
import org.eclipse.che.api.machine.server.model.impl.SnapshotImpl; | ||
import org.eclipse.che.api.machine.server.model.impl.*; |
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.
still need to remove wildcard import
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 I alrady fixed that: https://github.com/l0rd/che/blob/a35ccae37ab7fdecf958beb02acbf0e8177c8a3b/wsmaster/che-core-api-workspace/src/test/java/org/eclipse/che/api/workspace/server/WorkspaceServiceTest.java
You were probably looking at the outdated 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.
yep it was pending request (I forgot to validate it)
a35ccae
to
f6dfd7b
Compare
@@ -145,6 +145,7 @@ public MachineRuntimeInfoImpl getRuntime() { | |||
try { | |||
final ContainerInfo containerInfo = docker.inspectContainer(container); | |||
machineRuntime = new MachineRuntimeInfoImpl(dockerMachineFactory.createMetadata(containerInfo, | |||
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.
Let me explain how I understand what is happening with these changes. Please correct me if I'm mistaken.
DockerInstance always pass null as external host. DockerInstanceRuntimeInfo doesn't change that. LocalDockerInstanceRuntimeInfo uses assisted injection, so this null is passed here too.
So I don't see how another than null value can be accepted by DockerInstanceRuntimeInfo.
f6dfd7b
to
f549903
Compare
@musienko-maxim Please do a QA cycle for this PR |
ci-build |
Build success. https://ci.codenvycorp.com/job/che-pullrequests-build/452/ |
QA team has approved this PR. We will merge it when M3 is released |
f549903
to
9f1d920
Compare
This property allows communications beetween browser and containers that are on different networks (eg. Docker for Mac or NAT) Signed-off-by: Mario Loriedo <mloriedo@redhat.com>
9f1d920
to
c2ad879
Compare
This property allows communications beetween browser and containers that are on different networks (eg. Docker for Mac or NAT) Signed-off-by: Mario Loriedo <mloriedo@redhat.com>
What does this PR do?
Introduce a new property,
machine.docker.local_node_host.external
(along with the environment variableCHE_DOCKER_MACHINE_HOST_EXTERNAL
), that allow to configure the external URL browsers need to use to connect with containers that are not directly pingable. This happens for example with Docker for Mac.machine.docker.local_node_host.external=localhost
When this property is set the browser will use it to connect to the containers. Note that the wsmaster won't use that value to connect to the containers.
If this property is not set Che behaves as before.
This PR introduce a change to the API: Server class has a couple of new attributes:
internalUrl
andinternalAddress
. On the other there no particular change is needed client side and all clients will benefit of this change.This PR takes into account some feedbacks from PR #2004:
I will not close PR #2004. I want to continue the work to integrate Traefik in the che-launcher there. But traefik/traefik#444 should be fixed first.
What issues does this PR fix or reference?
#1644
Previous behavior
Running Che on Docker for Mac required some networking hacking
New behavior
Remove the need for the networking hack when running Che on Docker for Mac and make running Che as simple as
docker run -v /var/run/docker.sock:/var/run/docker.sock codenvy/che-launcher start
on all platforms.PR type
Minor change checklist