Uploaded image for project: 'jclouds'
  1. jclouds
  2. JCLOUDS-1014

Docker: Add possibility to change loginPort



    • Improvement
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 1.9.1
    • 1.9.2, 2.0.0
    • jclouds-labs


      The SSH server in Docker container can run on different port than is the default one (22). There should be a possibility for users to provide their own implementation of the ContainerToNodeMetadata.getLoginPort() method.

      From IRC discussion
      <jcacek> nacx, Hi, could you please give an advice how to change port on which SSH in a Node is running. I don't see such an option in the TemplateOptions.
      <nacx> hi jcacek let me check
      <nacx> jcacek, the login port is given by the NodeMetadata: https://github.com/jclouds/jclouds/blob/master/compute/src/main/java/org/jclouds/compute/domain/NodeMetadata.java#L99-L102
      <nacx> when the compute service creates a node, it should populate the right login port when returning it
      <nacx> translating this to Docker, right now always port 22 is returned
      <nacx> this method should be changed: https://github.com/jclouds/jclouds-labs/blob/master/docker/src/main/java/org/jclouds/docker/compute/functions/ContainerToNodeMetadata.java#L77-L104
      <nacx> in order to properly populate the login port given a Container
      <nacx> in fact, I see it is already populated: https://github.com/jclouds/jclouds-labs/blob/master/docker/src/main/java/org/jclouds/docker/compute/functions/ContainerToNodeMetadata.java#L93
      <nacx> I assume this is the piece of code that is causing trouble to you: https://github.com/jclouds/jclouds-labs/blob/master/docker/src/main/java/org/jclouds/docker/compute/functions/ContainerToNodeMetadata.java#L120-L135
      <nacx> it just looks for a port 22 in the container to get the port in the host
      <jcacek> nacx, thanks for the details. Yes, it seems as a correct place. I need to have the port configurable.
      <nacx> perhaps that "port 22 lookup" should be based on the image, or something like that
      <nacx> which is your use case?
      <jcacek> I'm running containers with networkMode=host (i.e. sharing network stack with the docker host). So I have to use another SSH port in container (e.g. 8822). And then I have to configure it in JClouds :)
      <jcacek> nacx - https://github.com/kwart/dockerfiles/tree/master/alpine-ext#32-ssh
      <jcacek> nacx, docker run -it -e ROOT_PASSWORD=alpine -e SSH_PORT=8822 --net=host -it kwart/alpine-ext:3.2-ssh
      <nacx> show does a docker inspect look like for such a container?, is there any network config?
      <nacx> s/show/how/
      <jcacek> There is no info about the open ports - there's only "NetworkMode": "host" attribute in the HostConfig
      <jcacek> nacx, So I prefer configuration option in jclouds Docker provider to override SSH port for a node.
      <jcacek> nacx, it's also necessary in standard bridged network mode. Nobody forces the image creators to start SSH on port 22.
      <nacx> that's tricky
      <nacx> agree
      <nacx> the tricky part is that the loginPort mechanism should also work
      <nacx> for nodes that haven't been created by the jclouds compute service
      <nacx> that's why the contract in jclouds is that the compute service should be able to just "list the nodes" and provide the login port for each
      <nacx> having a first thought, it could make sense to have pluggable "port lookup strategies", using the current method as the default one
      <nacx> and allow to define "per-image" strategies
      <nacx> if users are using images with particular ssh configuration, we could allow them to provide their custom port lookup funcion
      <nacx> (for example that looks t the container's env vars)
      <nacx> we can extract this method: https://github.com/jclouds/jclouds-labs/blob/master/docker/src/main/java/org/jclouds/docker/compute/functions/ContainerToNodeMetadata.java#L120-L135
      <jcacek> nacx, Yep, nice idea, it should work then.
      <nacx> into its own injectable function (Function<Container, Integer>)
      <nacx> so users can propvide a custom guice module
      <nacx> that binds that to a custom function
      <nacx> in case someone needs specific port discovery
      <nacx> that custom function could have specific lookup for the known images and default to the current one, etc
      <nacx> but the idea would be to make that port lookup function injectable
      <nacx> the TemplateOptions is not an option here, as this must work even if the user only does a listContainers to then ssh into one of them 8even if not deployed with jclouds)
      <jcacek> nacx Yes, i see it now.
      <jcacek> nacx, I'll file a new Feature Request JIRA and paste also this discussion into it. OK?
      <nacx> ok
      <nacx> I'm thinking that perhaps using Guice multibindings
      <nacx> there is a clean way to do that
      <nacx> so, we could have that default impl
      <nacx> and if it does not find a port
      <nacx> delegate to a per-image function
      <nacx> we can introduce that Map<image id, Function<container, port>
      <nacx> in jclouds
      <nacx> and let users easily provide their own custom function for each image
      <jcacek> nacx, I've never worked with Guice before, so I'm not able to comment the options now. But I'll try to dive into it.
      <nacx> the idea with my multibinding comments
      <nacx> is that we could have in jclouds the current function
      <nacx> and then a map of images names -> function (which would be empty)
      <nacx> guice multibindings allow to add bindings to existing collections
      <nacx> users could create the context providing a custom guice module (in the modules list)
      <nacx> a simple module with a single method such as:
      <nacx> public void configure() {
      <nacx>    MapBinder<String, Function> imagefunctions = MapBinder.newMapBinder(binder(), String.class, Function.class)
      <nacx>    imagefunctions.addBinding("redis, myRedisLookupFunction);
      <nacx>    imagefunctions.addBinding("kwart/alpine-ext", myAlpineLookupFunction);
      <nacx> }
      <nacx> that would add the custom functions for those images to the jclouds image-to-function map
      <nacx> so users have a relatively clean and easy way to provide their custom lookup functions for each docker image
      <nacx> they want to customizer
      <nacx> then, any class in jclouds can have injected a: Map<String, Function>
      <nacx> and that map will be populated with any key/value configured by the users using the mapbinder
      <nacx> perhaps this is too guice specific, but I think it could be a clean way to address this issue
      <jcacek> nacx, OK, thanks for explaining it. 
      <nacx> this is pretty straightforward to implement, so if you open a jira issue I can take it and do it, providing the alpine example
      <nacx> or feel free to go for the PR yourself :) I'll be happy to help




            nacx Ignasi Barrera
            kwart Josef Cacek
            0 Vote for this issue
            3 Start watching this issue