メンチカツには醤油でしょ!!

AWS/Java/Node.js/Spreadsheets/Docker/Jenkins/コミュニティ・勉強会レポを主とした技術系ブログ

WindowsマシンでJenkinsを構築して、SVNソース取得⇒エックスサーバーへアップ

 

そろそろやらないと取り残されちゃうのと、情報が充実してきたのでJenkins。
Macも持ってるからそっちでやれって感じなんだけど、
オトナの事情によりWindows 8.1 (・・;

 

Welcome to Jenkins CI! | Jenkins CI
http://jenkins-ci.org

 

Windowsなので、native packageからWindowsインストーラーをDLします。

 

インストールしてジョブ設定したんだけど、実行するとエラー。
SVNから取得する親プロジェクトはうまくいってる。
(だってsvn updateしてるだけなのでw)

 

ビルドします。 ワークスペース: C:\Jenkins\workspace\【ジョブ名】 [【ジョブ名】] $ sh -xe C:\Windows\TEMP\hudson9164964019113453717.sh 指定されたファイルが見つかりません。 FATAL: コマンドの実行に失敗しました java.io.IOException: Cannot run program "sh" (in directory "C:\Jenkins\workspace\【ジョブ名】"): CreateProcess error=2, ?w?????t?@? at java.lang.ProcessBuilder.start(Unknown Source) at hudson.Proc$LocalProc.<init>(Proc.java:244) at hudson.Proc$LocalProc.<init>(Proc.java:216) at hudson.Launcher$LocalLauncher.launch(Launcher.java:773) at hudson.Launcher$ProcStarter.start(Launcher.java:353) at hudson.Launcher$ProcStarter.join(Launcher.java:360) at hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:94) at hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:63) at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20) at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:781) at hudson.model.Build$BuildExecution.build(Build.java:199) at hudson.model.Build$BuildExecution.doRun(Build.java:160) at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:562) at hudson.model.Run.execute(Run.java:1665) at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:46) at hudson.model.ResourceController.execute(ResourceController.java:88) at hudson.model.Executor.run(Executor.java:246) Caused by: java.io.IOException: CreateProcess error=2, ?w?????t?@? at java.lang.ProcessImpl.create(Native Method) at java.lang.ProcessImpl.<init>(Unknown Source) at java.lang.ProcessImpl.start(Unknown Source) ... 17 more Build step 'シェルの実行' marked build as failure Finished: FAILURE

 

要するにshコマンドが発行できねーぞということなんだけど、
Windowsネイティブ環境にはそもそもそんなものないので、
Cygwin を入れてみた。

 

WindowsCygwin バージョン 1.7 をインストール
http://www.kkaneko.com/rinkou/cygwin/cygwin.html
文中のC:¥cygwinのパス追加の所は64bitを入れた人はC:¥cygwin64〜なので注意ね。
(ちょっとハマったw)
追記 (上記のサイトが飛んでしまったので、近いものを追記しました)
Windowsでターミナル環境の構築 - kametasoと月からの使い
http://khmtvx.hatenablog.com/entry/2013/08/30/151358

 

Windows 8だったからかはわからないが、ウィザードの途中Cygwin 導入パッケージ に Devel/git-svn がデフォルトチェックついてなかったのでon
(というか、ここは必要なもの全部確認したほうがよさそう。他の環境に入れた時も今回使いたいrsyncsshがチェックなかったり…)
で、環境変数系を設定。
上記URLの (オプション) パッケージの追加 あたりまで全部やった。

 

ファイル名を指定して実行 ⇒ cmd で、
ls (Windowsでいうdirコマンド) とか
shコマンドも打ってみたけどなんか動いてるみたい。
sshコマンドもrsyncコマンドも打って確認しておいたほうが良い。

 

んで、お次はこれ。

 

ユーザーanonymousが実行

ビルドします。 ワークスペース: C:\Jenkins\workspace\TestJob001

[TestJob001] $ sh -xe C:\Windows\TEMP\hudson7666424012018919149.sh

指定されたファイルが見つかりません。

FATAL: コマンドの実行に失敗しました

java.io.IOException: Cannot run program "sh" (in directory "C:\Jenkins\workspace\TestJob001"): CreateProcess error=2, ?w?????t?@?

at java.lang.ProcessBuilder.start(Unknown Source)

at hudson.Proc$LocalProc.<init>(Proc.java:244)

at hudson.Proc$LocalProc.<init>(Proc.java:216)

at hudson.Launcher$LocalLauncher.launch(Launcher.java:773)

at hudson.Launcher$ProcStarter.start(Launcher.java:353)

at hudson.Launcher$ProcStarter.join(Launcher.java:360)

at hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:94)

at hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:63)

at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)

at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:781)

at hudson.model.Build$BuildExecution.build(Build.java:199)

at hudson.model.Build$BuildExecution.doRun(Build.java:160)

at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:562)

at hudson.model.Run.execute(Run.java:1665)

at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:46)

at hudson.model.ResourceController.execute(ResourceController.java:88)

