星期五, 12月 25, 2015

Jenkins + Central Authentication Service, CAS

在 Windows 伺服器上的 Jenkins 要由 https://abc.com/cas 單一簽入的做法:
  1. 取得 https://abc.com 憑證簽署單位的憑證,假設檔名為 StartCom.crt。
  2. 以系統管理員身分在 Jenkins 安裝目錄下命令:jre\bin\keytool.exe -keystore jre\lib\security\cacerts -import -trustcacerts -file StartCom.crt -alias StartCom。
  3. 在 Jenkins 安裝 CAS Plugin,並設定 Security Realm CAS 的 URL、Protocol。

星期二, 12月 15, 2015

CentOS 6 as a Selenium node with Chrome

過去已有 Windows 當 Selenium (web driver) node 的經驗,原本以為換到 Linux 是件很簡單的事,不過實際試著做下來,才知若是 Firefox 還好,Chrome 就很麻煩了:
  1. 若 CentOS 6 還沒有 GUI,要下指令安裝:yum groupinstall "X Window System" "GNOME Desktop Environment" "Desktop" "Chinese Support"。
  2. 若要從遠端操控 CentOS 6 的圖形介面,可以用 VNC。在 CentOS 6 安裝 VNC Server,執行 vncserver :1,用 vncpasswd 命令設遠端連線密碼。從 Mac 連過去甚至 VNC Viewer 都不用裝,在 Safari 瀏覽 vnc://hostname:5901 就可以了。
  3. 在 CentOS 6 安裝 Chrome 已不被 Google 原廠支援,幸好還有位大師指導
  4. 不像 Firefox,所有其他的瀏覽器都需要 Driver 才能與 Selenium hub 溝通,所以要另外下載。所謂「安裝」就是把下載的檔案放在 PATH 所指的路徑即可。
  5. 以上都做了,結果還是不通?可以直接在終端機執行 chromedriver 看是什麼問題,原來還是 libstdc++.so.6 惹的禍。經過上述大師的修正,應該會有兩個以上,可以透過「find / -name libstdc++.so.6」來確認,而且每一個的差異可透過「strings <PATH>/libstdc++.so.6 | grep GLIBC」識別,換另一個版本的也許就好了。
[2016/09/10 補充]
  • CentOS 7 安裝各種 GUI 的說明可參考這篇
  • Chrome 有自動更新的機制,每次事後都要把 /usr/lib64 目錄下的 libstdc++.so.6 指到 /opt/google/chrome/lib 去,否則就是找不到 Chrome Web Driver 的錯誤。

星期六, 12月 12, 2015

Convert .bat to .sh

有一行很簡單的命令:

java -jar a.jar fileB

以上就是 c.bat 批次檔的內容,與 a.jar、fileB 都在同一目錄下,在 Windows 的環境沒問題。既然 Java 是跨平台的,想必可移到 Linux / Mac 的指令稿,但一直不行?也確定這行直接放在終端機跑過沒問題,只是不能從 c.sh 間接地執行。除了 chmod +x 還有別的事要做?後來改成這樣:

#!/bin/bash
java -jar a.jar fileB

結果在 Mac 上是出現這個訊息:

-bash: ./c.sh: /bin/bash^M: bad interpreter: No such file or directory

半信半疑,加了到底是有幫助還是把事情搞得更複雜?幸好看到這篇,在 vi 編輯 c.sh 下兩道指令:

:set ff=unix
:x

終於修好了!

星期三, 12月 09, 2015

C# 對民國年的處理

最近看到很多人自成一格的處理民國年,很醜的就不提了,有的猛一看還不錯:

private string FormatDate0(DateTime dateTime)
{
return dateTime.AddYears(-1911).ToString("yyy/MM/dd");
}

以今天為例,結果是 104/12/09,看來沒問題?但試試 FormatDate0(new Date(2016, 2, 29)) => 105/02/28,知道不行了吧?改進如下:

private string FormatDate1(DateTime dateTime)
{
string returnValue = null;
Calendar taiwanCalendar = new TaiwanCalendar();
int year = taiwanCalendar.GetYear(dateTime);
int month = taiwanCalendar.GetMonth(dateTime);
int day = taiwanCalendar.GetDayOfMonth(dateTime);
returnValue = String.Format("{0:000}/{1:00}/{2:00}", year, month, day);
return returnValue;
}

雖然有點長,但感覺是用比較「正統」的方式在處理。如果真要挑毛病的話,就是年月日必須分開處理,難道沒辦法保留在一起嗎?有人介紹了以下這種:

[SecurityPermission(SecurityAction.Assert, ControlThread = true)]
private string FormatDate2(DateTime dateTime)
{
string returnValue = null;
CultureInfo taiwanCulture = new CultureInfo("zh-TW");
DateTimeFormatInfo formatInfo = taiwanCulture.DateTimeFormat;
Calendar taiwanCalendar = new TaiwanCalendar();
formatInfo.Calendar = taiwanCalendar;
Thread currentThread = Thread.CurrentThread;
currentThread.CurrentCulture = taiwanCulture;
returnValue = dateTime.ToString("yyy/MM/dd");
return returnValue;
}

真的是複雜但優雅!但別急著高興,先不論 SecurityPermission 帶來的一絲不安,有個測試案例結果不太妙,FormatDate2(new Date(2010, 1, 23)) => 99/01/23,開頭的零跑哪去了?怎麼看都是微軟的問題,自力救濟吧:

...
// bugfix begin
//returnValue = dateTime.ToString("yyy/MM/dd");
int year = taiwanCalendar.GetYear(dateTime);
returnValue = String.Format("{0:000}", year);
returnValue += dateTime.ToString("/MM/dd");
// bugfix end
return returnValue;
}

