VirtualBox在Ubuntu下無法安裝Guest Additions

剛剛在VirtualBox 4.2.4裝了Ubuntu 12.10,安裝完畢後要安裝Guest Additions卻發生錯誤,按照console的提示把訊息印出來 /var/log/vboxadd-install.log 錯誤大概是這樣的:

Error: unable to find the sources of your current Linux kernel.

Google後發現這篇討論串

然後發現先安裝下列的套件然後再安裝Guest Additions,就可以了!

sudo apt-get install dkms build-essential linux-headers-generic

解決VirtualBox的共用資料夾無法建立軟連結

我的電腦我習慣上桌面還是用Windows,但是開Server下指令還是Linux系統方便多了,所以開發時需要執行東西我會用VirtualBox開Ubuntu來進行。

VirtualBox有個方便的功能稱為共用資料夾(shared folder),因此我習慣將在Windows的workspace利用共用資料夾分享到Ubuntu (VM)裡面,然後由Ubuntu來開server。

但是最近開始玩Node.js發現,VirtualBox共用資料夾安裝是無法增加軟連結(Symbolic link)。因為安裝npm package的時候經常需要增加軟連結的權限,因此安裝的最後就會出現錯誤訊息!

npm ERR! Error: EROFS, symlink '../express/bin/express'
npm ERR! If you need help, you may report this log at:
npm ERR!
npm ERR! or email it to:
npm ERR!     

npm ERR! System Linux 2.6.38-13-generic
npm ERR! command "/PATH-To-NODE/bin/node" "/PATH-To-NODE/bin/npm" "install" "express"
npm ERR! cwd /media/sf_SHARED_FOLDER/test
npm ERR! node -v v0.8.15
npm ERR! npm -v 1.1.66
npm ERR! path ../express/bin/express
npm ERR! code EROFS
npm ERR! errno 56
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR!     /media/sf_SHARED_FOLDER/test/npm-debug.log
npm ERR! not ok code 0

而在console執行建立軟連結的指令也會錯誤

$ ln -sf /SOME_PATH/SOME_FILE /media/sf_SHARED_FOLDER/A_SYMBOLIC_LINK
ln: creating symbolic link `/media/sf_SHARED_FOLDER/A_SYMBOLIC_LINK': Read-only file system

google之後看到這篇文章發現原來python virtualenv也有類似的問題。總之在HOST OS為Windows 7、Client OS (VM)為 Ubuntu Linux的時候,共用資料夾就會發生軟連結無法寫入的情況!

修正方法如下,請在HOST (Windows) 開啟cmd (需要管理員權限開啟):

> c:OracleVirtualBoxVBoxManage setextradata YOURVMNAME VBoxInternal2/SharedFoldersEnableSymlinksCreate/YOURSHAREFOLDERNAME 1

上面的參數請視情況修改:

  • c:OracleVirtualBox : 這是VirtualBox的預設資料夾,如果安裝在不同資料夾,請自行修改。
  • YOURVMNAME : 請修改為你要開啟的VM名稱。
  • YOURSHAREFOLDERNAME :修改為VM設定中共用資料夾的名稱

確認是不是設定成功了,可以用這個指令查看:

> c:OracleVirtualBoxVBoxManage getextradata YOURVMNAME enumerate

設定完畢後就可以順利使用了!

如果設定後出現這樣的錯誤:

ln: failed to create symbolic link `LINKNAME': Protocol error

表示你的VirtualBox不是用管理員權限打開。

[翻譯] 安全的儲存密碼 (Storing Passwords Securely)

其實我的對於系統儲存密碼這件事情,原本是以為用MD5、SHA之類的單向雜湊函式來儲存就「夠安全了」。前幾天看到了Storing Passwords Securely這篇文章,才徹底的把我從迷思中拉出來,文章還蠻淺顯易懂的,所以就試著翻譯一下。接下來是免責聲明,雖然我略懂一些資訊安全的皮毛,但我不是資訊安全方面的專家,加上我的英文能力不佳所以翻譯可能有錯誤,如果有任何不精確的地方希望能海涵,然後以下的內容僅翻譯文章中間的部分,前面與最後面Additional Measures、Extra我沒有翻譯,如果有興趣可以去看看原文