at hudson.model.Executor.run(Executor.java:246)

Caused by: java.io.IOException: CreateProcess error=2, ?w?????t?@?

at java.lang.ProcessImpl.create(Native Method)

at java.lang.ProcessImpl.<init>(Unknown Source)

at java.lang.ProcessImpl.start(Unknown Source)

... 17 more

Build step 'シェルの実行' marked build as failure

Finished: FAILURE

 

・・・ん~さっきshはできたのになーと思って、cmdからエラーだというコマンドを発行。

sh -xe C:\Windows\TEMP\hudson7666424012018919149.sh

ここね。

そしたら、これがきた。

cygwin warning:

  MS-DOS style path detected: C:\Windows\TEMP\hudson7666424012018919149.sh

  Preferred POSIX equivalent is: /cygdrive/c/Windows/TEMP/hudson7666424012018919149.sh

  CYGWIN environment variable option "nodosfilewarning" turns off this warning.

  Consult the user's guide for more details about POSIX paths:

    http://cygwin.com/cygwin-ug-net/using.html#using-pathnames

sh: C:\Windows\TEMP\hudson7666424012018919149.sh: No such file or directory

 

このパスの指定の仕方はWindows方式だからダメよ、と。

 

ここでMacを触る機会があったので、同じ設定をしたら動いた。

そりゃそーか。

でも今回俺はWindows機にセットアップしないといけないんだよなぁ…

 

想定している解決案は2つ
1. Cygwinで使うパスについて、Windows表記を解釈させるオプションがどっかにないか
2. Jenkins が発行するコマンドのパスの部分を、UNIX形式もしくは指定できないか。

 

しかし、問題はそこじゃなかった。
気づいたことが・・・

 

こんな感じで設定していたのだが、

f:id:ryoichi0102:20131022154738j:plain

この ビルド手順の追加▼ で シェルの実行 を選んでたのが間違い。
Windowsバッチコマンド実行 を選びなおしたらできた。

 

なんだ"Windowsコマンドだけで全部できる"ならCygwinいらないじゃん。
(今回はそれでもrsyncsshを使用するのCygwinは必要でした)


はい次。

 

C:\Users\【俺】>rsync -auvz --delete --exclude '.svn' -e "ssh -p 10022 -i /cygdrive/c/Users/【俺】/.ssh/【秘密鍵】.key" "/cygdrive/c/Jenkins/workspace/TestJob001/" 【サーバーアカウント名】@【ホスト名】.xsrv.jp:/【サーバー内のディレクトリ】/

The authenticity of host '[【ホスト名】]:10022 ([【IPアドレス】]:10022)' can't be established.

RSA key fingerprint is 【英数字2桁コロン区切り】.

Are you sure you want to continue connecting (yes/no)? yes【←yes入力】

Warning: Permanently added '[【ホスト名】]:10022,[【IPアドレス】]:10022' (RSA) t

o the list of known hosts.

 

 

cmdからもコマンド実行して試しているんだけど
ここのyesは一回入力したらもう出なくなった。
(最低限1回はコマンドラインから実行する必要あるってこと?
 Jenkinsだけで構築した場合、誰がyes入れてくれるんだろう。
 もしくはずっとJenkinsからは解決できないエラー?) 
ここは原因不明だけど、できちゃったので次へ。。。
(後でknown_hostsに登録すれば良いということがわかった、Cygwin実行時のknown_hostsってどこなんだろか)

 

C:\Users\【俺】>rsync -auvz --delete --exclude '.svn' -e "ssh -p 10022 -i /cygdrive/c/Users/【俺】/.ssh/【秘密鍵】.key" "/cygdrive/c/Jenkins/workspace/TestJob001/【パス】" 【ユーザー名】@

【アカウント名】.xsrv.jp:/【アカウント名】.xsrv.jp/test

Enter passphrase for key '/cygdrive/c/Users/【俺】/.ssh/【秘密鍵】.key':

sending incremental file list

rsync: mkdir "/【アカウント名】.xsrv.jp/test" failed: No such file or directory (2)

rsync error: error in file IO (code 11) at main.c(576) [receiver=3.0.6]

rsync: connection unexpectedly closed (9 bytes received so far) [sender]

rsync error: error in rsync protocol data stream (code 12) at /usr/src/ports/rsy

nc/rsync-3.0.9-1/src/rsync-3.0.9/io.c(605) [sender=3.0.9]

泣。

あるあるあるあるそのディレクトリあるからー。

 

よしまずはrsyncコマンドにも書いたsshで入れるかどうか。 

C:\Users\【俺】>ssh -p 10022 -i /cygdrive/c/Users/【俺】/.ssh/【秘密鍵】.key 【ユーザー名】@【アカウント名】.xsrv.jp

で入ったらそれはできる。
ssh関連が間違ってるわけではなさそう。

 

んで、pwd したら

/home/【ユーザー名】 

だって。
なんだパス指定の頭の / が要らないのか。

 