有些畫蛇添足的感覺,看得真不舒服。

星期四, 11月 26, 2015

jQuery 民國年小日曆

別再自己搞,這種一定早就有人處理過了不是嗎?但有點不容易弄清楚。首先由這個網站開始,下載之後打開一個名為 calendarsPickerBasic.html 的網頁來玩玩看,預設是回曆,要改成民國年的話就必須增加這一行
  • <script src="jquery.calendars.taiwan.js"></script>
再修改這一行
  • //var calendar = $.calendars.instance('persian');
  • var calendar = $.calendars.instance('taiwan');
如此而已。但如果還要同時以正體中文顯示月份、星期的名稱,必須再增加一行
  • <script src="jquery.calendars.taiwan-zh-TW.js"></script>
剛改過的那一行也要進一步再改成
  • //var calendar = $.calendars.instance('persian');
  • var calendar = $.calendars.instance('taiwan', 'zh-TW');
關鍵應該是「紀年」與「語言」是可以分開處理的,同理,顯示的樣式也是。

星期三, 11月 25, 2015

透過 NLog 寫入資料庫

log4net 已經不流行了,NLog 取而代之,基本概念是 Rule 決定要記什麼,而 Target 決定要記到哪去。基本的使用,只要安裝一個 NLog.Config NuGet 套件,再把範本設定檔的註解打開,使用端的程式寫一寫就好了。進一步若要往資料庫送可以參考這篇(雖然不一定是什麼好主意),除了許多內容可以選擇之外,若還要自訂一些欄位的話可以參考這篇

以 C# 程式產生 Word 檔案

原本直覺是用 NPOI,但實際動手才發現還真不好做。另外有一個 Open XML SDK for Microsoft Office,似乎比較有希望,NPOI 還是專門對付 Excel 就好了。

星期五, 11月 13, 2015

又差點被一個 VirtualBox Image 搞瘋

從某個知名網站抓 VirtualBox 映像檔,CentOS 5.6 x86_64 的鍵盤都亂了,看似歐洲出品,但 locale 都是 en_US?答案在 /etc/sysconfig/keyboard:
  • KEYBOARDTYPE="pc"
  • KEYTABLE="it"
讓 IT 下班就沒事了!

[2015/12/12 補充]
有一種類似的狀況是只有單、雙引號要連按鍵兩次才會出現,而且長相有些奇特,依這篇的說法下指令解救:

setxkbmap -layout us

星期三, 11月 11, 2015

Windows 指令服務化-搭配自動重啟