Continue reading “[翻譯] 安全的儲存密碼 (Storing Passwords Securely)”

JDownloader如何在Windows XP中自動換IP (PPPoE連線為例)

JDownloader是一套很強的下載軟體,他可以自動下載freakshare.net, megaupload.com, filesonic.com, rapidshare.com 等等免費空間(這裡有完整支援網站列表),雖然有些驗證碼(Captcha)還是要自行輸入,不過一大堆檔案要下載時還是方便多了。此外要抓Youtube的影片也可以用JDownload下載。

不過這邊主要不是要介紹JDownloader怎麼用,主要是想要說明一下JDownloader自動換IP功能。這邊介紹的是以一般寬頻連線(ADSL或是光世代等利用PPPoE方式連線)。因為許多免費空間都會利用IP來限制下載的容量,也就是說一個IP下載超過某個容量後就要等一段時間才可以繼續下載。不過JDownloader可以讓你的電腦(如果能夠的話)可以自動更換IP,然後繼續下載以節省時間。然後大家都知道ADSL、光世代一般來說PPPoE播號都是浮動IP,也就是說重新連線IP就會更換了,也因此這邊就是要介紹Windows XP (vista跟7差不多)可以自動斷線、自動重新播號以取得新IP的這個過程。

Step 1. 讓Windows連線不要提示

為什麼說,要讓Windows連線不要提示呢?因為一般撥號連線Windows會詢問密碼之類的,會停在確認的地方,如此每次換IP都還要自己按一下很麻煩,所以首先要讓Windows在連線寬頻網路的時候不要詢問使用者自動連線。

其實很簡單,就是找到你的連線,然後押右鍵 內容 > 選項 之中的撥號選項都不要勾,這樣就會自動進行連線啦。

 

Step 2. 在JDownloader中設定自動連線的指令

再來就是把下面的指令寫入JDownloader就行了,注意因為我的連線名稱就叫”寬頻連線”,請改用自己電腦上的連線名稱,備註:這個指令也可以運用登入自動連線。

 

 

C:WINDOWSsystem32rasphone.exe -h “寬頻連線”
ping 127.0.0.1 -n 5 -w 1000 > nul
C:WINDOWSsystem32rasphone.exe -d “寬頻連線”

設定的地方可以在這裡找到,設定好了之後最下面的變更IP可以測試看看設定是否成功。

Update Oct 8, 2011: 中間增加一行ping這個指令,這是在掛斷連線後休息五秒後再嘗試重新連線。

Update Oct 9, 2011: 下圖Step3應該是要選隔壁的那個tab,批量(Batch)才是對的

簡單介紹到這邊。感謝收看啦!

程式設計師的美德

程式設計師的美德,真是一個值得每個程式設計師釘在牆上的經典,所以決定要寫篇文章讓自己不要忘了。

「程式設計師的美德 (The Virtues of Programmer)」是Perl的發明者之一的Larry Wall在歐萊禮的駝峰書 Programming Perl中提到的,他列了三項美德分別是:懶惰(Laziness) 、沒耐心(Impatience)、自大(Hubris),這三項ㄧ般都是用在負面的地方的詞,為什麼又會變成程式設計師的美德呢?讓我們細說從頭。

↓ 大咪眼睛大大的超可愛的~沒表情還真是個小帥哥阿
IMG_6795.jpg

程式設計師的美德

以下是我大略的原文翻譯,原文可以在wiki中找到。如果有不正確或不精準的地方,也麻煩給我feedback。

  • 懶惰(Laziness):懶惰的程式設計師會為了減少整體開發所消耗的心力而撰寫高品質的程式碼。而且撰寫文件讓你不需要回答許多問題。[註:所以懶惰的程式設計師會減少重複的程式碼(redundant code)、會考慮可重用的架構(reusable)]
  • 沒耐心(Impatience):怒氣讓程式設計師覺得電腦程式實在跑太慢了。這讓程式設計師撰寫程式不單單只考慮程式的需求,而是考慮得更深遠。[註:所以沒耐心的程式設計師,會考慮程式的運行效率等非功能性的需求]
  • 自大(Hubris):這種極端過度的自信讓程式設計師不想讓別人看到他所撰寫或維護的程式有任何缺點。[註:所以自大的程式設計師,會撰寫讓人無可挑剔的程式碼]