C:\Users\【俺】>rsync -auvz --delete --exclude '.svn' -e "ssh -p 10022 -i /cygdrive/c/Users/【俺】/.ssh/【秘密鍵】.key" "/cygdrive/c/Jenkins/workspace/TestJob001/【パス】" 【ユーザー名】@【アカウント名】.xsrv.jp:【アカウント名】.xsrv.jp/【パス】

Enter passphrase for key '/cygdrive/c/Users/【俺】/.ssh/【秘密鍵】.key':

sending incremental file list

【転送したファイルが一覧で表示される】

【転送したファイルが一覧で表示される】

【転送したファイルが一覧で表示される】

 

脳汁出たわw

 

とりあえずcmdからファイル転送できるようになった。

 

で、Jenkinsから同じことするとこれですわ。

ユーザーanonymousが実行

ビルドします。 ワークスペース: C:\Jenkins\workspace\TestJob001

[TestJob001] $ cmd /c call C:\WINDOWS\TEMP\hudson8318937263722321795.bat

 

C:\Jenkins\workspace\TestJob001>rsync -auvz --delete --exclude '.svn' -e "ssh -p 10022 -i /cygdrive/c/Users/【俺】/.ssh/【秘密鍵】.key" "/cygdrive/c/Jenkins/workspace/TestJob001/【パス】" 【ユーザー名】@【アカウント名】.xsrv.jp:【アカウント名】.xsrv.jp/【パス】 

Host key verification failed.

rsync: connection unexpectedly closed (0 bytes received so far) [sender]

rsync error: unexplained error (code 255) at /usr/src/ports/rsync/rsync-3.0.9-1/src/rsync-3.0.9/io.c(605) [sender=3.0.9]

 

C:\Jenkins\workspace\TestJob001>exit 255 

Build step 'Windowsバッチコマンドの実行' marked build as failure

Finished: FAILURE 

 

Host key verification failed. ・・・ですか。


http://www.asterisk-works.jp/wiki/index.php/SSH
ここを見ると、known_hostsがうんたら。

 

vi ~/.ssh/known_hosts
すると確かに何か書かれている。
上に書いたyesがよろしくなかったのか、その後色々鍵を生成しなおしたので
そのタイミングでここだけ更新されてなかったのだろうきっと、きっと。
とりあえずknown_hostsの該当項目(今回接続するサーバーのとこ)を消したりもした。

 

だめだー><まだ出る。状況変わらず。

 

何度も公開鍵を再生成したり、known_hostsを消して再試行するなど試行錯誤。

 

are sure you want の所で no すると、
Host key verification failed.
が出ることに気づいた。
うわーこれじゃん。noでも接続できるように何かしないといけないってことね。

 

(ここらへんで1週間ぐらい経った。だんだん疲れてきたよー)

 

結果ここは、
エックスサーバーのパスフレーズ なしで設定してその秘密鍵を使ってみたが
どうもだめ。
Jenkinsのビルドエラーのコンソールの最初にanonymousで実行と出てるんだけど、それが何か気になる。
俺ユーザーじゃないからダメなのか?

 

 

ここでユーザー関連をいじってしまい、ログインできなくなった。
config.xml 削除でもだめ。
まさかのゴール直前?で再インストール T T

 

・・・さて、ユーザー登録もちゃんとしなおして再開。

 

なんか色々調べてたらこれが出て来た。

 

Windows ServerでJenkins Git Plugin を使う | 開発もがきログ
http://devstrugglog.tumblr.com/post/44417371337/windows-server-jenkins-git-plugin

ここを見ると、

JenkinsのWindowsサービスをLOCAL SYSTEMで動かしている場合は、SSH鍵は C:\Windows\SysWOW64\config\systemprofile.ssh に置く。

 って書いてあって、なるほどWindowsで実行しているときはLOCAL USER(?)で実行されるのかーということがわかってきた。

 

で、Jenkinsの設定にそういうものがないかどうかずっと探していたんだけど、
ここで上司ヘルプ!w

 

Windowsのservices.msc (コンパネのサービス) に Jenkins が居て
そこの実行ユーザーをWindowsのログインユーザーに変えてあげたらいけた。

 

f:id:ryoichi0102:20131031184210j:plain

 

ここ ↑ の、

 

f:id:ryoichi0102:20131031184231j:plain

 

↑ これね。

 

known_hostsに登録してあげる必要があるので、
一度はコマンドラインから入って、プロンプトyesで登録するか
known_hostsをエディタ編集で登録するといいよ。

 

疲れてるときは視野が狭くなるから誰かに聞くといいよw
ひとまずここで奮闘記としては完了。

 

※ 後記1

この後、rsyncで転送したファイルのパーミッションが700なので
chmod発行しなおしたりなどもあった。

 

※ 後記2

転送しているブツがCake PHPだったのでrsyncコマンドはwebroot除外して
2回rsyncする必要が出てきた。

 

後記らへんに関してはベストプラクティスがありそうなので
色々運用しながら変えていこうと思う。

 

かくして、私もJenkinsが使える人の仲間入りを果たした。