Subversion export remotely with uninstalled svn-rexport.sh
Subversion 採用了許多成熟的程式庫,這種模組化的設計,使其可以專注在版本控制的核心問題上,而不必與如 portability 等問題打交道。然而,若我們想要在全心安裝的系統裡,儘快開始使用 Subversion 的話,這種設計,就會因為 dependency 太多,產生許多安裝時的麻煩。這些麻煩,在當我們開始將許多軟體的設定檔,放進 repository 之後,更容易造成 bootstrapping 的問題。
例如,Subversion 相依於 Apache,而我對於 www/apache22,亦有一套針對自己喜好的設定,這些設定會存放於 Subversion 裡做版本控制。裝新機時,直接從 Subversion 裡拿出設定檔,即可將系統安裝成我慣用的樣子。然而,以上實際上是個雞生蛋、蛋生雞的問題:在裝 www/apache22 之前,沒辦法安裝 devel/subversion,但我又需要 devel/subversion,以便取得放在 repository 裡,用來設定 www/apache22 的選項。
為了解決這個問題,要不是得先用預設選項,裝一組陽春的 www/apache22 與 devel/subversion,起出設定選項之後,再整個砍掉重練一次;要不就得利用其它機器,取得設定檔。前者太過麻煩,所以我通常是用後者。
但後者其實還是很麻煩,因此,如果有個機制,可以讓我不必安裝 Subversion,就可以取得 svn export 出的內容,那整件事情就容易許多了。因為我有寫 install script,所以若有這個機制,整個 deploy 過程,就可以用兩個指令搞定:
- 利用這個機制,取出最新版的設定;
- 執行 install script,會將整個環境設定成我慣用的樣子,所有設定檔皆安裝至定位。
所以,問題來了,怎樣在本機尚未安裝 Subversion 的情況下,透過另一台機器,取得 repository 內容?甚至,做這件事的程式,如果不必先安裝在本機,那更好。於是,我發現我搞出了 svn-rexport.sh 這個 script。這個 script 的用法很特別,其 usage 為 (後略):
Usage: ssh [USER@]HOST svn-rexport.sh [OPTIONS...] URL [PATH] | sh -s
流程為:
- 透過 ssh 到另一台遠端機器裡執行安裝在那台機器上的
svn-rexport.sh,因此,我們無須在本機安裝svn-rexport.sh。 - 接著,在遠端執行的
svn-rexport.sh,會依據 command-line 參數,將由 URL 指定的 repository 內容,export 出來。 - 起出內容之後,用
shar(1) 包裝,寫到stdout。 - 由
svn-rexport.sh在遠端機器輸出的 shar 檔內容,會透過 SSH 送回本機,此時用 pipe 導到每台 UNIX 都有的 bourne shell (sh),令sh從stdin讀入要執行的內容並執行之。 - 因為 sh 所執行的內容,格式為 shar,相當於解開這個 shar-ball,於是就在本機裡,將我們所需要的 repository 內容,解開置放於目前目錄下。
然後,我就可以執行 install script,將慣用的環境 deploy 出來。整個機制,在本機端,只需要有 ssh 與 sh 兩個指令即可。
以上,實在是太邪惡了啊,不過,的確是替我節省了很多時間,讓我隨時可以開個 VM,兩、三動裡,就可以重現我慣用的開發環境,十分方便。程式碼放在 gist:312523 (svn-rexport.sh),以下為完整的 usage message:
Usage: ssh [USER@]HOST svn-rexport.sh [OPTIONS...] URL [PATH] | sh -s
Export Subversion URL in remote host and extract to local PATH>, even without
this script. Assuming this script is already deployed in HOST, and USER can
run Subversion commands non-interactively in HOST. This command will run this
script in HOST as USER, export from Subversion URL, pack as shar(1) ball, send
back via ssh(1), and extract locally to PATH.
Alternatively, we can specify USER@HOST via --connect option if we have this
script deployed in local machine. When --connect is specified, we should run
this script locally. This script will manipulate all of above via ssh(1).
Options:
-h,--help Show this help message.
-u,--username USERNAME Use USERNAME to login to Subversion repository.
-p,--password PASSWORD Use PASSWORD to login to Subversion repository.
(USERNAME and PASSWORD are required if these is no
credentials cached in USER@HOST, since Subversion
command will be ran non-interactively.)
-c,--connect [USER@]HOST When run this script locally with this option,
will connect to USER@HOST via ssh(1) to export URL
to local PATH. (USER default to $USER).
-r,--revision REV Use REV as the Subversion revision argument.
-v,--verbose Show verbose messages.
Example:
- Run remotely: will run this script in HOST as USER, export from Subversion
URL, pack as shar(1) ball, send back via ssh(1), and extract locally to PATH.
SHELL> ssh USER@HOST svn-rexport.sh http://foo.com/svn/ bar | sh -s
- Run locally: will execute subversion command remotely via ssh(1).
SHELL> svn-rexport.sh --connect user@foo.com http://foo.com/svn/ bar
Revision: r578 (2010-02-24)
噢,對,--connect 還沒做。:-p



Post a Comment