以下開始抱怨…可略過…

失德的程式碼

我眼睛盯著專案的重複了幾十處的程式碼,抓狂的對著螢幕怒吼著:「這就是這個程式設計師不夠懶阿!」。工作上看到了某個案子的程式有著大批大批的redundant code、可以想見當初的狀況就是完全沒有考慮重用就直接把package裡面的source複製貼上,然後再改裡面的code。也許,當初是為了「快」所以複製了第一段程式碼。這樣只要修改一下設定檔就可以使用了,第一時間感覺起來好像「比較快」,所以有第一個、第二個到十幾個,當第一扇窗戶破掉的時候不快點處理,接著旁邊的窗戶很快就會開始破掉! (請參考破窗理論),不斷複製貼上的結果很快其他窗戶就全破掉了。

這個程式設計師不但不夠懶,沒考慮自己後續維護的時間、只想到眼前這樣修改比較快,可是麻煩的垃圾全部都在後續維護的時候才慢慢發酵。而且也不夠自大,所以編寫出來的程式讓我看了很怒。而且也太有耐心,這個程式跑得真的慢透了,啟動要跑三小時以上,難道都沒有人覺得討厭嗎?(註:而且三小時是我turing過系統的效率之後,沒turing過之前跑一跑會自己自動葛屁)。

破窗之後?

由於程式非常分散,每個package的code有點像又不大像,所以想要merge也是很困難的任務,所以現在要改邏輯或turing performance都非常困難,修改起來也相當沒有信心。此時我會陷入一種兩難,一個就是想要先把程式的架構搞好,即重構(refector),但是怕又弄出了一堆Bug,因為程式會改有差異一是有原因的,不過不是你改的也很難確定到底是什麼原因,就算是自己弄得日子久了怕也忘光了。這麼多分散的程式,全部無腦的merge起來也可能會出更多的trouble,再說要整理所要多花的時間究竟有多久實在很難評估。所以大部分的時候,我還是選擇依照這個個亂搞的架構繼續亂搞,減少變動的幅度也減少出trouble的機會。所以像我現在要改一個邏輯就必須改幾十個地方,但是就算是這樣也還是比我把整個架構翻掉重改還快。

出了什麼問題

也許,有先前弄過這個專案看到會很不滿,在此深深的一鞠躬,我不認為這是哪個個人的錯,至少不全然是。我沒有責怪的意思,而且我也是繼續把窗戶弄破的幫兇,而且我剛剛也說了,通常我會選擇繼續沿用糟糕的架構把功能做完,而不是改善架構。也許後來維護的人,也許也會同樣的對我有怨念。我認為,會出現破掉的窗戶的理由只有兩種:

  1. 技術能力不足:先前波波醫師吵得沸沸揚揚之際,有人說「沒有醫術、哪來的醫德」,當程式設計師的技術能力不夠的時候,要完成功能已經是不容易了,哪還有的心思去思考什麼其他的問題呢?當然無法撰寫出有品質的程式!更無法能有什麼德行了。首先是一個地方破了一個窗,之後整個系統都有可能崩潰。
  2. 這是組織的政治與文化的問題:對許多程式設計師而言,撰寫更精巧、更漂亮的程式碼也是一件振奮人心的事情,有些人甚至將之視為一種「修練」,然而去實作或修改某些功卻並非總是那麼的有趣。所以,程式碼的品質變取決於組織的文化,而組織的文化又是因為高層的態度而形成的。有些組織高層很注重程式的品質,甚至在政策上訂有各種規範與標準,由此形成的文化就會趨向高品質邁進(當然阿,也有規定太多寫東西綁手綁腳的,這又是另一個問題了)。然而另一個極端,如果組織高層根本就不管你怎麼做到的,形成「花時間去提高程式碼的品質」這件事情變成曲高和寡,而變成「要多花時間弄出好程式的請自己多花時間加班」在沒有胡蘿蔔更而有木棒的情況下,大多數的人趨向用quick & dirty的方式把功能delivery,這樣又有多少人可以真正的成為有德之人呢?如果文化已經形成,旗下的程式碼普遍都是亂寫的時候,想要改善恐怕也來不及了吧?當組織所累積的所謂資產都是這種破窗,那所謂的實力到底是什麼?

