Windows Server に Apache を利用して Subversion サーバーを構築して ActiveDirectory 認証を設定する
タイトルの通り。以下の環境・アプリケーションを使用して Subversion サーバーを構築する。
- Windows Server 2012
- Apache 2.4.16
- Subversion 1.9.0
- 外部からは
http://svn.example.com/svn/
の URL に対してアクセス。
1. 準備
ApacheHaus の Web ページから、Apache および Subversion のモジュールをダウンロードする。 Windows 向けのパッケージは ApacheHaus 以外のサイトでも公開されているが、ApacheHaus だと Subversion のモジュールも一緒に提供されているので安心感がある。
http://www.apachehaus.com/cgi-bin/download.plx
今回は以下のモジュールをダウンロード。 ※ Apache および Subversion のモジュールは VC9 でコンパイルされたものと VC11 でコンパイルされたものの 2 種類があるので揃えるように注意する。
- Apache 2.4.16 x64 (Apache 2.4.x VC11)
- Mod Subversion 1.9.0 for Apache 2.4.x x64 (Modules for Apache 2.4.x VC11)
2. モジュールを展開する
ダウンロードしたモジュールを展開する。今回はそれぞれ以下のディレクトリに展開する。
D:\ `- Application\ `- Apache\ `- httpd-2.4.16-x64\
3. リポジトリを配置するディレクトリを作成する
Subversion のリポジトリを配置するディレクトリを作成する。今回は D:\Application\Apache\_svn\repositories
というディレクトリを作成。
4. Apache の設定ファイルを修正
Apache の設定ファイルを修正。主な修正内容は以下のとおり。
httpd.conf
- デフォルトの設定だと
ServerRoot
が存在しないディレクトリをを指しているので修正 - 必要なモジュールを有効化
- 今回用に作成する設定ファイルを読み込むように設定
svn.conf (新規作成)
- Subversion サーバーの設定
- LDAP 認証の設定
- リポジトリごとのアクセス権限を設定できるようにする
httpd.conf
修正する箇所のみ記載。
(デフォルトの設定だと `ServerRoot` が存在しないディレクトリをを指しているので修正) - Define SRVROOT "/Apache24" + Defile SRVROOT "D:/Application/Apache/httpd-2.4.16-x64" (必要なモジュールを有効化。それぞれ先頭の # を削除してコメント解除。) - #LoadModule authnz_ldap_module modules/mod_authnz_ldap.so + LoadModule authnz_ldap_module modules/mod_authnz_ldap.so - #LoadModule ldap_module modules/mod_ldap.so + LoadModule ldap_module modules/mod_ldap.so (今回用に作成する設定ファイルを読み込むように設定) + Include conf/svn.conf
svn.conf
httpd-2.4.16-x64\conf
ディレクトリ内に新規ファイルとして作成する。
#### Subversion サーバー # モジュールロード LoadModule dav_module modules/mod_dav.so LoadModule dav_fs_module modules/mod_dav_fs.so LoadModule dav_svn_module modules/mod_dav_svn.so LoadModule authz_svn_module modules/mod_authz_svn.so # バーチャルホスト設定 <VirtualHost *:80> ServerAdmin administrator@example.com ServerName svn.example.com CustomLog "logs/svn.example.com/access.log" common ErrorLog "logs/svn.example.com/error.log" Timeout 1200 ProxyTimeout 1200 <Location /svn/> DAV svn SVNParentPath "D:/Application/Apache/_svn/repositories" SVNListParentPath on AuthzSVNAccessFile "D:/Application/Apache/_svn/access-rule.txt" # LDAP認証 AuthType Basic AuthName "Subversion Repository" AuthBasicProvider ldap AuthLDAPUrl "ldap://ad.example.com:389/DC=example,DC=com?sAMAccountName?sub?(objectClass=user)" AuthLDAPBindDN Administrator@example.com AuthLDAPBindPassword administrator-password Require valid-user LDAPReferrals Off </Location> </VirtualHost>
以下、簡単にディレクティブの設定を解説。詳しくはお調べください。
- CustomLog, ErrorLog
該当のバーチャルホストにアクセスされた際のアクセスログとエラーログの出力先を指定。
今回はlogs\svn.example.com
ディレクトリにログを出力するように設定しているが、svn.example.com
ディレクトリを事前に作成していないと apache の起動に失敗するので注意。 - SVNParentPath
Subversion リポジトリが配置されているディレクトリを指定。 - AuthzSVNAccessFile
リポジトリごとにアクセス権限を設定するためのファイルを指定。権限の設定方法は後述。 - AuthLDAPUrl, AuthLDAPBindDN, AuthLDAPBindPassword
LDAP サーバー (今回は ActiveDirectory) に接続するための情報を指定。 - LDAPReferrals Off
よくわからないけど付けないとエラーが発生する。
5. リポジトリの作成
D:/Application/Apache/_svn/repositories
ディレクトリにリポジトリを作成する。他のサーバーに作成済みの Subversion リポジトリをコピーしてきても OK 。
リポジトリを作成するためのコマンドは、Apache ディレクトリに統合した際に httpd-2.4.16-x86\bin
に展開されているので、パスを通すか直接呼び出す。
初期ディレクトリの作成が長くて打ち間違えると大変なので、バッチ化した方がいい。
(リポジトリのルートディレクトリに移動) > cd D:\Application\Apache\_svn\repositories (リポジトリ hoge を作成) > D:\Application\Apache\httpd-2.4.16-x64\bin\svnadmin.exe create hoge (初期ディレクトリ作成) > D:\Application\Apache\httpd-2.4.16-x64\bin\svn.exe mkdir ^ file:///D:/Application/Apache/_svn/repositories/hoge/trunk ^ file:///D:/Application/Apache/_svn/repositories/hoge/branches ^ file:///D:/Application/Apache/_svn/repositories/hoge/tags ^ -m "Create base directories"
6. リポジトリの権限設定
D:/Application/Apache/_svn/access-rule.txt
にリポジトリのアクセス権限を設定するためのファイルを作成する。
[groups] hoge = rabitarochan, user_aaa, user_bbb fuga = user_aaa, user_bbb [repo_hoge:/] * = @hoge = rw [repo_fuga:/] * = @fuga = rw
以下、簡単に解説。詳細は AuthzSVNAccessFile
でググろう。
[groups]
以下にグループを定義することができる。<グループ名> = <ユーザー名>
の形式で記述し、ユーザー名はカンマで区切る。[<リポジトリ(ディレクトリ)名>:<パス>]
以下にアクセス権限を定義できる。パスは/hoge
のように詳細に設定することも可能。* =
をはじめに定義し、全てのユーザーからのアクセスを禁止する。@hoge = rw
を定義し、hoge
グループのユーザーに対して read / write 権限を追加。
読み取り専用の権限を設定する場合は@hoge = r
と記述する。- グループは必ず作成する必要はなく、
user_ccc = rw
とユーザーの権限を直接定義することも可能。
7. Apache を Windows サービスに登録する。
コマンドプロンプトにて以下のコマンドを実行。
(Windows サービスに登録) > D:\Application\Apache\httpd-2.4.16-x64\bin\httpd.exe -k install
以下、オプションなど補足。
-n <サービス名>
とすると、サービス名を指定できる。デフォルトはApache2.4
。- Windows サービスを解除する場合は
-k uninstall
を実行する。もし-n
オプションでサービス名を指定して登録した場合は、名前を揃える必要があるので注意する。
8. 起動, 動作確認
Windows サービスの管理画面から、登録したサービスを開始する。Apache の設定ファイルの記載ミスや、必要なファイル, ディレクトリがない場合は起動に失敗するため、Apache のログファイルを参照して解決する。
まとめ
Apache + Subversion on Windows Server の手順をほぼ 1 から解説してみました。 Collabnet Subversion Edge が遅いと苦情を受けた方 (おれおれ!!) は、ぜひお試しください。
タプルをそれぞれの変数に展開するときにも `@` が使える
FP in Scala の日本語訳読んでます。
読んでることとは直接関係ないですが、例えばこんな関数があったとします。
// 第6章 純粋関数型の状態から // RNG は乱数生成の状態を表すオブジェクトだと思ってください。 def nextInt: (Int, RNG) = ???
この関数を変数に取る際、それぞれ別の変数に分割して取ることができます。
// i には生成した乱数が、nextRng には状態が取れる。 val (i, nextRng) = nextInt
「べつの変数にも分割して取りたいけど、パターンマッチみたいにタプルも一緒に取りたいなー」と思ってたら、同じ書き方で取ることができるようです。知らなかった・・・。
// tpl には結果のタプルがそのまま取れる。 val tpl @ (i, nextRng) = nextInt
私が知らなかっただけかもしれませんが、少し感動したのでブログ書きました。
C#の「nameof」をScalaで実装してみる
C# vNext に、nameof
という演算子が追加されています。
どういうものかというと、指定したメンバー名を string 型で受け取ることができるというとてもイケてる演算子です。
// こんなクラスがあって class Person { public string Name { get; set; } public int Age { get; set; } } // こんなことができる var p = new Person(); Console.WriteLine(nameof(p.Name)); // => "Name" Console.WriteLine(nameof(p.Age)); // => "Age"
参照先の記事にあるように、文字列を指定してリフレクションをしていたコードが安全に記述できるようになります。
「これって Scala のマクロ使えば似たようなことができるんじゃ?」と思ったので、実験してみました。
目標
インスタンスのメンバー名を取れるよりは、型を指定してそのメンバーを取れる方がいいなと思ったので、以下のコードでメンバー名を取得できることを目標にしました。
// こんなクラスがあって case class Person(name: String, age: Int) // こんな定義で def nameOf[A](f: A => Any): String = macro... // こんなことができる nameOf[Person](_.name) // => "name"
コード
注)Scala のマクロを書くのはほぼ初めてです。実験ですのでエラーハンドリング等はちゃんとやってません。
あまり説明もできませんので、コードを張って終わりにしたいと思います・・・。
まとめ
マクロの勉強不足なのでうまくかけていないところもありますが、とりあえず取得できるということが分かりました。 実用的に使えるようにしたいところです。
ScalaでC#のasync, awaitを実現するライブラリ「async」の紹介
この記事は Iwate Advent Calendar 2014 の22日目の記事です。昨日はnana4gontaさんのFirefox Developer Editionを使って他ブラウザをリモートデバッグする - Qiitaでした。明日はayokuraさんです。
岩手関連の記事を書こうと思い、仕事で使おうとしてるD3.jsを使って岩手県を書こうとしたらズバリそのままのサイトを発見して挫折しました。
岩手県ぬりえ
http://acuerdo.m18u.net/iwate_nurie/
結局思いつかなかったので全然関係ない話題を書きます。
続きを読む型パラメータ付きメソッドを持つトレイトとコンパニオンオブジェクト
タイトルはなんだか難しいですが、要は以下のコードのコンパイルを通したいということです。
trait Test { def apply[A](value: A): String } object Test { def apply[A](f: A => String): Test = new Test { def apply[A](value: A): String = f(value) } }
上記のソースだと、Testオブジェクト#applyの型パラメータAとTestトレイト#applyの型パラメータが別々のものなので、コンパイルが通りません。
error: type mismatch; found : value.type (with underlying type A) required: A def apply[A](value: A): String = f(value) ^
どうにかする方法はないでしょうか・・。
Play2.3でSecureSocialを使う(2014年6月時点)
※(2014年6月27日)この情報はすでに古く、Play2.3に対応した公式モジュールがリリースされている可能性があります。公式サイトやリポジトリをご確認ください。
PlayFrameworkに認証/認可機能を追加できるSecureSocial
というモジュールがあります。
- 公式サイト
SecureSocial - Authentication for Play Framework Applications
http://securesocial.ws/ - リポジトリ
jaliss/securesocial
https://github.com/jaliss/securesocial
SecureSocialの特徴は以下のとおりで、必要とされている機能はひと通り用意されており、認証機能を手軽に構築できるモジュールです。(ほぼ上記ページの内容ですが。)
- ScalaだけでなくJavaでも使える。
- Play2だけでなくPlay1でも使える。
- ユーザ/パスワード認証だけでなく、OAuth1,2やOpenIDにも対応。また、TwitterやFacebookなど向けのモジュールも用意されている。
- 既存アプリへの組込みも簡単。
- 拡張性があり、新たな認証にも対応できる。
- ユーザ登録時やパスワードリセット時などにメールを送信する機能が使える。
さて、このモジュールですが残念ながら現在(2014/06/27)時点でPlay2.3向けのモジュールが提供されていません。 現在の状況としては、PRは投げられていますがメイン開発者が他の機能に注力しているため、レビュー・取り込みされていません。
ですが、PR元のプロジェクトをsbtで参照することで、Play2.3に対応したSecureSocialが使えますので、今回はその手順をまとめてみました。
- Playプロジェクトを作成する
- Play2.3対応版SecureSocialをプロジェクト参照する
1. Playプロジェクトを作成する
まずは、空のプロジェクトを作成してきます。Play2.3からはplayコマンドではなく、Typesafe Activatorを利用してプロジェクトを作成するように変更されていますのでご注意ください。
今回は、play23-securesocial
というプロジェクト名でplay-scala
というテンプレートを利用して作成します。
> activator new play23-securesocial play-scala
Typesafe Activatorとは?
Typesafe Activatorとは、Scalaプロジェクトをあらかじめ用意されたひな形を利用して作成できるツールです。実際には、Webからソースコードを編集するUIなども用意されているようですが、ここでは説明しません。
Typesafe Activatorをインストールしていない方は、公式サイトZIPファイルをダウンロードし、任意の場所に展開します。 その後、実行ファイルにPATHを通せばactivatorコマンドが利用できるようになります。
PlayFrameworkのインストールに関するドキュメント
Installing
http://www.playframework.com/documentation/2.3.x/InstallingTypesafe Activatorのインストールに関するドキュメント
Build Reactive Applications with Typesafe Activator | Typesafe
http://typesafe.com/platform/getstarted
Typesafe Activatorをインストールしたくない!
Typesafe Activatorをインストールしたくない方は、@xuwei_kさんがズバリのブログ記事を公開していますので、そちらを参考にしましょう。
- typesafe activatorを使わないplayframework2.3の始め方 - scalaとか・・・
http://d.hatena.ne.jp/xuwei/20140531/1401525122
ただし、この記事ではTypesafe Activatorを利用して作成したプロジェクトを元に話を進めます。build.sbt
の中身がTypesafe Activatorを利用した場合と@xuwei_kさんの記事とで若干異なりますのでご注意ください。
2. Play2.3対応版SecureSocialをプロジェクト参照する
プロジェクトが作成できましたので、Play2.3に対応したSecureSocialを参照するように設定します。
といっても、冒頭に記載したとおりPlay2.3に対応したモジュールはまだリリースされていませんので、libraryDependencies
では参照できません。そのため、GitHubのリポジトリを直接参照するように、build.sbt
を書いていきます。
//build.sbtの一部 lazy val root = (project in file(".")).enablePlugins(PlayScala) .dependsOn(ProjectRef(uri("https://github.com/ewiner/securesocial.git#play-2.3"), "mainModule"))
dependsOn
以降を追加することにより、uriで指定した、Play2.3対応SecureSocialのGitプロジェクトが参照されます。
まとめ
Play2.3対応のSecureSocialについて調査していたところ、上記の方法で使えるという情報があったのでまとめてみました。 それより、sbtにGitプロジェクトを直接参照する機能があることを知らず感動しました。知らないことはまだまだいっぱいありますね・・。
認証/認可に必要な機能はひと通り揃っているモジュールですので、興味のある方はSecureSocialを使ってみてください。
FluentdのWindowsブランチに対してテストを流してみた
※Rubyはほとんど触ったことありません。
FluentdのWindowsブランチに結構手が入ってるようでしたので、テストを流してみました。
結果はこちら。
実行環境
2013-12-19現在のWindowsブランチのHEADに対してテストを実施しました。
- OS: Windows 8 x64
- Ruby: ruby 1.9.3p362 (2012-12-25) [i386-mingw32]
- Bundler: Bundler version 1.2.3
- Rake: rake, version 10.1.0
実行方法
何も考えずにbundle exec rake test
を実行すると、すぐエラーが発生してしまうので、以下のバッチファイルを作成して1ファイルずつテストを流しました。
@echo off @call bundle install for %%f in ("test\*.rb") do ( echo [Test start: %%f] @call bundle exec rake --trace test TEST='"%%f"' >test_log\%%f.log 2>&1 ) for %%f in ("test\plugin\*.rb") do ( echo [Test start: %%f] @call bundle exec rake --trace test TEST='"%%f"' >test_log\%%f.log 2>&1 ) pause exit /b 0
結果
プラグインで結構失敗が多いですね。中にはRuby側?なのか、[BUG] win32_mutex_lock: WAIT_ABANDONED
と出力されていました。
in_tail.rb
のテストで発生したエラーを追いかけてみると、shutdown
メソッドの@thread.join
を実行した際に上記のエラーが発生していました。Cool.io絡みなのかとおもいつつ、それを使っているプラグインにはテストが成功しているものもあるので、一概には言えない感じですね・・。Unixにひもづく処理だったり、ファイルを扱う処理なのでしょうか。
あと、そのままテストを流すと、おそらく$platformwin
がうまく設定されていない感じだったので、それも原因の一つかもしれないです。Issueに、Windows版の場合はソースを分けるというものが上がっていたので、その対応次第では通るテストも増えるかもしれません。
まとめ
やはりWindows対応は大変そうだなーという印象でした。もう少しRuby力をあげて、直せそうなところから手をつけていきたいです。