{"action":"created","comment":{"url":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/comments/33051989","id":33051989,"diff_hunk":"@@ -0,0 +1,153 @@\n+package com.nirima.jenkins.plugins.docker.launcher;\n+\n+import com.github.dockerjava.api.DockerClient;\n+import com.github.dockerjava.api.NotFoundException;\n+import com.github.dockerjava.api.command.CreateContainerCmd;\n+import com.github.dockerjava.api.command.ExecCreateCmdResponse;\n+import com.github.dockerjava.api.command.InspectContainerResponse;\n+import com.nirima.jenkins.plugins.docker.DockerComputer;\n+import com.nirima.jenkins.plugins.docker.DockerTemplate;\n+import com.nirima.jenkins.plugins.docker.DockerTemplateBase;\n+import hudson.model.Descriptor;\n+import hudson.model.TaskListener;\n+import hudson.slaves.ComputerLauncher;\n+import hudson.slaves.JNLPLauncher;\n+import hudson.slaves.SlaveComputer;\n+import jenkins.model.Jenkins;\n+import org.apache.commons.io.Charsets;\n+import org.apache.commons.io.IOUtils;\n+import org.kohsuke.accmod.Restricted;\n+import org.kohsuke.accmod.restrictions.NoExternalUse;\n+import org.kohsuke.stapler.DataBoundConstructor;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+import java.io.IOException;\n+import java.io.InputStream;\n+import java.io.PrintStream;\n+import java.util.Arrays;\n+\n+/**\n+ * JNLP launcher. Doesn't require open ports on docker host.\n+ *\n+ * Steps:\n+ * - runs container with nop command\n+ * - as launch action executes jnlp connection to master\n+ *\n+ * @author Kanstantsin Shautsou\n+ */\n+public class DockerComputerJNLPLauncher extends DockerComputerLauncher {\n+    private static final Logger LOGGER = LoggerFactory.getLogger(DockerComputerJNLPLauncher.class);\n+\n+    /**\n+     * Configured from UI\n+     */\n+    protected JNLPLauncher jnlpLauncher;\n+\n+    @DataBoundConstructor\n+    public DockerComputerJNLPLauncher(JNLPLauncher jnlpLauncher) {\n+        this.jnlpLauncher = jnlpLauncher;\n+    }\n+\n+    public JNLPLauncher getJnlpLauncher() {\n+        return jnlpLauncher;\n+    }\n+\n+    @Override\n+    public boolean isLaunchSupported() {\n+        return true;\n+    }\n+\n+    @Override\n+    public void launch(SlaveComputer computer, TaskListener listener) throws IOException, InterruptedException {\n+        final PrintStream logger = listener.getLogger();\n+        final DockerComputer dockerComputer = (DockerComputer) computer;\n+        final String containerId = dockerComputer.getContainerId();\n+        final String rootUrl = Jenkins.getInstance().getRootUrl();\n+        final DockerClient connect = dockerComputer.getCloud().connect();\n+\n+        // exec jnlp connection in running container\n+        // TODO implement PID 1 replacement\n+\n+        final InputStream resourceAsStream = DockerComputerJNLPLauncher.class.getResourceAsStream(\"init.sh\");\n+\n+        String cdCmd = \"cd /home/jenkins/\";\n+        String wgetSlaveCmd = \"wget \" + rootUrl + \"jnlpJars/slave.jar -O slave.jar\";\n+        String jnlpConnectCmd = \"java -jar slave.jar \"\n+                + \"-jnlpUrl \" + rootUrl + dockerComputer.getUrl() + \"slave-agent.jnlp \";\n+//                + \"-secret \" + dockerComputer.getJnlpMac();\n+\n+        String[] connectCmd = {\n+                \"bash\", \"-c\", cdCmd + \" && \" + wgetSlaveCmd + \" && \" + jnlpConnectCmd","path":"docker-plugin/src/main/java/com/nirima/jenkins/plugins/docker/launcher/DockerComputerJNLPLauncher.java","position":81,"original_position":81,"commit_id":"ddb3770d142f95c6d112e125d5ccd4ae00585e2c","original_commit_id":"ddb3770d142f95c6d112e125d5ccd4ae00585e2c","user":{"login":"steve-jansen","id":3165077,"avatar_url":"https://avatars.githubusercontent.com/u/3165077?v=3","gravatar_id":"","url":"https://api.github.com/users/steve-jansen","html_url":"https://github.com/steve-jansen","followers_url":"https://api.github.com/users/steve-jansen/followers","following_url":"https://api.github.com/users/steve-jansen/following{/other_user}","gists_url":"https://api.github.com/users/steve-jansen/gists{/gist_id}","starred_url":"https://api.github.com/users/steve-jansen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/steve-jansen/subscriptions","organizations_url":"https://api.github.com/users/steve-jansen/orgs","repos_url":"https://api.github.com/users/steve-jansen/repos","events_url":"https://api.github.com/users/steve-jansen/events{/privacy}","received_events_url":"https://api.github.com/users/steve-jansen/received_events","type":"User","site_admin":false},"body":"@KostyaSha my preference would be to declare an `ENTRYPOINT` in my dockerized slave and have the plugin send in the `-jnlpUrl` and `-secret` args.  This would let we do things like baking the slave.jar into my docker build if I want to.","created_at":"2015-06-23T15:11:58Z","updated_at":"2015-06-23T15:11:58Z","html_url":"https://github.com/jenkinsci/docker-plugin/pull/234#discussion_r33051989","pull_request_url":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/234","_links":{"self":{"href":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/comments/33051989"},"html":{"href":"https://github.com/jenkinsci/docker-plugin/pull/234#discussion_r33051989"},"pull_request":{"href":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/234"}}},"pull_request":{"url":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/234","id":36151618,"html_url":"https://github.com/jenkinsci/docker-plugin/pull/234","diff_url":"https://github.com/jenkinsci/docker-plugin/pull/234.diff","patch_url":"https://github.com/jenkinsci/docker-plugin/pull/234.patch","issue_url":"https://api.github.com/repos/jenkinsci/docker-plugin/issues/234","number":234,"state":"open","locked":false,"title":"WIP launchers","user":{"login":"KostyaSha","id":231611,"avatar_url":"https://avatars.githubusercontent.com/u/231611?v=3","gravatar_id":"","url":"https://api.github.com/users/KostyaSha","html_url":"https://github.com/KostyaSha","followers_url":"https://api.github.com/users/KostyaSha/followers","following_url":"https://api.github.com/users/KostyaSha/following{/other_user}","gists_url":"https://api.github.com/users/KostyaSha/gists{/gist_id}","starred_url":"https://api.github.com/users/KostyaSha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KostyaSha/subscriptions","organizations_url":"https://api.github.com/users/KostyaSha/orgs","repos_url":"https://api.github.com/users/KostyaSha/repos","events_url":"https://api.github.com/users/KostyaSha/events{/privacy}","received_events_url":"https://api.github.com/users/KostyaSha/received_events","type":"User","site_admin":false},"body":"Just to start some discussion. And exclude potential conflicts. \r\nI'm working on adding other ways on connecting slave to master. JNLP is one of ideas and should allow connecting slaves back through firewalls while only connection to docker API will be required. Other variants of launching maybe experimented then. (For local connection like @jglick suggested it even can  be possible to do connection through plain stdin/stdout without ssh/security overhead).\r\nAlso with this changes slave/template configuration becomes close to default dumbslaves, that are user-friendly.\r\n\r\nSo current plan:\r\n- unbundle existed launcher to separate class. Sshconnector is very useful because it doesn't have Host address like sshlauncher. \r\n- move DockerTemplateBase related methods, fields, help files to DockerTemplateBase. Corresponding config.jelly should help cleanup-ing and keeping code up-to-date in right place.\r\n- unhardcode 22 port for DockerSSH ComputerLauncher\r\n- DockerComputerLauncher become a marker class and it's implementations should handle host names and docker related part during connection/launching\r\n- After this changes DockerTemplate can be simplified and contain in itself DockerTemplateBase without extending classes. For UI this will be simply `<f.property>`\r\n- Add data migration and tests for it\r\n\r\n@magnayn will you have any objections for this work? \r\n\r\n/cc @thomassuckow\r\n\r\nCurrent code is WIP and you can skip hard commenting.\r\nPS for container create/start i found inconsistency in docker-java and docker docs, so this will be clean-uped later.\n\n<!-- Reviewable:start -->\n[<img src=\"https://reviewable.io/review_button.png\" height=40 alt=\"Review on Reviewable\"/>](https://reviewable.io/reviews/jenkinsci/docker-plugin/234)\n<!-- Reviewable:end -->\n","created_at":"2015-05-25T17:54:30Z","updated_at":"2015-06-23T15:11:58Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c0b9893ebd78bbbd517b47657fcc06c771816f10","assignee":{"login":"KostyaSha","id":231611,"avatar_url":"https://avatars.githubusercontent.com/u/231611?v=3","gravatar_id":"","url":"https://api.github.com/users/KostyaSha","html_url":"https://github.com/KostyaSha","followers_url":"https://api.github.com/users/KostyaSha/followers","following_url":"https://api.github.com/users/KostyaSha/following{/other_user}","gists_url":"https://api.github.com/users/KostyaSha/gists{/gist_id}","starred_url":"https://api.github.com/users/KostyaSha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KostyaSha/subscriptions","organizations_url":"https://api.github.com/users/KostyaSha/orgs","repos_url":"https://api.github.com/users/KostyaSha/repos","events_url":"https://api.github.com/users/KostyaSha/events{/privacy}","received_events_url":"https://api.github.com/users/KostyaSha/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/234/commits","review_comments_url":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/234/comments","review_comment_url":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/comments{/number}","comments_url":"https://api.github.com/repos/jenkinsci/docker-plugin/issues/234/comments","statuses_url":"https://api.github.com/repos/jenkinsci/docker-plugin/statuses/ddb3770d142f95c6d112e125d5ccd4ae00585e2c","head":{"label":"KostyaSha:connectionStrategy","ref":"connectionStrategy","sha":"ddb3770d142f95c6d112e125d5ccd4ae00585e2c","user":{"login":"KostyaSha","id":231611,"avatar_url":"https://avatars.githubusercontent.com/u/231611?v=3","gravatar_id":"","url":"https://api.github.com/users/KostyaSha","html_url":"https://github.com/KostyaSha","followers_url":"https://api.github.com/users/KostyaSha/followers","following_url":"https://api.github.com/users/KostyaSha/following{/other_user}","gists_url":"https://api.github.com/users/KostyaSha/gists{/gist_id}","starred_url":"https://api.github.com/users/KostyaSha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KostyaSha/subscriptions","organizations_url":"https://api.github.com/users/KostyaSha/orgs","repos_url":"https://api.github.com/users/KostyaSha/repos","events_url":"https://api.github.com/users/KostyaSha/events{/privacy}","received_events_url":"https://api.github.com/users/KostyaSha/received_events","type":"User","site_admin":false},"repo":{"id":29350108,"name":"docker-plugin","full_name":"KostyaSha/docker-plugin","owner":{"login":"KostyaSha","id":231611,"avatar_url":"https://avatars.githubusercontent.com/u/231611?v=3","gravatar_id":"","url":"https://api.github.com/users/KostyaSha","html_url":"https://github.com/KostyaSha","followers_url":"https://api.github.com/users/KostyaSha/followers","following_url":"https://api.github.com/users/KostyaSha/following{/other_user}","gists_url":"https://api.github.com/users/KostyaSha/gists{/gist_id}","starred_url":"https://api.github.com/users/KostyaSha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KostyaSha/subscriptions","organizations_url":"https://api.github.com/users/KostyaSha/orgs","repos_url":"https://api.github.com/users/KostyaSha/repos","events_url":"https://api.github.com/users/KostyaSha/events{/privacy}","received_events_url":"https://api.github.com/users/KostyaSha/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/KostyaSha/docker-plugin","description":"Jenkins Cloud Plugin for Docker","fork":true,"url":"https://api.github.com/repos/KostyaSha/docker-plugin","forks_url":"https://api.github.com/repos/KostyaSha/docker-plugin/forks","keys_url":"https://api.github.com/repos/KostyaSha/docker-plugin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/KostyaSha/docker-plugin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/KostyaSha/docker-plugin/teams","hooks_url":"https://api.github.com/repos/KostyaSha/docker-plugin/hooks","issue_events_url":"https://api.github.com/repos/KostyaSha/docker-plugin/issues/events{/number}","events_url":"https://api.github.com/repos/KostyaSha/docker-plugin/events","assignees_url":"https://api.github.com/repos/KostyaSha/docker-plugin/assignees{/user}","branches_url":"https://api.github.com/repos/KostyaSha/docker-plugin/branches{/branch}","tags_url":"https://api.github.com/repos/KostyaSha/docker-plugin/tags","blobs_url":"https://api.github.com/repos/KostyaSha/docker-plugin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/KostyaSha/docker-plugin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/KostyaSha/docker-plugin/git/refs{/sha}","trees_url":"https://api.github.com/repos/KostyaSha/docker-plugin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/KostyaSha/docker-plugin/statuses/{sha}","languages_url":"https://api.github.com/repos/KostyaSha/docker-plugin/languages","stargazers_url":"https://api.github.com/repos/KostyaSha/docker-plugin/stargazers","contributors_url":"https://api.github.com/repos/KostyaSha/docker-plugin/contributors","subscribers_url":"https://api.github.com/repos/KostyaSha/docker-plugin/subscribers","subscription_url":"https://api.github.com/repos/KostyaSha/docker-plugin/subscription","commits_url":"https://api.github.com/repos/KostyaSha/docker-plugin/commits{/sha}","git_commits_url":"https://api.github.com/repos/KostyaSha/docker-plugin/git/commits{/sha}","comments_url":"https://api.github.com/repos/KostyaSha/docker-plugin/comments{/number}","issue_comment_url":"https://api.github.com/repos/KostyaSha/docker-plugin/issues/comments{/number}","contents_url":"https://api.github.com/repos/KostyaSha/docker-plugin/contents/{+path}","compare_url":"https://api.github.com/repos/KostyaSha/docker-plugin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/KostyaSha/docker-plugin/merges","archive_url":"https://api.github.com/repos/KostyaSha/docker-plugin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/KostyaSha/docker-plugin/downloads","issues_url":"https://api.github.com/repos/KostyaSha/docker-plugin/issues{/number}","pulls_url":"https://api.github.com/repos/KostyaSha/docker-plugin/pulls{/number}","milestones_url":"https://api.github.com/repos/KostyaSha/docker-plugin/milestones{/number}","notifications_url":"https://api.github.com/repos/KostyaSha/docker-plugin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/KostyaSha/docker-plugin/labels{/name}","releases_url":"https://api.github.com/repos/KostyaSha/docker-plugin/releases{/id}","created_at":"2015-01-16T13:45:06Z","updated_at":"2015-01-16T14:11:07Z","pushed_at":"2015-06-17T12:36:17Z","git_url":"git://github.com/KostyaSha/docker-plugin.git","ssh_url":"git@github.com:KostyaSha/docker-plugin.git","clone_url":"https://github.com/KostyaSha/docker-plugin.git","svn_url":"https://github.com/KostyaSha/docker-plugin","homepage":"https://wiki.jenkins-ci.org/display/JENKINS/Docker+Plugin","size":1014,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"jenkinsci:master","ref":"master","sha":"41f052b4738ef0b31d6cc0d1381e268fa6a2c104","user":{"login":"jenkinsci","id":107424,"avatar_url":"https://avatars.githubusercontent.com/u/107424?v=3","gravatar_id":"","url":"https://api.github.com/users/jenkinsci","html_url":"https://github.com/jenkinsci","followers_url":"https://api.github.com/users/jenkinsci/followers","following_url":"https://api.github.com/users/jenkinsci/following{/other_user}","gists_url":"https://api.github.com/users/jenkinsci/gists{/gist_id}","starred_url":"https://api.github.com/users/jenkinsci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jenkinsci/subscriptions","organizations_url":"https://api.github.com/users/jenkinsci/orgs","repos_url":"https://api.github.com/users/jenkinsci/repos","events_url":"https://api.github.com/users/jenkinsci/events{/privacy}","received_events_url":"https://api.github.com/users/jenkinsci/received_events","type":"Organization","site_admin":false},"repo":{"id":15799524,"name":"docker-plugin","full_name":"jenkinsci/docker-plugin","owner":{"login":"jenkinsci","id":107424,"avatar_url":"https://avatars.githubusercontent.com/u/107424?v=3","gravatar_id":"","url":"https://api.github.com/users/jenkinsci","html_url":"https://github.com/jenkinsci","followers_url":"https://api.github.com/users/jenkinsci/followers","following_url":"https://api.github.com/users/jenkinsci/following{/other_user}","gists_url":"https://api.github.com/users/jenkinsci/gists{/gist_id}","starred_url":"https://api.github.com/users/jenkinsci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jenkinsci/subscriptions","organizations_url":"https://api.github.com/users/jenkinsci/orgs","repos_url":"https://api.github.com/users/jenkinsci/repos","events_url":"https://api.github.com/users/jenkinsci/events{/privacy}","received_events_url":"https://api.github.com/users/jenkinsci/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/jenkinsci/docker-plugin","description":"Jenkins Cloud Plugin for Docker","fork":false,"url":"https://api.github.com/repos/jenkinsci/docker-plugin","forks_url":"https://api.github.com/repos/jenkinsci/docker-plugin/forks","keys_url":"https://api.github.com/repos/jenkinsci/docker-plugin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jenkinsci/docker-plugin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jenkinsci/docker-plugin/teams","hooks_url":"https://api.github.com/repos/jenkinsci/docker-plugin/hooks","issue_events_url":"https://api.github.com/repos/jenkinsci/docker-plugin/issues/events{/number}","events_url":"https://api.github.com/repos/jenkinsci/docker-plugin/events","assignees_url":"https://api.github.com/repos/jenkinsci/docker-plugin/assignees{/user}","branches_url":"https://api.github.com/repos/jenkinsci/docker-plugin/branches{/branch}","tags_url":"https://api.github.com/repos/jenkinsci/docker-plugin/tags","blobs_url":"https://api.github.com/repos/jenkinsci/docker-plugin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jenkinsci/docker-plugin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jenkinsci/docker-plugin/git/refs{/sha}","trees_url":"https://api.github.com/repos/jenkinsci/docker-plugin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jenkinsci/docker-plugin/statuses/{sha}","languages_url":"https://api.github.com/repos/jenkinsci/docker-plugin/languages","stargazers_url":"https://api.github.com/repos/jenkinsci/docker-plugin/stargazers","contributors_url":"https://api.github.com/repos/jenkinsci/docker-plugin/contributors","subscribers_url":"https://api.github.com/repos/jenkinsci/docker-plugin/subscribers","subscription_url":"https://api.github.com/repos/jenkinsci/docker-plugin/subscription","commits_url":"https://api.github.com/repos/jenkinsci/docker-plugin/commits{/sha}","git_commits_url":"https://api.github.com/repos/jenkinsci/docker-plugin/git/commits{/sha}","comments_url":"https://api.github.com/repos/jenkinsci/docker-plugin/comments{/number}","issue_comment_url":"https://api.github.com/repos/jenkinsci/docker-plugin/issues/comments{/number}","contents_url":"https://api.github.com/repos/jenkinsci/docker-plugin/contents/{+path}","compare_url":"https://api.github.com/repos/jenkinsci/docker-plugin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jenkinsci/docker-plugin/merges","archive_url":"https://api.github.com/repos/jenkinsci/docker-plugin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jenkinsci/docker-plugin/downloads","issues_url":"https://api.github.com/repos/jenkinsci/docker-plugin/issues{/number}","pulls_url":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls{/number}","milestones_url":"https://api.github.com/repos/jenkinsci/docker-plugin/milestones{/number}","notifications_url":"https://api.github.com/repos/jenkinsci/docker-plugin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jenkinsci/docker-plugin/labels{/name}","releases_url":"https://api.github.com/repos/jenkinsci/docker-plugin/releases{/id}","created_at":"2014-01-10T14:05:42Z","updated_at":"2015-06-20T05:36:21Z","pushed_at":"2015-06-20T19:33:30Z","git_url":"git://github.com/jenkinsci/docker-plugin.git","ssh_url":"git@github.com:jenkinsci/docker-plugin.git","clone_url":"https://github.com/jenkinsci/docker-plugin.git","svn_url":"https://github.com/jenkinsci/docker-plugin","homepage":"https://wiki.jenkins-ci.org/display/JENKINS/Docker+Plugin","size":2209,"stargazers_count":160,"watchers_count":160,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":106,"mirror_url":null,"open_issues_count":48,"forks":106,"open_issues":48,"watchers":160,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/234"},"html":{"href":"https://github.com/jenkinsci/docker-plugin/pull/234"},"issue":{"href":"https://api.github.com/repos/jenkinsci/docker-plugin/issues/234"},"comments":{"href":"https://api.github.com/repos/jenkinsci/docker-plugin/issues/234/comments"},"review_comments":{"href":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/234/comments"},"review_comment":{"href":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/jenkinsci/docker-plugin/pulls/234/commits"},"statuses":{"href":"https://api.github.com/repos/jenkinsci/docker-plugin/statuses/ddb3770d142f95c6d112e125d5ccd4ae00585e2c"}}}}