嘮叨了一堆,事實上是抱怨的成分居多,一方面也警惕自己千萬不要把自己的基礎建設搞得窗戶全破了。

WordPress在Linux上安裝、更新套件出現錯誤

把Wordpress從Windows搬到Ubuntu Linux上之後,出現了選擇安裝、更新套件的時候出現要求輸入FTP、SSH帳號的訊息「欲執行此動作,WordPress 需要訪問您的網頁伺服器。請輸入 FTP 密碼繼續。」,出現這個表示Wordpress無法寫入實體檔案,所以要求你提供可寫入實體檔案的FTP帳號。

Wordpress無法更新的錯誤畫面

如果wordpress是架在自己可以管理到的Linux主機,請先確認一下wordpress資料夾下的檔案是否都有寫入權限,建議最快的解決方法就是把wordpress下的所有檔案的owner都換成執行apache的使用者,不過這個使用者名稱在各種distro並不一致,在ubuntu下是www-data。

chown -R www-data wordpress

更多訊息可以參考: Why WordPress Asks for Connection Info

OAuth簡單流程介紹

OAuth是一種是一種開放的標準協定,提供使用者在不需要提供使用者的帳號密碼給第三方網站的情況下,讓第三方網站可以存取私人資料的驗證方式。目前最多的應用就是可以利用諸如GoogleFacebookYahooTwitter新浪微博…等大網站的帳號登入自己寫的應用程式。

其實我個人是使用現成的套件Scribe免去很多麻煩,其他語言可以在這裡找到適用的API套件。雖然有套件可以使用,但是還是要稍微了解一下OAuth的簡易驗證流程與名詞,這樣寫程式的時候才不會一頭霧水。下面是大致驗證程序的筆記(如果有錯還麻煩告訴我一下):

1.到驗證網站註冊,取得一組 Consumer key跟Consumer secret
2.使用者點擊觸發
3.應用程式向驗證網站取得一組request token
4.應用程式利用這組request token組成一組Authorization Url並將使用者redirect去驗證網站
5.使用者驗證網站進行驗證
6.通過後驗證網站會redirect回一組先前設置好的callback url,並送一組access token、verifier,
7.應用程式利用這組access token及verifier向驗證網站取得使用者資料。

註1:驗證網站就是Google、Facebook等提供OAuth的網站
註2:應用程式就是要取得使用者資料的程式,也就是我們要寫的程式
註3:使用者…這個應該不用說明了吧?就是使用應用程式的人

大致上這樣就完成OAuth的步驟。希望透過這些專有名詞的介紹可以幫到想要整合的人。

Cassandra 簡易配置與啟動

Contents:

下載程式 (Downloads)

  • 可以在Apache Cassandra的下載網頁下載最新的穩定版本。這是最推薦的方式,下面其他的方法除非是Cassandra的開發人員或是發現bug必須使用最新版本才能修復時才會使用到。筆者撰稿的時候,最新版本的穩定版本0.7.0,接下來的範例也是以0.7.0版為主,此外指令系統環境預設是Ubuntu 10.10。
  • 可以到Apache Cassandra的SVN上下載最新的原始檔自行build, https://svn.apache.org/repos/asf/cassandra/trunk/
    • 或直接用SVN或git check out。
      • svn checkout https://svn.apache.org/repos/asf/cassandra/trunk cassandra
      • git clone git://git.apache.org/cassandra.git
  • 或者也可以在這裡找到 Nightly Build 版本,所謂Nightly Build版就是依據SVN上的最新程式碼每天Build出來的新版本,不過也因為程式碼都是最新的因此可能會有許多其他的問題。

