-
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
Restore support of single-port Che mode (on docker infra) #8471
Conversation
@@ -67,5 +70,11 @@ protected void configure() { | |||
bind( | |||
org.eclipse.che.workspace.infrastructure.docker.monit.DockerAbandonedResourcesCleaner | |||
.class); | |||
|
|||
if (Boolean.parseBoolean(System.getenv("CHE_SINGLE_PORT"))) { |
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 suggest not to use conditional binding. We are usually complaining such solutions. Instead of that you can use technique that was used in Che 5 https://github.com/eclipse/che/blob/5.22.x/dockerfiles/init/modules/che/templates/che.env.erb#L81
Map<String, String> containerLabels = new HashMap<>(); | ||
for (Map.Entry<String, ServerConfig> serverEntry : | ||
machineEntry.getValue().getServers().entrySet()) { | ||
final String serverName = serverEntry.getKey().replace('/', '-'); |
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 server name can contain other symbols that are not allowed in the DNS entry. Can you check whether such a use case breaks this code?
* @return wildcard domain | ||
*/ | ||
private String getWildcardNipDomain(String localAddress) { | ||
return String.format("%s.%s", getExternalIp(localAddress), "nip.io"); |
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.
Since nip.io is not always available it would be nice to allow to override this with another hostname, such as xip.io or user specific.
if (machineName != null) { | ||
joiner.add(machineName); | ||
} | ||
if (workspaceID != 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.
When any of arguments is null this method produces a hostname that differs from what is declared in the javadocs to this class. Are you sure that null arguments should be allowed?
public String build(String serverName, String machineName, String workspaceID) { | ||
StringJoiner joiner = new StringJoiner("."); | ||
if (serverName != null) { | ||
joiner.add("server-" + serverName.replace('/', '-')); |
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.
What if multiple dashes happen, is it valid host that works in single port case?
throws InfrastructureException { | ||
final String host = hostnameBuilder.build(serverName, machineName, identity.getWorkspaceId()); | ||
try { | ||
URI uri = UriBuilder.fromUri(url).host(host).build(); |
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 that in this case port is also rewritten, but this code changes a hostname only.
public String build(String serverName, String machineName, String workspaceID) { | ||
StringJoiner joiner = new StringJoiner("."); | ||
if (serverName != null) { | ||
joiner.add("server-" + serverName.replace('/', '-')); |
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.
Can you elaborate on why this prefix server-
is needed?
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 not necessary. Just to be more clear where the link points to.
@@ -255,6 +255,9 @@ che.infra.docker.bootstrapper.installer_timeout_sec=180 | |||
# Once servers for one installer available - checks stopped. | |||
che.infra.docker.bootstrapper.server_check_period_sec=3 | |||
|
|||
# URL rewriter. May be overriden in case of single-port mode e.t.c | |||
che.infra.docker.url_rewriter=default | |||
|
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.
Make sure you are able to configure it with CLI
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
@@ -379,3 +382,7 @@ che.infra.openshift.pvc.access_mode=ReadWriteOnce | |||
# then OpenShift infrastructure will reconfigure installer to use first available from this range | |||
che.infra.openshift.installer_server_min_port=10000 | |||
che.infra.openshift.installer_server_max_port=20000 | |||
|
|||
# Single port mode wildcard domain host & port. nip.io is used by default | |||
che.singleport.wildcard_domain.host=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.
Make sure you are able to configure it with CLI
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
@Nullable @Named("che.docker.ip.external") String externalIpOfContainers, | ||
@Nullable @Named("che.singleport.wildcard_domain.host") String wildcardHost, | ||
@Nullable @Named("che.singleport.wildcard_domain.port") String wildcardPort) { | ||
this.hostnameBuilder = |
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 it's not injected from 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.
To avoid one more conditional binding since this class is not used in normal mode.
dockerfiles/init/manifests/che.env
Outdated
@@ -245,6 +245,12 @@ | |||
# user configuration. | |||
CHE_SINGLE_PORT=false | |||
|
|||
# Wildcard DNS host and port for the single port mode. Default is nip.io | |||
#CHE.SINGLEPORT.WILDCARD__DOMAIN.HOST=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.
Replace dots with underscores
dockerfiles/init/manifests/che.env
Outdated
#CHE.SINGLEPORT.WILDCARD__DOMAIN.PORT=NULL | ||
|
||
# Url rewriter overrides default used in single port mode. | ||
#CHE.INFRA.DOCKER.URL_REWRITER=SINGLEPORT |
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 a note that this env var doesn't work when single port is enabled.
} | ||
|
||
@PostConstruct | ||
private void checkRewriterIsPresent() throws Exception { |
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.
Can we do that right in the constructor? Then we would need neither post construct method nor rewriterValue
.
internalEnv.getMachines().entrySet()) { | ||
final String machineName = machineEntry.getKey(); | ||
Map<String, String> containerLabels = new HashMap<>(); | ||
for (Map.Entry<String, ServerConfig> serverEntry : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need traefik rules for internal servers
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 check
final String port = serverEntry.getValue().getPort().split("/")[0]; | ||
|
||
containerLabels.put(format("traefik.%s.port", serviceName), port); | ||
containerLabels.put(format("traefik.%s.frontend.entryPoints", serviceName), "http"); |
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.
Since single port mode effectively supports only HTTP protocol it may be useful to specify this in che.env and docs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added note
* @return wildcard domain | ||
*/ | ||
private String getWildcardDomain(String localAddress) { | ||
return String.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.
Can we do this and getExternalIp
a one-time operation in the constructor in a singleton class?
} | ||
|
||
private String normalize(String input) { | ||
return pattern.matcher(input).replaceAll("-"); |
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 that with this logic it is possible that:
- hyphen become the first char
- hyphen become the last char
Those cases are forbidden in hostnames.
settingsProvisioners, | ||
projectsVolumeProvisioner, | ||
installerConfigProvisioner, | ||
labelsProvisioner, | ||
dockerApiEnvProvisioner, | ||
wsAgentServerConfigProvisioner, | ||
singlePortLabelsProvisioner, |
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 single port labels provisioning is not covered in this test.
if (serverName != null) { | ||
joiner.add(normalize(serverName)); | ||
} | ||
if (machineName != 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.
Can you describe in javadocs the case when some component is 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.
yes
*/ | ||
private final Pattern pattern = Pattern.compile("[^a-zA-Z0-9\\-]"); | ||
|
||
public SinglePortHostnameBuilder( |
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.
Can you cover this class with unit tests?
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
ci-build |
Build success. https://ci.codenvycorp.com/job/che-pullrequests-build/4439/ |
i just tried to run che6 in single port on docker, but it seems some changes to https://github.com/eclipse/che/blob/master/dockerfiles/cli/version/latest/images#L4 didn't make it into master, 6.1.0 or 6.2.0. (it is still traefik 1.3.0-rc3 instead of 1.5.0) |
why do you think so? |
@hkolvenbach what is the CHE version you are trying with? |
@skabashnyuk the dockerfiles for the @riuvshin we are currently using I was just mentioning the mismatching version number of |
@hkolvenbach |
thanks! |
What does this PR do?
Restores single-port execution mode using docker infra & Traefik as a proxy.
What issues does this PR fix or reference?
#7362
Release Notes
Restored support of single-port Che mode (on docker infra)
Docs PR
N/A