為了這個目標,原先還蠻高興找到一個官方的 SC.exe 工具,但總是失敗在服務無法啟動。後來才了解到,在 Windows 的世界,可不是一般的程式都可以「服務化」的。好在有善心人士開發了得獎程式,以 Wrapper 的原理讓普通程式都能服務化,真是感謝!這套工具的使用步驟也非常容易:
  • 下載
  • 安裝(其實就是複製幾個執行檔、動態連結函式庫到系統目錄)
  • 撰寫組態設定(可參考快速上手
  • 執行服務註冊(srvstart.exe install MY_SERVICE -c C:\SRVSTART\SRVSTART.INI,大寫處都要依實際狀況調整)
在確認服務可以啟動之後,若也想要掛了之後可以自動重啟,搭配服務本身的設定(還細分為第一、二次、後續的失敗)即可。

[2016/11/29]
看來這個更好用。

星期二, 11月 10, 2015

CentOS 6 指令服務化-搭配自動重啟

使用者抱怨有個常駐型的程式「經常」會自動消失,事實上是有拋出例外,只不過那在標準輸出/錯誤,又沒有重導留下紀錄,所以結果是一定要等有人覺得不對勁,去檢查才知道程式掛了,再重啟來補救。
因為底層很多元件原廠都不再支援,再維護下去也是枉然,所以老闆指示要快速「緩解」,不求根治。找了半天資料,還考慮過 Nagios,後來發現這種事在 Linux 根本是小事一椿:respawn。
這種自動復活的技巧已經發展了三代(參考資料),CentOS 6 是第二代的 Upstart。請在 /etc/init 目錄下新建一個類似 myJob.conf 的檔案,內容框架如下:
  • start on runlevel [2345]
  • stop on shutdown
  • respawn
  • exec your-command args
為了保險起見,我用 Java 寫了一個小程式,輸入參數為延遲秒數,時間到了之後就故意拋個例外出來,也終止程式。通常這種都會開個 console 來跑,但拿掉之後不就非常像上述的症狀?設成開機後自動執行不就更像了?改用上述的啟動方式,可以到 /var/log/messages 取得證明,果真是一再重覆「掛了」又「復活」的戲碼。

星期二, 10月 20, 2015

星期四, 10月 08, 2015

Docker Container without ps / yum / rpm command?

在我抓了一個官方的 HAProxy 來練 Docker 時,很奇怪的是用這招進去:
  • docker exec -it myContainerName bash
之後想下幾個常用命令都不行?一度懷疑是要用什麼別招進去,但最後證明是一連串的誤會:
  • 在 Linux 管理套件有兩大主流,Debian / Red Hat,在企業應用的訓練之下一直都著重後者,忘了前者才是個人使用的最愛。HAProxy 是 Debian 系的,所以沒有 yum / rpm 是正常的,試 apt-get / dpkg 就有了(參考資料)。
  • 如何得知我在使用中的 Linux 是屬於什麼發行套件?指令 cat /etc/*-release(參考資料)。
  • Docker 化的 Debian GNU/Linux 7 (wheezy) 天生就漏了 ps 命令?但這麼多人會遇到的問題也不必煩惱的(參考資料)。

星期五, 10月 02, 2015

El Capitan

  • 字變漂亮了
  • VPN 不再一直斷
  • VirtualBox 4.x 必須升級至 5.x
  • Secure Empty Trash 功能已被移除
  • Notes 舊資料會不見,請先備份或事後補救

星期五, 9月 25, 2015

認識 Docker + HAProxy (Software Load Balancing)

首先當然要裝好 Docker,再來是準備一台以上的 WebServer,以 Nginx 為例:
  • docker run --name nginx1 -d -p 8081:80 nginx
  • docker run --name nginx2 -d -p 8082:80 nginx
其中 -p 是表示將 Docker Host 的埠對應到 container 裏,所以在 Docker Host 上的 http://localhost:8081、http://localhost:8082 就會分別導到 nginx1、nginx2 的 80 埠,可以檢查一下是否能看到 Nginx 預設的首頁。

為了要知道這些 WebServer 的位址,可以下指令:
  • docker inspect nginx1 | grep IPAddress
  • docker inspect nginx2 | grep IPAddress
假設得到的結果是 nginx1: 172.17.0.1;nginx2: 172.17.0.2。接下來準備 HAProxy,因為官網說「沒有兩個人的設定一樣」,所以他們索性就不放一個入門級的設定範例了。沒關係,自己寫一個:
  • listen balanceGroup1 :80
    • server nginx1 172.17.0.1:80
    • server nginx2 172.17.0.2:80
  • listen stats :1936
    • mode http
    • stats enable
    • stats uri /
以上內容存檔在 /var/docker/haproxy.cfg,接著是重點:
  • docker run --name haproxy1 -d -p 80:80 -p 1936:1936 -v /var/docker:/usr/local/etc/haproxy:Z haproxy
如此就可以在 Docker Host 上訪問 localhost(會輪流導向 nginx1、nginx2),也可以在 localhost:1936 監控。因為瀏覽器的快取做得好,有時候反而不利於觀察 HAProxy 的行為,可以改用 curl 命令列工具。

[2018/05/12]
事隔多年,設定檔必須小改以符合新版的規定,如原先:
  • listen balanceGroup1 :80
要拆成兩行
  • listen balanceGroup1
    • bind :80
[2018/08/31]
服務與監控使用同一個埠似乎比較簡潔,就是整併上述 listen stats 段落,改為:
  • listen balanceGroup1
    • mode http
    • bind :80
    • stats enable
    • stats uri /admin?stats
    • server nginx1 172.17.0.1:80
    • server nginx2 172.17.0.2:80

星期一, 9月 21, 2015

修正 CentOS 7 所在時區(以台北為例)

  • sudo ln -fs /usr/share/zoneinfo/Asia/Taipei /etc/localtime
[2016/04/07] 遇到一部主機怎麼設時間都不對?原來是 CentOS7 Minimal Distribution 的問題,這篇有些指令可以參考,解決之道是安裝設定 nptd,大部份參考這篇

[2016/11/16] Ubuntu 的互動式指令:
  • dpkg-reconfigure tzdata

星期一, 9月 14, 2015

IntroduceInstabilityByIgnoringProtectedModeSettings

過去在 Selenium RC + IE 的測試時,發現如果 IE 各個安全區域沒有一致的「受保護模式」設定,瀏覽器都會開不起來,必須設定標題屬性的值為真才行。最近搬上 Selenium Grid,發現這招不行了?深究之下,才知以前的那招實在是不太好,還是乖乖地將每個安全區域的「受保護模式」設成一樣,都同時是「啟用」似乎比較好。詳情可參考這篇

Selenium Grid on Jenkins

  • Selenium Grid Hub (Jenkins)
    • 安裝 Plugin
    • 設定埠(含防火牆)
  • Selenium Node (Linux or Windows or ...)
    • 安裝瀏覽器
    • 安裝 WebDriver(在執行路徑)
    • 安裝 Java + Selenium Server JAR、啟動
    • 設定埠(含防火牆)
    • 設定 json 格式的組態
    • 如果是 IE,可能還需要參考這篇這篇

星期四, 9月 10, 2015

SELinux 讓 CentOS 7 上的 Docker 跟別人不一樣?

很多介紹 Docker 的文章都是說 sudo service docker start 即可啟動服務,但在 CentOS 7 上卻必須用 su - 加上留一個 Terminal 給 docker -d,否則後續每個 docker run 的結果都是 Exited?理由就在 CentOS 7 預設的 SELinux,看來關掉比較方便(但又不太安全?),組態管理在 /etc/sysconfig/selinux 這個檔案設定,或可用 getenforce / setenforce 命令短期控制。

[2015/09/18]
有問題的不見得是 docker 或 SELinux,別人提供的 image 也可能是原因。像我原本搭配一個 sameersbn/redis 測試,必須關閉 SELinux 或用 su - / docker -d 這招,但後來測試官方的 redis image 卻沒有這個問題,看來以後還得好好地研究 dockerfile 才行。
[2016/03/19]
在試 HAProxy 的過程中,排除了 SELinux 還是不行?從這篇回答學到,還可以在最後加上「 tail -f /dev/null」。
參考來源:How can I use docker without sudo? C6.5 與 C7 的一些差異與 systemctl 的介紹

星期二, 9月 08, 2015

解決 Mac Terminal SSH 到 Linux 時的第一個錯誤訊息

錯誤訊息:-bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): 沒有此一檔案或目錄

解決之道:參考這篇文章

拖了幾個月的挑戰

Linux 硬碟空間加大,參考這篇,總算成功。
後記:第二次本以為是駕輕就熟,沒想到竟然踢到鐵板。先是空間已完全用盡,有些指令是無法執行的;再來掛在 resize2fs,得到 Bad magic number in super-block while trying to open...,還好又找到這篇救了我。

星期五, 8月 21, 2015

還會想用是非不分的 IE 嗎?

據說升級 IE 11 之後會有些問題,但設定「相容性檢視」可以解決。驚人內幕是:舊程式的錯誤會被舊的 IE 掩飾,新的 IE 雖然回歸正道,但卻被污名化,下圖是一段證據,在 IE 11 會顯示正確的「not found」,但開啟相容性檢視或降至 IE 8 卻會顯示錯誤的「found」。

用 JavaScript 取得 IE 的版本號

function getIeVersion() {
    var returnValue = 0;
    var userAgent = window.navigator.userAgent;
    if (/rv:11.0/.test(userAgent)) {
        returnValue = 11;
    }
    else {
        var matching = /MSIE \d+/.exec(userAgent);
        try {
            returnValue = parseInt(matching[0].substring(5));
        }
        catch (exception) {
        }
    }
    return returnValue;
}

nginx 試用

為了一個案子查問題需要幾個靜態網頁放在伺服器上,抓了 nginx for Windows 來用,還真小,解壓縮後也不到 4MB。紀錄幾點重要事項:
  • 靜態網頁都放在 html 目錄下,預設首頁是 index.html。
  • 若要修改埠號,在 conf/nginx.conf 很容易找到。
  • 根目錄就有一個 nginx.exe,點兩下執行即可啟動。
  • 預設就有紀錄,都在 logs 目錄內。

星期五, 8月 07, 2015

bitnami.com GitLab on CentOS

這個裝在虛擬機上的,只有一位使用者的版控,卻經常有使用者反映不能 Push,錯誤訊息是「non-fast forward」,意思是「有別人的 Push 沒有 Pull 下來,又想把自己的 Commit 給 Push 上去」,哪來的「別人」?
研究了半天,果真如此,有圖為證:
原來從 bitnami.com 抓來的 GitLab 有個隱形使用者,即使是相同的帳號,透過 GitEye 的是 centos,透過 GitLab Web UI 上來的是 Administrator,這是「兩個不同的人」,但在 GitLab 管理介面列所有使用者,又只有 Administrator 一人而已。
雖然我們管不到 centos 這個人,不過有辦法讓他們合一:找到 centos 的電子郵件帳號,設成 Administrator 的第二個電子郵件帳號。

星期二, 6月 30, 2015

Java Web Start - ArrayIndexOutOfBoundException: 8

最近一連檢查到三部主機(Windows Server 2008 R2 64 bit)都有同樣的問題:首先是因為要裝 Jenkins Slave (JNLP),不是最新版 JRE 會有問題,所以升級到 Version 8 Update 45。升級後有的是在跑 JNLP 時出錯,有的更糟,在驗證 Java 安裝版本就不行了,錯誤都如標題,取代了我們期望的 Applet 簽署說明。





























首先,不論 IE 版本(8~11)為何,一律恢復原廠設定,再關閉 Server 上瀏覽器的增強式安全性設定 ESC;接著奇怪的解法來了(在 IE 設定):
  • 網際網路選項
  • 連線
  • LAN 設定
  • 自動設定
  • 自動偵測設定<-勾選
為何瀏覽器的代理伺服器設定這麼重要?因為 Java Console 的網路設定預設「依瀏覽器設定」,而 JNLP 或 Applet 的下載都是透過 Java Console 設定控制,這也提示了另一種解法,直接修改 Java Console 的網路設定。
至於 IE 的代理伺服器「自動偵測設定」為何沒有勾選?還不清楚。因為重新安裝了幾次乾淨虛擬機,或升級新版瀏覽器,或恢復出廠預設值,這裏總是在已勾選狀態的。

星期五, 6月 12, 2015

權限太多也不行?

要以 A 主機的使用者 u1 透過 SSH 連到 B 主機的使用者 u2 身分,有兩種方式:
  • login as u1 on A, ssh u2@B, password required.
  • login as u1 on A, generate key pair, save [A] /home/u1/.ssh/id_rsa.pub to [B] /home/u2/.ssh/authorized_keys, ssh u2@B, password NOT required.
但好玩的來了:如果 /home/u2/.ssh 的權限是 700 或 755 都可以免密碼,但 777 就不行了?如果 /home/u2/.ssh/authorized_keys 的權限是 400 或 700 也都可以免密碼,但 777 又不行?

星期四, 5月 28, 2015

Mac 上不了 5G 的 Wi-Fi?

因為公司的無線投影一定要上 5G 的 Wi-Fi,而我的 Mac 根本就掃不到那個基地台,困擾了好一陣子,今天終於下定決心要弄出來。爬了幾篇文,原來還有個「會隨時改變的國碼」?主要先參考這篇得知 Wi-Fi 的型號,再依這篇把國碼設到 X2,以免被各國的設備拉來拉去的,注意要先關閉 Wi-Fi ,等設好後重啟電腦再開 Wi-Fi,大功告成。
如果真實的國家界限也是這麼鬆散的,就世界大同?

錯誤的主機名稱解析拖慢網頁

有一個本機網頁要等很久,查了半天才知內含問題連結,只要主機名稱是
  • platform.linkedin.com
  • platform.twitter.com
的資源,都要等幾十秒才會逾時放棄。現在的解法,在 /etc/hosts 加上:
  • 127.0.0.1    platform.linkedin.com
  • 127.0.0.1    platform.twitter.com
大概縮短到一秒內就放棄了,所以會快很多。

ifup / ifdown not working?

在 Linux 執行以下的指令
  • ifconfig
藉由回應得知網路卡的名稱
  • eth0...
接著需要重啟該網路卡,以便套用新設定,其中一個指令為:
  • ifdown eth0
結果卻得到這樣的回應
  • usage: ifdown <device name>
原來用了多年的指令竟然改了?印象中在 Linux 的世界還是頭一遭,新的指令是:
  • ip link set eth0 down

星期日, 5月 17, 2015

在 CentOS 6 編譯 .NET 的程式

  1. 用 Mono,不要期待 Wine,一個一個套件再補太辛苦了。
  2. Mono 也不喜歡 CentOS,明明在 Ubuntu 或 Mint 都那麼好裝。但就算是 EPEL 都請出來,還是找不到 mono-complete,所以改這樣「yum install mono\*」,凡是 mono 開頭的套件都裝下去。
  3. 如此一來有了 xbuild.exe,但不被認可為執行檔,請將這句指令放在開機後自動執行:「echo ':CLR:M::MZ::/usr/bin/mono:' > /proc/sys/fs/binfmt_misc/register」。

星期五, 5月 08, 2015

Derby 資料庫的簡單瀏覽方法

不像輕量級的 SQLite 一個資料庫就是一個檔案,稍「重」些的 Derby 一個資料庫是一個目錄(假設在 /home/myName/myDb),可以使用 JDK 內建的工具 ij 下指令存取:
  • cd /home/myName
  • <JDK_HOME>/db/bin/ij
  • connect 'jdbc:derby:myDb;user=me;password=secret';
  • show tables;
  • describe <TableName>;
  • select * from <TableName>;
  • exit;

星期四, 4月 23, 2015

詹金斯要喝酒

因為 Wine 的使用者身分很難調,但在 Jenkins 上要透過它來執行 Windows 平台的程式,研究了半天,最後決定這個比較容易的辦法:將 Jenkins 執行的使用者從 jenkins 換成登入 Linux 安裝 Wine 的那個使用者,做法可以參考這篇

在 CentOS 6 (32 bit) 安裝 Stable Wine 1.6.2

大致上可參考這篇,裝完之後可以用,不過有很多類似 "PNG support is not compiled in" 的錯誤訊息。若要解決這個問題,有兩個步驟:
  • sudo yum -y install libpng-devel
  • vim /tmp/wine-1.6.2/tools/wineinstall
    • CONFARGS="" -> CONFARGS="--with-png"

星期三, 4月 22, 2015

VirtualBox Host 之下的多個 Guest 網路互聯

  1. 關閉 VirtualBox 應用程式。
  2. 自訂 Host 本身的網路位址,例 10.1.2.3。
  3. 預計多個 Guest 所共存的網路名稱叫 intnet,位址範圍在 10.1.2.10 ~ 10.1.2.20。
  4. 指令:vboxmanage dhcpserver add -netname intnet -ip 10.1.2.3 -netmask 255.255.255.0 -lowerip 10.1.2.10 -upperip 10.1.2.20 -enable。
  5. 查詢:vboxmanage list dhcpservers。
  6. 開啟 VirtualBox 應用程式。
  7. 針對需要互聯的 Guest 都增加 internal network 網路介面,名稱叫 intnet。
  8. 開啟各 Guest。

星期二, 4月 21, 2015

bitnami.com 救了我

花了好幾天才研究出如何安裝成功的 GitLab 竟然有個重要功能失效,放棄了!幸好有別人找到這個網站。

星期一, 4月 20, 2015

讓 CentOS 6 登入畫面不要出現那麼多帳號

在裝了某個軟體之後,因為建了許多帳號,一個個系統使用者都出現在登入畫面上了。後來是參考這篇來解決,雖然是 Ubuntu 的論壇。

星期六, 4月 18, 2015

困而學之

Ruby? Rails? 這兩個我不懂也不想懂,反正能正常運作就是了。但遇到 GitLab 那個很難打的預設密碼「好像」被我自己改壞掉,不得不想辦法重置的時候,幸好參考這一篇的內容救了回來。
糟糕!我好像常這樣。論語是這麼說的:

生而知之者上也;學而知之者次也;困而學之又其次也;困而不學,民斯為下矣。

GitLab 開機後自動執行

因為 32 位元的 GitLab 沒有安裝套件,一切都得自己來。在奮鬥許久後,終於新建了一個使用者 gitlab,抓完原始碼放在家目錄下的 gitlabhq,建置安裝完成。啟動的指令如下:
  • sudo /etc/rc.d/init.d/mysqld start
  • sudo /etc/rc.d/init.d/redis start
  • cd && cd gitlabhq && bundle exec rails s -e production
想要開機後自動執行,可以將指令放在 /etc/rc.d/rc.local 這個檔案,大致需要以下這些:
  • # exec >/var/log/rc.local.log 2>&1
  • /etc/rc.d/init.d/mysqld start
  • /etc/rc.d/init.d/redis start
  • PATH=$PATH:/usr/local/bin
  • cd /home/gitlab/gitlabhq && bundle exec rails s -e production &
部份需要改變的原因是執行身分不同、路徑不同、環境變數不同,還有背景執行。如果需要偵錯,也可以打開被註解的那一行。

星期五, 4月 17, 2015

Install GitLab on CentOS 6 32bit

GitLab 只提供 64 位元的安裝套件,沒想到在 32 位元的環境這麼難裝,基本上參考一篇快滿三年的文章,再修改一些步驟以解決問題,紀錄一下:

# add current user to sudoers

# www connected

sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

sudo sed -i "s/mirrorlist=https/mirrorlist=http/" /etc/yum.repos.d/epel.repo

sudo yum -y groupinstall 'Development Tools' 'Additional Development'

sudo yum -y install readline readline-devel ncurses-devel gdbm-devel
glibc-devel tcl-devel openssl-devel curl-devel expat-devel db4-devel
byacc gitolite sqlite-devel gcc-c++ libyaml libyaml-devel libffi
libffi-devel libxml2 libxml2-devel libxslt libxslt-devel libicu
libicu-devel system-config-firewall-tui python-devel redis

curl -O http://ftp.ruby-lang.org/pub/ruby/2.2/ruby-2.2.2.tar.gz

tar xzvf ruby-2.2.2.tar.gz

cd ruby-2.2.2

./configure --enable-shared --disable-pthread

sudo make && sudo make install

sudo yum -y install qt-devel qtwebkit-devel

export PATH=$PATH:/usr/lib/qt4/bin

alias sudo="sudo env PATH=$PATH"

sudo gem update --system

sudo gem update

sudo gem install rails

sudo adduser --shell /bin/bash --create-home --home-dir /home/gitlab gitlab

sudo passwd gitlab

su gitlab

ssh-keygen -t rsa

# keep default filename, empty for no passphrase

exit

sudo adduser --system --shell /bin/sh --comment 'gitolite'
--create-home --home-dir /home/git git

sudo cp /home/gitlab/.ssh/id_rsa.pub /home/git/gitlab.pub

sudo passwd git

su git

gl-setup ~/gitlab.pub

# When the prompt appears edit the provided file (it's in a vi-Editor)
and set $REPO_UMASK to 0007

exit

sudo usermod -a -G git gitlab

sudo chmod -R g+rwX /home/git/repositories/

sudo chmod 770 /home/git

sudo service sshd start

su gitlab

ssh git@localhost

exit

exit

su -

curl https://bootstrap.pypa.io/ez_setup.py | python

exit

sudo easy_install pip

sudo pip install pygments

sudo gem install bundler

sudo visudo

# add: gitlab    ALL=(ALL)    ALL

sudo gem install charlock_holmes

sudo yum -y install cmake

sudo gem install rugged -v '0.21.4'

su gitlab

cd && git clone https://github.com/gitlabhq/gitlabhq.git

cd gitlabhq

bundle install

sudo yum -y install mysql-server

sudo yum -y install nodejs

sudo /etc/init.d/mysqld start

mysql_secure_installation

mysql -u root -p

mysql> CREATE DATABASE gitlab CHARACTER SET UTF8;

mysql> GRANT ALL PRIVILEGES ON gitlab.* TO 'gitlabusr'@'localhost'
IDENTIFIED BY 'supersecret' WITH GRANT OPTION;

mysql> quit

sudo nohup redis-server > /dev/null

# hit CTRL+Z

bg

cp ~/gitlabhq/config/database.yml.mysql ~/gitlabhq/config/database.yml

cp ~/gitlabhq/config/gitlab.yml.example ~/gitlabhq/config/gitlab.yml

vim ~/gitlabhq/config/database.yml

# In database.yml you have to edit the production settings of your
database (at the very top of the file). You have to change the
database-name, username and password.

RAILS_ENV=production rake db:setup

RAILS_ENV=production rake db:seed_fu

bundle exec rails s -e production

# visit http://localhost:3000 with root / 5iveL!fe

以上。日後要啟動 GitLab 服務的步驟也整理在此:

# Terminal #1

sudo /etc/rc.d/init.d/mysqld start

redis-server

# Terminal #2

su gitlab

cd

cd gitlabhq

bundle exec rails s -e production

星期四, 4月 16, 2015

VirtualBox Guest Additions on CentOS 6

看了很多篇文章,最正確完整的是這篇。唯一的一個小問題,如果在裝完 epel 6 rpm 之後的 yum install 出現 Cannot retrieve metalink 的錯誤,要多跑這個指令:
  • sudo sed -i "s/mirrorlist=https/mirrorlist=http/" /etc/yum.repos.d/epel.repo
之後如果要掛載共享目錄,比來比去還是我的一篇舊聞算不錯,即使當初設定的題目似乎沒有涵蓋,但仍然適用。

[2015/06/29] 若是由 osboxes.org 抓的 CentOS 7 image,步驟可以少很多,符合這篇文章 4.2.2.1.6 小節的描述,基本上只要:
  • sudo yum update -y
  • sudo yum install -y gcc kernel-devel
  • reboot
  • install Guest Additions
  • reboot
就可以安裝成功了。

星期一, 4月 13, 2015

CentOS 6.3 + Jenkins + Git

由於 CentOS 6.3 內建的 Git 較舊,在最近的 Jenkins 版本使用了新功能(git config --local)會導致錯誤,必須先升級

星期五, 3月 27, 2015

判別 .NET dll「能在哪用」

安裝 .NET Framework SDK 後,有個名叫 corflags.exe 的命令列程式能列出(甚至修改)類似以下的結果:
  • PE: PE32
  • ILONLY: 1
  • 32BIT: 1
解讀也是需要點技巧的:
  • anycpu: PE = PE32 / 32BIT = 0
  • x86: PE = PE32 / 32BIT = 1
  • x64: PE = PE32+ / 32BIT = 0
主要參考這篇文章

星期一, 3月 23, 2015

PostgreSQL 接受遠端連入

這真的是很淺的問題,但沒有經驗就是能卡很久。pg_hba.conf 要修改,加上紅字的部份範例如下:
  • host all all 127.0.0.1/32 md5
  • host all all 172.16.0.1/16 md5

星期五, 3月 13, 2015

增加機碼的副作用一例

使用 SmartPackager 錄製任務前後的快照相比,得知新增「近端區域網路」會異動兩種看似重複的機碼:
  • HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\contoso.com\www
    • http (REG_DWORD: 1)
  • HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMapKey
    • http://www.contoso.com (REG_SZ: 1)
後者是不需要的,而且若留著會有嚴重的副作用:鎖住使用者手動編輯的功能。

用機碼新增近端區域的網站,擋我者死?

需求是:內部使用者都要在「政府組態基準」環境,上一個新的網路應用程式(假設在 http(s)://www.contoso.com)工作,而且必須用到一個已簽署、安全的 ActiveX,所以重點是 IE 要知道這不是網際網路區域,而是「近端內部網路」。

(錯的)做法:在每部電腦上增加以下機碼
  • HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\contoso.com\www
    • http (REG_DWORD: 1)
    • https (REG_DWORD: 1)
表面上這是可以達成需求的,但使用者實際測試後反映,他們原先各自設了一些屬於近端內部網路的位址都不見了!所以這個太過霸道的作法並不可行。後來研究的結果,把紅字部份刪掉,這個新的機碼位置就既可以增加新位址,又保留個人設定。

一段後話:透過瀏覽器的設定,使用者並不會看到 http(s)://www.contoso.com,所以變成有點難判別他是否做過了這件事。

已簽署的 ActiveX 未出現下載安裝提示

整理目前遇過的幾種可能與解決方法:
  • 已在瀏覽器的「管理附加元件」清單,但被停用或限制在特定的網站才能使用。
  • 瀏覽器設定被改過,可以全部恢復成預設值、重啟電腦來解決。
  • 使用者帳戶控制(UAC)被關閉,可以恢復成預設值、重啟電腦來解決。
  • 部署在近端(例如 http://machineName/index.html),也啟用了預設是關閉的近端區域,雖然不會提示,但是會直接下載安裝。
  • 相同的程式名稱與 Class GUID 已註冊,可以用這兩種搜尋條件分別找一次,刪去相關的機碼。
  • 在 Windows Server 等級的作業系統,瀏覽器與一般不同,雖是能調整,但應該想想這種環境本來就不太對。

製作 *.msi 安裝執行檔

為了「安裝」這件事,過去常用 NSIS 將檔案、指令包成 *.exe,目的是能達成,但有點陽春。最近被逼著要 *.msi,主要是為了兩個好處:派送、反安裝。
搭配的工具是 Smart Packager,用法大致是:錄下安裝的所有工作(複製檔案到定點、執行批次檔、編輯群組原則或註冊機碼等),再過濾掉一些雜訊,測試,存成 msi。
光是這樣給使用者還不夠,因為「發行者不明」,可以用 signtool 外覆一個數位簽署。

星期二, 3月 10, 2015

已簽署的 ActiveX 出現怪異的資訊列提示

這可說是我測試過這麼多 ActiveX 下載、安裝、啟用過程中最討厭,也是最搞不懂的結果了。如今終於確認其中一種(不敢說是唯一)成因,有幾個要件:
  • InstallScope = machine
  • 檔案所在目錄的賦予某些人的權限不足,例如 User1: RW, User2: RO, User3: None。權限不足的使用者就會看到這個資訊列提示。
  • 註冊機碼沒有問題

星期四, 3月 05, 2015

當網際網路區域已簽署的 ActiveX 遇上政府組態基準(GCB)

簡單來說,即使是已簽署的 ActiveX 控制項,只要遇上套用「政府組態基準」的電腦,就無法下載安裝執行。在此將整個測試環境與解決步驟列出來:
  • 安裝 Windows 7,內建的瀏覽器是 IE 8。這是目前「政府組態基準」唯一允許的用戶端電腦環境。
  • 在網管眼中,要讓多部電腦套用「政府組態基準」,應該透過群組原則派送比較有效率,但這裏只是做驗證,所以能改到一部電腦上就夠了。請到行政院國家資通安全會報技術中心下載「LocalGPO 安裝程式」(工具)、「政府組態基準內容」(規則集,分別針對作業系統、防火牆、瀏覽器)。
  • 把 LocalGPO 安裝好,用系統管理權限執行,會出現命令列視窗。
  • 政府組態基準內容共有七個以 GUID 為名的目錄,在上述命令列視窗逐一執行 cscript LocalGPO.wsf /Path:"<PATH_TO_GUID>"。
  • 重啟電腦,此時便完成「政府組態基準」的套用。
  • 以系統管理身分登入,執行 gpedit.msc 群組原則編輯,找到 Computer Configuration -> Administrative Templates -> Windows Components -> Internet Explorer -> Internet Control Panel -> Security Page -> Site to Zone Assignment List,先設為 Enabled,並在此新增一筆資料,名稱是含有 ActiveX 網頁的協定與完整網域名稱(例如 http://abc.com),值是 1(代表近端內部網路)。
  • 改完後,這個 FQDN 就不再屬「網際網路區域」,當首次造訪,網頁上的 ActiveX 就會直接提示使用者允許下載安裝,連「資訊列提示」步驟都跳過,而且管理附加元件的相關狀態是「啟用」,代表執行也應該沒問題。

星期一, 2月 16, 2015

PSCP + freeSSHd

為了彌補 Jenkins 的 Publish Over SSH plugin 只能將檔案由 Jenkins 往 SSH Server 送,不能反過來從 SSH Server 抓檔案的困擾,可以在 Jenkins 上安裝 PuTTY 的兄弟:PSCP.exe。要注意的幾點:
  • 在 Jenkins 設定一個 Execute Windows batch command 並執行之前,依這篇文章的做法,讓對方伺服器成為我「認識的主機」,要特別注意 Jenkins 服務的帳戶是哪個,如果是「本機系統帳戶」的話,機碼應該在 HKEY_USERS\.DEFAULT\Software\SimonTatham\PuTTY\SshHostKeys 這個位置。
  • 連線用戶身分的私鑰,可以由 PassPhrase 保護,或不加保護。如果是受保護的私鑰,在 PSCP 的命令參數除了 -i 指定私鑰檔之外,還要另加一個 -pw PassPhrase。至於私鑰檔的格式,與 PuTTY 相同,匯出工具可參考這篇

星期四, 2月 12, 2015

PuTTY 很棒,但 PuTTYgen 需要替代品

就「產生金鑰對」這功能,PuTTYgen 當然是可以勝任的,但有時我們會需要把結果匯出到不同的檔案格式,以便對其他程式交換金鑰,就會覺得還是 Bitvise SSH Client 比較好。在產生金鑰對之後,它可以選擇兩種公鑰匯出格式(OpenSSH、StandardSSH2)與三種私鑰匯出格式(Bitvise、OpenSSH、PuTTY)。

Jenkins + SSH plugin

為了讓 Jenkins 能成為 SSH client,從遠端下命令,考慮使用「SSH plugin」這個插件,但它表現不太理想(搭配某些免費的 SSH Server 會有問題),換成「Publish Over SSH」會比較好,雖然名字看起來功能是不同的,但它除了主要做 SCP 之外,也能下命令到遠端哦!

星期三, 2月 11, 2015

freeSSHd

這是一個安裝在 Windows 上的簡易 SSH Server,有幾點要注意:
  1. 在它本身的控制面板上如果顯示 "SSH server is not running",請看工作管理員,是否執行了多個程序,或有其他程式已佔用了預設的 port 22。
  2. 以「系統管理員」身分執行,否則自訂帳號可能無法儲存,控制面板一關就失效了(即使程序還在)。
  3. 預設防火牆是禁止外界連入 port 22 的,要開啟或換埠。
  4. 似乎過一段時間(幾小時?)沒有使用的話,即使服務仍處於啟動狀態,工作管理員的程序也在,但外面就是連不進來,要重啟服務來解決。
至於另一個比較知名的 OpenSSH 也有 Windows 版本,但它基於 Cygwin,又太舊了,所以安裝步驟要加很多補丁(可參考這篇說明),不推薦。

星期二, 2月 03, 2015

Jenkins + remote JMeter

  1. Install Java, JMeter in same version on Jenkins and remote JMeter server (ex: 10.1.2.3).
  2. [remote JMeter server]
    1. Edit jmeter.properties: "server.rmi.port=1099", "server.rmi.localport=4000".
    2. Allow firewall inbound port: 1099, 4000.
    3. Run "jmeter-server".
  3. [Jenkins (JMeter controller)]
    1. Edit jmeter.properties: "#server_port=1099" (default), "client-rmi-localport=1098", "jmeter.save.saveservice.output_format=xml".
    2. Allow firewall inbound port: 1098.
  4. Install Performance plugin on Jenkins.
  5. Source Code Management: checkout your script (my.jmx) to workspace.
  6. Execute Windows batch command: jmeter.bat -n -t my.jmx -l output.jtl [-j jmeter.log] -R10.1.2.3
  7. Publish Performance test result report: output.jtl

星期二, 1月 20, 2015

第一個 Jenkins Plugin 完成

多年來第一份正式的 Java 開發工作,雖沒什麼功能,實驗性質濃厚,但打通關之後的事應該就簡單了。若不是選了難搞的 MsDeploy 當 Runtime.exec() 的對象,應該能順利很多。

星期三, 1月 14, 2015

Mac / Linux batch rename

我有一大堆像這樣的檔案:
  • DSCN9537_1.jpg
  • DSCN9538_2.jpg
  • ...
  • DSCN9636_100.jpg
想要把檔名改成:
  • DSCN9537.jpg
  • DSCN9538.jpg
  • ...
  • DSCN9636.jpg
在 Linux 或 Mac 的做法:

for file in *.jpg; do mv $file $(echo $file | rev | cut -d_ -f2 | rev).jpg; done

星期一, 1月 12, 2015

Jenkins log SEVERE

在區域網路內有 Mac 的情況下,Jenkins log 會有許多「嚴重」(SEVERE)錯誤,原因是 UDP 5353,它同時被用於
  • Jenkins -> JmDNS
  • [Mac] Home Sharing -> Multicast DNS
由後者發出的封包不符前者的規則,導致解析失敗,就這麼簡單!那要如何避免呢?設置以下的 Jenkins 參數
  • -Dhudson.DNSMultiCast.disabled=true

星期二, 1月 06, 2015

Jenkins + CssLint 三大問題

  1. 某些 .css 檔案在掃描後會導致建置失敗,但紀錄中未指出原因,而且掃描是正常完成的,報告也有產出。這些檔案應該有些共同特徵,但目前尚不清楚。
  2. 當一次掃描的 .css 總數過大時,也會有上述癥狀,但這「過大」的條件並不固定,似乎會隨當時資源的使用狀況浮動。
  3. 在上述問題發生時,在命令列視窗重複執行該指令,並不會有任何錯誤訊息,掃描可正常完成。這點使得找問題加倍困難。