簡單設置 (simple configuration)

Cassandra是利用Java所撰寫的因此在能夠運行JVM的平台就可以運行,此外根據Cassandra Wiki的說明,Cassandra必須在Java 1.6的版本才能運行推薦使用Sun JDK的 1.6 u19, u21或更新的版本。準備好JDK之後,解壓縮剛剛下載的檔案後可以修改下列檔案的設置:

  • conf/cassandra.yaml
    • 必須確認下列三個設置的目錄存在,如果不存在請手動修改該檔案或建立對應的目錄
      • data_file_directories
      • commitlog_directory
      • saved_caches_directory
    • 如果是Unix-Like的系統(如:Ubuntu Linux) 可以用下面的指令建立預設的目錄

      sudo mkdir /var/lib/cassandra
      sudo mkdir /var/lib/cassandra/data
      sudo mkdir /var/lib/cassandra/commitlog
      sudo mkdir /var/lib/cassandra/saved_caches
      sudo mkdir /var/log/cassandra

    • 如果是Windows系統,則一定要修改cassandra.yaml的內容,例如:
      • Windows cassandra settings
      • 用cmd開啟命令模式後,可以用下面的指令快速建立目錄

        mkdir datadata
        mkdir datacommitlog
        mkdir datasaved_caches
        mkdir log

  • conf/log4j.properties
    • 筆者下載的0.7.0壓縮包裡沒有這個檔案,可以將log4j-tools.properties複製到log4j.properties再加以修改。
    • 這個檔案預設的Log Level是INFO等級,如果有特殊需求可以改成更高(在log4j.rootLogger這邊)。
    • 另外log檔案的預設路徑是/var/log/cassandra/system.log。如果特殊需要也可以修改。
    • 如果是Windows的使用者的話,就一定要更改,否則log會寫不進去。

單一節點啟動(Running a single node)

啟動前須注意下面的事項:

  • 前面設置的三個路徑路徑是可以被寫入的。如果建立資料夾用sudo命令來建立時,這些資料夾的owner會是root,所以因此執行Cassandra也必須是root才可以寫入。
    • 或者下面執行的時候都用sudo使用root權限來運行。
    • 可以將上面資料夾的owner改為當前的使用者「sudo chown -Rv $(whoami) /var/lib/cassandra」

sudo chown -Rv $(whoami) /var/lib/cassandra
sudo chown -Rv $(whoami) /var/log/cassandra

  • 無法順利啟動時,請確認系統的JAVA_HOME路徑設置正確。

確認無誤後可以執行 「bin/cassandra -f」 來啟動系統(Windows系統請執行bincassandra.bat)。運行後可以利用「bin/nodetool -host <IP> ring」來查詢運行狀態。

啟動Cassandra叢集(Running a cluster)

一個Cassandra服務稱為一個節點(node),而Cassandra叢集(Cluster)即是啟動個node一起工作,node啟動時會依據seeds的設置來找到其它node,node間的溝通稱為Gossip,為了讓結點可以透過網路進行Gossip,因此也必須設置bind的網路位置。依照前面的說明與設置bind位址預設為localhost,因此只能啟動single node(單一節點)的Cassandra,但如果要啟動多個節點,則必須修改「conf/cassandra.yaml」中的設置。

  • seeds
    • 堤供node啟動時能找到其他node的服務。適合設置較為穩定的node作為seeds
  • listen_address
    • 即為Gossip使用的位址,可以用主機名稱或是用介面的IP位址,請勿使用0.0.0.0來bind所有的介面。
  • rpc_address
    • 即為Thrift,可以使用0.0.0.0來bind所有的介面。

啟動後可以用指令來查詢node的啟動狀態。

usr_name@your-hostname:~$ apache-cassandra-0.7.0/bin/nodetool -h 192.168.1.1 ring
Address         Status State   Load            Owns    Token
114370047407031585825716411201808513080
192.168.1.1 Up     Normal  17.64 KB        58.96%  44541738553819607218745010131931951155
192.168.1.2 Up     Normal  17.48 KB        41.04%  11437004740703158582571641120180851308

