Jenkinsの自動インストールをプロキシ対応するヘッポコパッチを作った

JenkinsにはJDKやAntをインターネットからダウンロードしてきて自動でインストールする便利な機能があるんだけれどもファイアウォール内でうまく動いた試しがなかったのだよ(当然,Jenkinsにプロキシの設定はしてる。


あんまり気にもせず「こんなもんかぁ」と思ってたら,川口さんから「それはバグ」と指摘をうける。



JenkinsのBTS調べてみたら,ちゃんとチケットもあがってた。
[JENKINS-10634] Proxy settings arent used by JDK-downloader - Jenkins JIRA


うむ,みんなこの機能使ってないのかねぇ。とは言え,バグだって言うし,見つけちゃったし,で仕方ないから直してみることにしたよ。


Jenkinsの開発環境を構築するのに挫折したのでパッチだけ。今日,githubからソースコードをダウンロードしてきたので,Jenkinsのバージョンは v1.430近辺かと。
#誰か代わりにgithubにプルリクエスト送って欲しい(って2人くらいしか心当たり居ないけど。

Index: core/src/main/java/hudson/tools/JDKInstaller.java
===================================================================
--- core/src/main/java/hudson/tools/JDKInstaller.java	(date 1316141278000)
+++ core/src/main/java/hudson/tools/JDKInstaller.java	(revision )
@@ -23,6 +23,7 @@
  */
 package hudson.tools;
 
+import com.gargoylesoftware.htmlunit.BrowserVersion;
 import com.gargoylesoftware.htmlunit.ElementNotFoundException;
 import com.gargoylesoftware.htmlunit.Page;
 import com.gargoylesoftware.htmlunit.WebClient;
@@ -33,6 +34,7 @@
 import hudson.FilePath;
 import hudson.Launcher;
 import hudson.Launcher.ProcStarter;
+import hudson.ProxyConfiguration;
 import hudson.Util;
 import hudson.model.DownloadService.Downloadable;
 import hudson.model.JDK;
@@ -343,7 +345,11 @@
         log.getLogger().println("Downloading JDK from "+primary.filepath);
         URL src = new URL(primary.filepath);
 
-        WebClient wc = new WebClient();
+        Jenkins j = Jenkins.getInstance();
+        ProxyConfiguration pc = j != null ? j.proxy : null;
+        WebClient wc = pc == null ? new WebClient()
+                                  : new WebClient(BrowserVersion.getDefault(), pc.name, pc.port);
+
         wc.setJavaScriptEnabled(false);
         wc.setCssEnabled(false);
         Page page = wc.getPage(src);
Index: core/src/main/java/hudson/FilePath.java
===================================================================
--- core/src/main/java/hudson/FilePath.java	(date 1316141278000)
+++ core/src/main/java/hudson/FilePath.java	(revision )
@@ -655,7 +655,17 @@
                 listener.getLogger().println(message);
 
             // for HTTP downloads, enable automatic retry for added resilience
-            InputStream in = archive.getProtocol().equals("http") ? new RetryableHttpStream(archive) : con.getInputStream();
+            InputStream in;
+            if (archive.getProtocol().equals("http")) {
+                Jenkins j = Jenkins.getInstance();
+                ProxyConfiguration p = j != null ? j.proxy : null;
+                in = p == null ? new RetryableHttpStream(archive)
+                               : new RetryableHttpStream(archive, p.createProxy());
+            }
+            else {
+                in = con.getInputStream();
+            }
+
             CountingInputStream cis = new CountingInputStream(in);
             try {
                 if(archive.toExternalForm().endsWith(".zip"))
@@ -1540,7 +1550,7 @@
                             private int copySize;
 
                             public CopyImpl() {
-                                setProject(new org.apache.tools.ant.Project());
+                                setProject(new Project());
                             }
 
                             @Override


JDKの自動インストールって初めてやってみたんだけど,Jenkinsさんに多めにヒープ割り当てとかないとコケるね。いくつが最低サイズかわかんないけど,512M割り当てたら動いた。

  > java -Xmx512m -jar jenkins.war


それと,Java7のインストーラはJava6と振る舞いが違うのか,ダウンロード後のインストール処理が失敗してましたよ。その件には熱心じゃないんで,このパッチでも対応してないけど。:-P
長いけどJava7の自動インストールに失敗したときに残ってた jdk.exe.install.log を載せておきます。ちなみに,OSはWindowsXP SP3ね。

=== ログ開始: 2011/09/16  16:49:56 ===
アクション開始 16:49:56: INSTALL。
アクション開始 16:49:56: AppSearch。
アクション終了 16:49:56: AppSearch。 戻り値 1。
アクション開始 16:49:56: LaunchConditions。
アクション終了 16:49:56: LaunchConditions。 戻り値 1。
アクション開始 16:49:56: FindRelatedProducts。
アクション終了 16:49:56: FindRelatedProducts。 戻り値 0。
アクション開始 16:49:56: ValidateProductID。
アクション終了 16:49:56: ValidateProductID。 戻り値 1。
アクション開始 16:49:56: setUserProfileNT。
アクション終了 16:49:56: setUserProfileNT。 戻り値 1。
アクション開始 16:49:56: setAllUsersProfile2K。
アクション終了 16:49:56: setAllUsersProfile2K。 戻り値 1。
アクション開始 16:49:57: CostInitialize。
アクション終了 16:49:57: CostInitialize。 戻り値 1。
アクション開始 16:49:57: FileCost。
アクション終了 16:49:57: FileCost。 戻り値 1。
アクション開始 16:49:57: IsolateComponents。
アクション終了 16:49:57: IsolateComponents。 戻り値 1。
アクション開始 16:49:57: CostFinalize。
アクション終了 16:49:57: CostFinalize。 戻り値 1。
アクション開始 16:49:57: SetARPReadme。
アクション終了 16:49:57: SetARPReadme。 戻り値 1。
アクション開始 16:49:57: SetODBCFolders。
アクション終了 16:49:57: SetODBCFolders。 戻り値 1。
アクション開始 16:49:57: MigrateFeatureStates。
アクション終了 16:49:57: MigrateFeatureStates。 戻り値 0。
アクション開始 16:49:57: InstallValidate。
アクション終了 16:49:57: InstallValidate。 戻り値 1。
アクション開始 16:49:57: RemoveExistingProducts。
アクション終了 16:49:57: RemoveExistingProducts。 戻り値 0。
アクション開始 16:49:57: InstallInitialize。
アクション終了 16:49:59: InstallInitialize。 戻り値 1。
アクション開始 16:49:59: ProcessComponents。
アクション終了 16:49:59: ProcessComponents。 戻り値 1。
アクション開始 16:49:59: UnpublishComponents。
アクション終了 16:49:59: UnpublishComponents。 戻り値 1。
アクション開始 16:49:59: MsiUnpublishAssemblies。
アクション終了 16:49:59: MsiUnpublishAssemblies。 戻り値 1。
アクション開始 16:49:59: UnpublishFeatures。
アクション終了 16:49:59: UnpublishFeatures。 戻り値 1。
アクション開始 16:49:59: StopServices。
アクション終了 16:49:59: StopServices。 戻り値 1。
アクション開始 16:49:59: DeleteServices。
アクション終了 16:49:59: DeleteServices。 戻り値 1。
アクション開始 16:49:59: UnregisterComPlus。
アクション終了 16:49:59: UnregisterComPlus。 戻り値 1。
アクション開始 16:49:59: SelfUnregModules。
アクション終了 16:49:59: SelfUnregModules。 戻り値 1。
アクション開始 16:49:59: UnregisterTypeLibraries。
アクション終了 16:49:59: UnregisterTypeLibraries。 戻り値 1。
アクション開始 16:49:59: RemoveODBC。
アクション終了 16:49:59: RemoveODBC。 戻り値 1。
アクション開始 16:49:59: RemoveRegistryValues。
アクション終了 16:49:59: RemoveRegistryValues。 戻り値 1。
アクション開始 16:49:59: UnregisterClassInfo。
アクション終了 16:49:59: UnregisterClassInfo。 戻り値 1。
アクション開始 16:49:59: UnregisterExtensionInfo。
アクション終了 16:49:59: UnregisterExtensionInfo。 戻り値 1。
アクション開始 16:49:59: UnregisterProgIdInfo。
アクション終了 16:49:59: UnregisterProgIdInfo。 戻り値 1。
アクション開始 16:49:59: UnregisterMIMEInfo。
アクション終了 16:49:59: UnregisterMIMEInfo。 戻り値 1。
アクション開始 16:49:59: RemoveIniValues。
アクション終了 16:49:59: RemoveIniValues。 戻り値 1。
アクション開始 16:49:59: RemoveShortcuts。
アクション終了 16:49:59: RemoveShortcuts。 戻り値 1。
アクション開始 16:49:59: RemoveEnvironmentStrings。
アクション終了 16:49:59: RemoveEnvironmentStrings。 戻り値 1。
アクション開始 16:49:59: RemoveDuplicateFiles。
アクション終了 16:49:59: RemoveDuplicateFiles。 戻り値 1。
アクション開始 16:49:59: RemoveFiles。
アクション終了 16:49:59: RemoveFiles。 戻り値 1。
アクション開始 16:49:59: RemoveFolders。
アクション終了 16:49:59: RemoveFolders。 戻り値 1。
アクション開始 16:49:59: CreateFolders。
アクション終了 16:49:59: CreateFolders。 戻り値 1。
アクション開始 16:49:59: MoveFiles。
アクション終了 16:49:59: MoveFiles。 戻り値 1。
アクション開始 16:49:59: InstallFiles。
アクション終了 16:49:59: InstallFiles。 戻り値 1。
アクション開始 16:49:59: PatchFiles。
アクション終了 16:49:59: PatchFiles。 戻り値 1。
アクション開始 16:49:59: DuplicateFiles。
アクション終了 16:49:59: DuplicateFiles。 戻り値 1。
アクション開始 16:49:59: BindImage。
アクション終了 16:49:59: BindImage。 戻り値 1。
アクション開始 16:49:59: CreateShortcuts。
アクション終了 16:49:59: CreateShortcuts。 戻り値 1。
アクション開始 16:49:59: RegisterClassInfo。
アクション終了 16:49:59: RegisterClassInfo。 戻り値 1。
アクション開始 16:49:59: RegisterExtensionInfo。
アクション終了 16:49:59: RegisterExtensionInfo。 戻り値 1。
アクション開始 16:49:59: RegisterProgIdInfo。
アクション終了 16:49:59: RegisterProgIdInfo。 戻り値 1。
アクション開始 16:49:59: RegisterMIMEInfo。
アクション終了 16:49:59: RegisterMIMEInfo。 戻り値 1。
アクション開始 16:49:59: WriteRegistryValues。
アクション終了 16:49:59: WriteRegistryValues。 戻り値 1。
アクション開始 16:49:59: WriteIniValues。
アクション終了 16:49:59: WriteIniValues。 戻り値 1。
アクション開始 16:49:59: WriteEnvironmentStrings。
アクション終了 16:49:59: WriteEnvironmentStrings。 戻り値 1。
アクション開始 16:49:59: InstallODBC。
アクション終了 16:49:59: InstallODBC。 戻り値 0。
アクション開始 16:49:59: RegisterTypeLibraries。
アクション終了 16:49:59: RegisterTypeLibraries。 戻り値 1。
アクション開始 16:49:59: RegisterComPlus。
アクション終了 16:49:59: RegisterComPlus。 戻り値 1。
アクション開始 16:49:59: InstallServices。
アクション終了 16:49:59: InstallServices。 戻り値 1。
アクション開始 16:49:59: StartServices。
アクション終了 16:49:59: StartServices。 戻り値 1。
アクション開始 16:49:59: SelfRegModules。
アクション終了 16:49:59: SelfRegModules。 戻り値 1。
アクション開始 16:49:59: RegisterUser。
アクション終了 16:49:59: RegisterUser。 戻り値 0。
アクション開始 16:49:59: RegisterProduct。
アクション終了 16:49:59: RegisterProduct。 戻り値 1。
アクション開始 16:49:59: PublishComponents。
アクション終了 16:49:59: PublishComponents。 戻り値 1。
アクション開始 16:49:59: MsiPublishAssemblies。
アクション終了 16:49:59: MsiPublishAssemblies。 戻り値 1。
アクション開始 16:49:59: PublishFeatures。
アクション終了 16:49:59: PublishFeatures。 戻り値 1。
アクション開始 16:49:59: PublishProduct。
アクション終了 16:49:59: PublishProduct。 戻り値 1。
アクション開始 16:49:59: unziptools。
アクション終了 16:49:59: unziptools。 戻り値 1。
アクション開始 16:49:59: preprogress1。
アクション終了 16:50:00: preprogress1。 戻り値 1。
アクション開始 16:50:00: postprogress1。
アクション終了 16:50:00: postprogress1。 戻り値 1。
アクション開始 16:50:00: charsets。
アクション終了 16:50:00: charsets。 戻り値 1。
アクション開始 16:50:00: preprogress2。
アクション終了 16:50:00: preprogress2。 戻り値 1。
アクション開始 16:50:00: postprogress2。
アクション終了 16:50:00: postprogress2。 戻り値 1。
アクション開始 16:50:00: javaws。
アクション終了 16:50:00: javaws。 戻り値 1。
アクション開始 16:50:00: deploy。
アクション終了 16:50:00: deploy。 戻り値 1。
アクション開始 16:50:00: preprogress3。
アクション終了 16:50:00: preprogress3。 戻り値 1。
アクション開始 16:50:01: postprogress3。
アクション終了 16:50:01: postprogress3。 戻り値 1。
アクション開始 16:50:01: jaws。
アクション終了 16:50:01: jaws。 戻り値 1。
アクション開始 16:50:01: preprogress4。
アクション終了 16:50:01: preprogress4。 戻り値 1。
アクション開始 16:50:01: postprogress4。
アクション終了 16:50:01: postprogress4。 戻り値 1。
アクション開始 16:50:01: jsse。
アクション終了 16:50:01: jsse。 戻り値 1。
アクション開始 16:50:01: preprogress5。
アクション終了 16:50:01: preprogress5。 戻り値 1。
アクション開始 16:50:01: postprogress5。
アクション終了 16:50:01: postprogress5。 戻り値 1。
アクション開始 16:50:01: tools。
アクション終了 16:50:01: tools。 戻り値 1。
アクション開始 16:50:01: preprogress6。
アクション終了 16:50:01: preprogress6。 戻り値 1。
アクション開始 16:50:01: postprogress6。
アクション終了 16:50:01: postprogress6。 戻り値 1。
アクション開始 16:50:01: rt。
アクション終了 16:50:01: rt。 戻り値 1。
アクション開始 16:50:01: preprogress7。
アクション終了 16:50:01: preprogress7。 戻り値 1。
アクション開始 16:50:01: postprogress7。
アクション終了 16:50:01: postprogress7。 戻り値 1。
アクション開始 16:50:01: localedata。
アクション終了 16:50:01: localedata。 戻り値 1。
アクション開始 16:50:01: preprogress8。
アクション終了 16:50:02: preprogress8。 戻り値 1。
アクション開始 16:50:02: postprogress8。
アクション終了 16:50:02: postprogress8。 戻り値 1。
アクション開始 16:50:02: preprogress9。
アクション終了 16:50:02: preprogress9。 戻り値 1。
アクション開始 16:50:02: postprogress9。
アクション終了 16:50:02: postprogress9。 戻り値 1。
アクション開始 16:50:02: preprogress10。
アクション終了 16:50:03: preprogress10。 戻り値 1。
アクション開始 16:50:03: postprogress10。
アクション終了 16:50:03: postprogress10。 戻り値 1。
アクション開始 16:50:03: removepackfiles。
アクション終了 16:50:03: removepackfiles。 戻り値 1。
アクション開始 16:50:03: preprogress12。
アクション終了 16:50:03: preprogress12。 戻り値 1。
アクション開始 16:50:03: postprogress12。
アクション終了 16:50:03: postprogress12。 戻り値 1。
アクション開始 16:50:03: InstallFinalize。
MSI (s) (A4:84) [16:50:03:615]: 製品: Java(TM) SE Development Kit 7 -- エラー 1311。  ソース ファイルが見つかりません。(cabinet): C:\Documents and Settings\xxxxx\Application Data\Sun\Java\jdk1.7.0\st170000.cab。 ファイルが存在するかどうか、およびこのファイルへのアクセス権があるかどうかを確認してください。

エラー 1311。  ソース ファイルが見つかりません。(cabinet): C:\Documents and Settings\xxxxx\Application Data\Sun\Java\jdk1.7.0\st170000.cab。 ファイルが存在するかどうか、およびこのファイルへのアクセス権があるかどうかを確認してください。
アクション終了 16:50:03: InstallFinalize。 戻り値 3。
アクション終了 16:50:03: INSTALL。 戻り値 3。
MSI (s) (A4:84) [16:50:03:646]: 製品: Java(TM) SE Development Kit 7 -- 構成に失敗しました。

=== ログ終了: 2011/09/16  16:50:03 ===