參考網頁

Tomcat 5 或 Tomcat 6 在Windowx x64上安裝成Windows Service服務的問題

下午在客戶那邊要把Tomcat 裝成service。一般情況是在用command line在tomcat/bin下

service.bat install

就可以安裝成服務。不過下午這樣裝,安裝成Windows服務都無法啟動,可是開Console卻很正常,在jakarta_service的log中出現下列錯誤:

[2011-01-25 16:34:24] [info] Procrun (2.0.4.0) started
[2011-01-25 16:34:24] [info] Running Service…
[2011-01-25 16:34:24] [info] Starting service…
[2011-01-25 16:34:24] [174  javajni.c] [error] 找不到指定的模組。
[2011-01-25 16:34:24] [994  prunsrv.c] [error] Failed creating java C:Javajre6binclientjvm.dll
[2011-01-25 16:34:24] [1269 prunsrv.c] [error] ServiceStart returned 1
[2011-01-25 16:34:24] [info] Run service finished.
[2011-01-25 16:34:24] [info] Procrun finished.

或是

[2011-01-25 15:58:32] [info] Procrun (2.0.4.0) started
[2011-01-25 15:58:32] [info] Running Service…
[2011-01-25 15:58:32] [info] Starting service…
[2011-01-25 15:58:32] [174  javajni.c] [error] %1 不是正確的 Win32 應用程式 。
[2011-01-25 15:58:32] [994  prunsrv.c] [error] Failed creating java C:Javajdk1.6.0_23jrebinserverjvm.dll
[2011-01-25 15:58:32] [1269 prunsrv.c] [error] ServiceStart returned 1
[2011-01-25 15:58:32] [info] Run service finished.
[2011-01-25 15:58:32] [info] Procrun finished.
[2011-01-25 15:58:50] [info] Procrun (2.0.4.0) started
[2011-01-25 15:58:50] [info] Running Service…
[2011-01-25 15:58:50] [info] Starting service…
[2011-01-25 15:58:50] [994  prunsrv.c] [error] Failed creating java
[2011-01-25 15:58:50] [1269 prunsrv.c] [error] ServiceStart returned 1
[2011-01-25 15:58:50] [info] Run service finished.
[2011-01-25 15:58:50] [info] Procrun finished.

google到的辦法都是要我重裝x64的JDK,可是這一點早就確認了。但是一直還是無法啟動。後來發現,原來我的tomcat是用zip包不是用installer,因此tomcat5.exe還有tomcat5w.exe是x86編譯的(32位元),因此要自己去tomcat的SVN上找到相對應版本的tomcat5.exe、tomcat5w.exe (或tomcat6.exe tomcat6w.exe)。

tomcat的SVN在這: http://svn.apache.org/viewvc/tomcat/

例如我下載5.5.27版的就在這:  http://svn.apache.org/viewvc/tomcat/tc5.5.x/tags/TOMCAT_5_5_27/connectors/procrun/bin/amd64/

但是Stack Overflow裡面tomcat6的路徑是放在: http://svn.apache.org/viewvc/tomcat/tc6.0.x/tags/TOMCAT_6_0_16/res/procrun/amd64/

結構有點不大一樣,總之先到這找到適用的版本,然後找到procrun這個目錄,然後再找amd64 (也就是x64)的版本,下載完後將原本的exe覆蓋。然後再重新安裝service就可以了。

參考:

How to run Tomcat 6 on WinXP 64 bit ? – Stack Overflow

[memo] Ubuntu Linux改Timezone的方式

在ec2上開ubuntu大多是UTC,雖然server是在外國,可是習慣上還是改回台灣的時區比較不會誤會。改時區實在無敵簡單的,基本上就是去/usr/share/zoneinfo裡面找到適當的時區,然後在製作軟連結到/etc/localtime就可以了。下面這個,是台灣時區的下法。

ln -sf /usr/share/zoneinfo/Asia/Taipei /etc/localtime