星期五, 12月 02, 2016

Break Same-origin policy by Nginx

HTML 5 愈來愈成熟,可預見的未來不再容許 ActiveX 的存在,替代方案是 WebSocket 或類似的架構,說穿了就是把一些髒事有安全疑慮的工作交給本機的一個輕量化 Web Server 處理。

不過「同源政策」又出來搗亂了,因為網頁所在伺服器與瀏覽器本來就不該一樣,而我能拿到的一個 ActiveX 替代方案參考實作,又偏偏不開放 Access-Control-Allow-Origin 這個表頭(一定是故意!),沒關係,請 Nginx 來助陣,設定如下:


如此一來,原先在 JavaScript 存取 http://localhost:61161 受到同源政策拘束的問題,改往 http://localhost:6116 即可解決。

星期二, 11月 29, 2016

VirtualBox Windows Guest + USB SmartCard Reader

不需要安裝 Guest Additions,但步驟如下可能會順利許多:
  1. 安裝 Windows Guest VM,關機。
  2. 插上讀卡機,在 VM USB (ver. 1.1 / 2.0) 設定勾選該裝置。
  3. 拔除讀卡機。
  4. 開啟 Windows Guest VM,開機完成再插入讀卡機。

Ping VirtualBox Windows Guest Fail?

想從 VirutalBox Host ping 到 Windows Guest?兩個條件:
  • VirtualBox Settings -> Network -> Host-only Adapter
  • Windows Guest Firewall -> Inbound Rules -> Virtual Machine Monitoring (Echo Request - ICMPv4-In / ICMPv6-In) -> Profile: Public / All -> Enable

星期四, 11月 24, 2016

Java 8 + JBoss 4.x + JSP

要安裝 JBoss 4.x,可先在下載,解壓縮即可。解壓後的目錄在下文以 <JBoss_Home> 表示。

啟動指令是 <JBoss_Home>/bin/run.sh -b <hostName_or_IP> &,如果省略 -b binding 的部份也可以,就只會允許伺服器本機的來源訪問;如果省略尾巴的 & 也可以,就變成前景執行(好像比較難管)?

停機指令是 <JBoss_Home>/bin/shutdown.sh -S -s <hostName_or_IP>,-s 的部份可省略,視如何開啟決定。

JBoss 4.x 接受 .war 熱部署,也就是把檔案直接丟 <JBoss_Home>/server/default/deploy 即可。

重點來了:如果底下是 Java 8 的話,.war 裡面的 JSP 如果有用到字串取代,在編譯時會拋出以下的錯誤:
依據這篇文章的說法,改 Java 7 即可解決。在安裝 Java 7 之後的程序如下:
怪的是,若再改回 Java 8 也不會有錯?其實原因在編譯結果已存在 JBoss 的其他位置,所以若將 JBoss 重新解壓縮到另一個目錄,那邊的 JSP 仍然會有問題。

星期六, 11月 19, 2016

Alpine quick start

因為 Docker 的關係,才注意到 Alpine 這種超輕量級的 Linux 最近很紅,以下紀錄一些初探的心得。

首先由官網下載 ISO,開機過程中有些問題要回答,大部份依照預設值即可。值得注意的是:
  • 首次登入的帳號是 root,無需密碼。
  • 登入後第一個命令在提示訊息也可看到:setup-alpine。
  • 網路必須要通,依預設會用 dhcp 連外。
  • 在意時區的話,可輸入 Asia/Taipei。
  • 鏡像站 mirror 的選擇,可依預設讓每一個都測試過反應時間,自動挑最快的。
  • 除非當作 LiveCD 用,可以一直按 enter 依預設值下去。若要安裝在硬碟的話,還是必須選擇裝在 sda 之類的裝置上,接著「如何使用」請回答 sys,為了要清除舊磁區內容還必須再回答 y。
  • 這階段完成會提示要 reboot,請先移除光碟再重啟。
重啟之後用新的帳密登入,接著來認識這個陌生的套件管理系統 apk:
  • 以 openjdk 為例,指令 apk search openjdk 搜尋沒有結果。
  • vi /etc/apk/repositories 可看到先前實測過最快的鏡像站,並且預設只接受官方套件,在此試著修改以增加社群等其他來源,存檔。
  • 執行 apk update,再次搜尋 openjdk 就有結果。
  • 執行 apk add openjdk8-jre (不需完整套件名稱)即可安裝。
  • 詳細列表可參考這裡,不過這裡的搜尋條件要用 openjdk* 的型式。
任務完成,Alpine 沒有 shutdown,請改用 poweroff。

Jenkins farm on Docker

單獨一部 Docker based Jenkins 不稀奇:
  • docker run -d --name jenkins -p 80:8080 jenkins
假設開起來了,查一下配到的 IP:
  • docker inspect jenkins | grep IPAddress
這裡得到的結果是 172.17.0.2,用瀏覽器訪問 http://localhost 與 http://172.17.0.2:8080 的結果應該是一樣的,我們用後者。首先需要 Unlock Jenkins。在 Terminal 下指令:
  • docker exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword
再把結果複製,貼到網頁裡,接著裝一下眾插件,設好管理帳號,Jenkins Standalone 就可以用了。

接下來要準備讓 Slave 掛上來,首先在 Jenkins 管理介面建一個新 Node,假設取名為 slave1,並設定 Remote root directory 為 /var/opt/jenkins,存檔,再點進去,畫面會像這樣:



點選超連結下載 slave.jar 並移到新建的 ~/share 目錄,然後在 Terminal 下指令:
  • docker run -d --name slave -v ~/share:/var/opt/jenkins:Z -w /var/opt/jenkins java:8-jre-alpine java -jar slave.jar -jnlpUrl http://172.17.0.2:8080/computer/slave1/slave-agent.jnlp -secret 1689af1c531a13800eff7b69113622c383d30b218cf7d28fea1322b3faf651b4
請注意不要抄我的密文,要與網頁上的一致,就能看到最輕量級的 Jenkins Slave 已在待命。

[2016/11/27]
補充不在 Docker 又限制 https,若憑證是自簽或沒有預設信任的狀況下,當然增加信任根憑證是治本之道,不過也可以應急:
  • java -jar slave.jar -jnlpUrl https://172.17.0.2:8080/computer/slave1/slave-agent.jnlp -secret 1689af1c531a13800eff7b69113622c383d30b218cf7d28fea1322b3faf651b4 -noCertificateCheck

星期三, 11月 16, 2016

Building dynatrace easyTravel from Source

  1. 在 dynatrace 官網下載 easyTravel 的原始碼壓縮檔,假設解壓目錄名為 ~/Downloads/dynatrace-easytravel-src。
  2. 安裝 Java、Ant。
  3. 編輯 /etc/hosts,為本機增加一個名稱,例如 osboxes。
  4. 切換至 ~/Downloads/dynatrace-easytravel-src/Distribution 目錄,執行 ant 命令,將產生 dist 子目錄放置編譯結果。
  5. 編輯 dist/startDistribution.sh,找到一行「export WEBLAUNCHER=set-this-property」,改為「export WEBLAUNCHER=osboxes」,存檔並執行,即會出現 easyTravel 的網頁管理介面。
  6. 在管理介面關閉 Mobile 相關的前端,也不要自動產生模擬流量,以節省資源。
  7. 在管理介面啟動 Production -> Standard 模式,注意資料庫必須正常運作,否則請檢查紀錄並排除問題。
  8. Credit Card Auth. (C++) 啟動失敗可以忽略,另外兩項在啟動過程中逾時,事實上已在提供服務。若在意的話,停止再啟動應能成功,否則請檢查紀錄並排除問題。
  9. 透過瀏覽器登入,帳密可用 afrida / afrida,網頁應會回應「Hello Afrida Afwika!」。

星期三, 11月 02, 2016

SonarQube Time Zone

SonarQube 預設使用 UTC,對於不夠國際化的我們是有點不方便。要如何在地化?編輯 sonar.properties,應可找到以下不連續的三行:
  • #sonar.ce.javaAdditionalOpts=
  • #sonar.search.javaAdditionalOpts=
  • #sonar.web.javaAdditionalOpts=
修改如下即可:
  • sonar.ce.javaAdditionalOpts=-Duser.timezone=Asia/Taipei
  • sonar.search.javaAdditionalOpts=-Duser.timezone=Asia/Taipei
  • sonar.web.javaAdditionalOpts=-Duser.timezone=Asia/Taipei
參考來源在

[2016/12/15]
其實這個問題應該回歸到作業系統的時區設定才對,當初先這麼做但失敗了,後來細究原因,才發現可能是因為沒有依照這篇舊聞。因為我的 SonarQube 是一個 Docker Container,而底下的作業系統是 Debian,無意間又找到另一種做法,指令如下:
  • dpkg-reconfigure tzdata

星期二, 11月 01, 2016

Docker container crash?

我負責的許多 Application Server 逐漸移到 Docker 上,最近常遇到休個週末回來就不行了?原來是這些在 VM 裡的 Docker 為了節能減碳,公司的政策是預設每週會自動停機,當底下的 VM 重啟之後,可以檢查到 Application Server 即使是開著的,埠口是外露的,也都只能在 container 本機存取服務,外界一概連不進去。
如此一定先懷疑防火牆吧?怪的是又沒去改,為何上週可以而本週不行?而且即使是整個防火牆都關了,也只修好一半,由完全失聯到「准進不准出」,像是 Jenkins 連不到外面的 Plugin Update Center,或是 SonarQube 連不到認證的 LDAP Server 等等。
最後找到真正的解法是 Docker Service 必須重啟。

星期三, 10月 26, 2016

Docker-based SonarQube

首先當然是要把 Docker 裝好,再來照這裡的說明只要一行指令:
  • docker run -d --name sonarqube1 -p 9000:9000 sonarqube
裝好了,要等個幾分鐘才開得起來。若是急性子可下指令觀察進度:
  • docker logs sonarqube1
用瀏覽器連要記得加上埠號 http://sonarqube1:9000。接著就再看看有什麼變化,例如希望使用者不需要加埠號即可訪問,改個設定就好(其實是另開新機):
  • docker stop sonarqube1
  • docker rm sonarqube1
  • docker run -d --name sonarqube2 -p 80:9000 sonarqube
SonarQube 是未登入即可看到內容,但管理者登入後才能設定,預設帳密都是 admin。在 SystemInfo 看到時區是錯的?可以參考這篇調整,但指令要在 container 裡面下:
  • docker exec -it sonarqube2 sh
另外,在首頁有提醒「Embedded database should be used for evaluation purpose only」,那來裝個 MySQL 好了(可參考這裡):
  • docker run -d --name mysql1 -e MYSQL_ROOT_PASSWORD=changeit mysql
不同於預設的 h2 database,在 MySQL 我們要自行準備一個空的資料庫與足夠權限的登入帳密給 SonarQube 用,而且現在是分別由兩個 container 負責,有點像是兩部主機,所以可像這樣設定:
  • docker exec -it mysql1 sh
  • mysql -u root -pchangeit
  • create database sonardb;
  • grant all on sonardb.* to sonaruser@'%' identified by 'sonarpass';
  • flush privileges;
  • exit
  • exit
為了模擬未來是跨 container 的通訊,可以另開一部 MySQL 並僅使用 client 端命令工具,來驗證準備給 SonarQube 用的資料庫。先查一下 mysql1 的位址:
  • docker inspect mysql1 | grep IPAddress
接著是第二部 MySQL:
  • docker run -d --name mysql2 --link mysql1 -e MYSQL_RANDOM_ROOT_PASSWORD=true mysql
  • docker exec -it mysql2 sh
  • mysql -h <mysql1_IPAddress> -u sonaruser -psonarpass
  • show databases;
  • exit
  • exit
注意 show databases; 的結果要看得到 sonardb 才對。接著還是依這篇最早提到的參考網址,重啟另一部連接 MySQL 的 SonarQube:
  • docker run -d --name sonarqube3 -p 9000:9000 --link mysql1 -e SONARQUBE_JDBC_USERNAME=sonaruser -e SONARQUBE_JDBC_PASSWORD=sonarpass -e "SONARQUBE_JDBC_URL=jdbc:mysql://mysql1/sonardb?useUnicode=true&characterEncoding=utf8" sonarqube
[2017/03/07]
搭配 PostgreSQL 似乎更容易些,且效率、評價都好,精簡至四道指令完成:

  • docker run -d --name postgres1 postgres
  • docker exec -it postgres1 createuser -U postgres -d -P -s sonar (input sonar / sonar)
  • docker exec -it postgres1 createdb -U sonar sonar
  • docker run -d --name sonarqube4 -p 9000:9000 --link postgres1 -e SONARQUBE_JDBC_URL=jdbc:postgresql://postgres1/sonar sonarqube

星期二, 10月 25, 2016

Red Hat Startup

CentOS 用這麼久了,原以為系出同門的 Red Hat 應該相去不遠才是,沒想到剛開始就踢到鐵板 - 沒有 yum?這樣是要叫人家怎麼裝東西?
好吧,先去 Red Hat 網站申請個帳號,再下指令:
  • subscription-manager register --username 帳號 --password 密碼 --auto-attach
然後呢?網路不通?連 ifconfig 都沒有?替代品:
  • ip a
沒有向 DHCP 取 IP,其實是網路介面在離線狀態,請看指令與前後查詢的結果(注意 enp0s8):

Linux access by non-root

用 root 帳號存取 Linux 是方便也是危險的。試想有人要攻一部主機時,沒有帳號是不能猜密碼的,他首先會猜這上面有什麼帳號?又哪個帳號具有最大的權限,讓攻下之後的效益最大?
通常建議平時的操作都用普通的使用者,只有在需要的時候取 root 權限做事,也就是 sudo。例如要新建一個 user1 帳號(此時還是 root 身分):
  • userdel -r user1
  • useradd user1
  • passwd user1
要如何設定 user1 在必要時能取得 root 權限?可以編輯 /etc/sudoers,通常會有這兩行:
  • ## Allow root to run any commands anywhere
  • root    ALL=(ALL)       ALL
仿上例,加以下一行即可:
  • user1   ALL=(ALL)       ALL
但這個檔案預設本身的權限是 440,只有 root 與其群組唯讀,所以要開放可寫才能修改。這樣有點麻煩?還可以參考同檔案通常還有這兩行:
  • ## Allows people in group wheel to run all commands
  • %wheel  ALL=(ALL)       ALL
也就是在不修改 /etc/sudoers 的情況下,將使用者加入 wheel 群組可達到同樣的效果,指令是:
  • usermod -aG wheel user1

星期二, 10月 11, 2016

Mac + VirtualBox + BlueStack => Crash

最近我 Mac 上的 Line 一直都不安份,常要求訊息加密(Letter Sealing)的身分驗證。由於沒有實體 Smartphone 的關係,一直要開 BlueStack 模擬很麻煩就算了,還會讓稍後再開 VirtualBox 的 Mac 當機!原來這兩個軟體是有些愛恨情仇的。而且 Bluestack 竟然也一年沒更新了,暫時就先關閉訊息加密吧,有空再找時間試試 Genymotion 能否取代掉 Bluestack。

SonarQube Analysis Fail?

我都是透過 Jenkins 向 Subversion 取得原始碼,再送給 SonarQube 分析,但有的專案順利,有的就不行,錯誤訊息像是:


關鍵在於 Jenkins 當然會有 Subversion 的帳密(用以取原始碼),但 SonarQube 也要?那是用來 blame 作者的。在 SonarQube 如此設定就能解決:


回頭再看那些順利的,歸納出一個差異:要不就是非 Subversion 的 VCS,要不就是帳號在 LDAP。結論:若是 Subversion 上的特殊帳號才會有此問題。

星期五, 9月 30, 2016

Jenkins Cobertura Report Missing?

很久以前好不容易在 Jenkins 弄出來的 Cobertura 測試涵蓋度報表,最近再看竟然只剩頁框了?原來是因為 Content Security Policy 的緣故,要在啟動時加一個參數來避免:
  • java -Dhudson.model.DirectoryBrowserSupport.CSP= -jar jenkins.war
如果光講這個方法就不好玩了,另一個有趣的是「Manage Jenkins -> Script Console」,這裡的指令即下即行。因為測試涵蓋度報表結構上與 Java Doc 類似,所以這樣的命令也能讓報表重現:
  • System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "sandbox; default-src 'none'; img-src 'self'; style-src 'self';") // default
  • System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "default-src 'none'; img-src 'self'; style-src 'self'; child-src 'self'; frame-src 'self';") // for JavaDoc, may be working or not
  • System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "") // work if no cache
  • System.getProperty("hudson.model.DirectoryBrowserSupport.CSP") // check

星期五, 9月 23, 2016

"top" in docker container - TERM environment variable not set

在 docker 裡竟然不能用 top 觀察資源的使用情況?執行這個命令之後就好了(參考這篇):
  • export TERM=xterm

星期二, 9月 06, 2016

移植 NUnit + Selenium BDD 測試案例到 Linux 上執行

首先準備乾淨的 Linux,這次用的是 OSBoxes 的 CentOS 7。當 VM 開起來之後,要手動啟用網路、讓它自動抓時區並對時,然後檢查 Firefox 的版本,ESR 38.3 太舊了,這樣更新:
  • sudo yum install -y firefox
升級到 ESR 45.3 之後,到 Selenium 下載 geckodriver,解壓後執行,再檢查是否有程式在聆聽 4444 埠?
  • netstat -tunlp | grep 4444
若有就對了。幸好 Mono 官網近來也提供 CentOS 的支援,這裡說明非常清楚,先加入金鑰與儲存庫,再安裝 mono-devel:
  • sudo yum install yum-utils
  • sudo rpm --import "http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF"
  • sudo yum-config-manager --add-repo http://download.mono-project.com/repo/centos/
  • sudo yum-install -y mono-devel
NUnit 也只是從官網下載解壓,至此萬事俱備。我的測試專案若要使用本機的瀏覽器,需如下設定:
  • RemoteWebDriverUri: http://localhost:4444
設定修改後需要重新編譯:
  • xbuild BehaviorTestSkeleton.sln
在命令列執行:
  • mono nunit3-console.exe BehaviorTestSkeleton.dll

星期二, 8月 30, 2016

Nginx on CentOS 5/6/7

之前在 Windows 裝過 Nginx,這次是 CentOS。
  • Install
    • 建立 /etc/yum.repos.d/nginx.repo 文字檔,內容如下:
      • [nginx]
      • name=nginx repo
      • baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
      • gpgcheck=0
      • enabled=1
    • 注意上述的 $releasever 要換成 CentOS 的版本號,可以是 5、6 或是 7
    • 執行 sudo yum install nginx
    • 官網原文在
  • Start as a service
    • sudo service nginx start
  • Test
    • curl http://localhost
[2018/02/05]
也可以先裝 EPEL 就好:
  • sudo yum install epel-release
  • sudo yum install nginx

星期五, 8月 26, 2016

GitLab 8.x Upgrade

系統升級本是一件大事,理論上流程應該是「備份、下載、升級、重啟、成功或還原」,但在我所處的困苦環境,想備份都沒有硬碟空間,所以只好冒著失敗的風險直接升(當然還是有整機還原這條後路),只要三個步驟,大約三分鐘:
  • sudo yum install gitlab-ce
  • gitlab-ctl reconfigure
  • gitlab-ctl restart

星期四, 8月 04, 2016

第一次看到微軟的 Docker Images

雖然 Docker 官網已默默地「有了」微軟的產品(其實是作者後知後覺?),但介紹文出爐還不到一個月。對於最低消費還要近 10GB 感到還有進步空間。有圖為證:

星期二, 7月 12, 2016

Simplest AJAX client / server with CORS

先談最簡單的 AJAX server:
  • NodeJS
  • Module: Express (optional)
  • 網路上一大堆 http.createServer(req, res) 範例
  • 防火牆設定
接著在 server 上準備一個 jQuery based 網頁去呼叫上述的服務,但因為網頁並沒有真的部署在任何 Web Server 上,所以在瀏覽器開啟的網址列會是以 file:// 開頭,一般受限於 CORS 會不能對 server 發起 Request,或精確地說,在瀏覽器預檢 preflight 失敗後就放棄,若開啟任何開發者工具之類的側錄看來像沒反應。針對各種瀏覽器的解決如下:
  • Chrome、Firefox、Safari:在 server js 加這一行
    • response.setHeader("Access-Control-Allow-Origin", "*");
  • IE:在網頁傳送 ajax 之前加這一行
    • $.support.cors = true;
  • Edge:以系統管理員身分開啟命令列提示,輸入
    • CheckNetIsolation LoopbackExempt -a -n=Microsoft.MicrosoftEdge_8wekyb3d8bbwe
這絕對是我看過最怪的解法了,不過有憑有據,也真的有效。

星期三, 6月 15, 2016

修正 GitLab 發系統通知信需要密碼的錯誤

不論是前任管理員或網路上都有此誤解,澄清相關設定如下即可:
  • 寄件伺服器接受網域內互寄不需密碼驗證
  • gitlab_email_from 必須是真正的郵件位址,不能是 noreply@nodomain
  • 不設定 smtp_user_name
  • 不設定 smtp_password
  • 不設定 smtp_authentication
  • 其他 smtp 相關設定依官網範例

星期六, 6月 04, 2016

利用 PowerShell 處理多文字檔內的字串替換

假設待處理文字檔的完整路徑都一行一行地收集在 list.txt,每個檔案內的 old 都要換成 new,PowerShell 的命令檔 *.ps1 內容如下:

$fileList = Get-Content list.txt
foreach ($targetFile in $fileList) {
    (Get-Content $targetFile) |
Foreach-Object {$_ -replace "old", "new"} |
Set-Content $targetFile
}

若更單純些,只要處理一個文字檔,只要保留迴圈內的部份,$targetFile 直接換成檔名即可。

星期四, 6月 02, 2016

到不了的中斷點

在 Visual Studio 的某個專案,其他許多中斷點都正常,唯獨這一個停不下來:
  • string s = AppDomain.CurrentDomain.BaseDirectory;
它有什麼特別?原來這是編譯器最佳化的對象。有個設定可以讓它恢復平民身分:
  • Project Properties -> Build -> Optimize code -> uncheck

星期二, 5月 31, 2016

救回 Windows 作業系統下被封印的 USB 磁碟空間

明明就是 16GB 的新 USB Disk,在 Mac 使用正常,跑到 Windows 不但提示要格式化才能使用,而且空間只有 200MB?救命文在

星期三, 5月 18, 2016

放寬 IIS 7 上傳大檔的限制

如圖。值得注意的是有兩個設定值影響,而且一個單位是位元組,另一個是仟位元組。

自動更新的 IIS / IIS Express 網站建置時戳

在網站開發期,由於要經常建置、部署、測試,常會有一個困擾,那就是「不容易識別目前在執行的網站版本」。如果有個政策是「每次部署都人工修改頁面上的版本資訊」固然可以,但難保不會忘了做。
為了解決這種問題,我的做法是在首頁引入以下的檔案:
  • <script src="lastBuild.js"></script>
並且在頁尾安排顯示的位置,
  • <div id="lastBuild"></div>
當頁面載入時,更新內容:
  • <script>
  •     $(function () {
  •         $("#lastBuild").text("lastBuild: " + lastBuild);
  •     });
  • </script>
重點是 lastBuild.js 的內容,藉由 Visual Studio 編輯 Pre-build event command line 動態產生,指令為:
  • set output=../lastBuild.js
  • echo | set /p dummy = "var lastBuild = '" > %output%
  • FOR /f %%a in ('WMIC OS GET LocalDateTime ^| find "."') DO set D=%%a
  • set timestamp=%D:~0,4%/%D:~4,2%/%D:~6,2%T%D:~8,2%:%D:~10,2%:%D:~12,2%';
  • echo | set /p dummy = %timestamp% >> %output%
有些值得說明的地方,例如第 1 行定義產檔位置在上層目錄(否則可能預設在 bin\);第 2, 5 行的 echo | set /p dummy = 而不是單純用 echo,為的是避免多餘的空行;第 3 行的 WMIC 指令用來取日期,若單純用 date 指令會受 Locale 影響年月日的順序,find "." 也是用來過濾掉多餘的其他行;第 4 行用來格式化時戳字串。如此在每次建置時,產生出來的 lastBuild.js 內容就會像這樣:
  • var lastBuild = '2016/05/18T17:09:15';
在頁尾的顯示會像這樣:
  • lastBuild: 2016/05/18T17:09:15

星期三, 5月 11, 2016

Visual Studio Web Publish on many Configurations

過去一直沒搞清楚這幾個 Configurations 有什麼不同?


其實很簡單:最上面是 Solution 的,中間是 Project 的,下面是從 Publish Web 開出來,當然就是「發行網站」的組態設定。但這又是什麼?
在此又牽涉到另一個過去沒搞清楚的:到底 Web.config 下面多出那兩個是什麼?


事實上那就呼應到發行網站時可以搭配的多種組態啦!那是直接編輯各個組態檔嗎?可以是,也可以不是。因為實務上絕大部份的組態設定在不同組態下都是相同的,如果因此就複製貼上一大段實在不智,正規的做法如下:


如此在發行網站時,就會即時計算與組態匹配的內容,動態地產生調整後的 Web.config 供發行使用。在此例中,當 Publish Configuration = Release 時,Connection1 的 Server=Development... 會被置換成 Server=Release...,但 Connection2、Connection3 將繼承原本的 Web.config。

星期六, 4月 30, 2016

IIS 主機上「其他」檔案存取

為了要取得 IIS 主機上的一些「非」網站內檔案(例如紀錄檔),過去的經驗都是另開遠端桌面,但限於授權數量,當很多人都需要的時候就不方便了。
其實早就有 WebDAV 可以利用,但只能開放網站所在位置的實體目錄?如果紀錄檔在 D:\ 而網站在 C:\inetpub\wwwroot?不是問題,可以在網站上掛虛擬目錄。
在使用端如何掛 WebDAV 分享出來的目錄?設「網路連線磁碟機」,在資料夾的設定不同於常見的 \\server\share 形式,而是像 http://host/share 這樣。
WebDAV 設定需要注意的是:
  • 需要開啟 Enable
  • 編寫規則
  • 相關設定
  • 授權給匿名或特定角色、使用者
  • 搭配網站的認證授權設定

讓 Linux 認得 Windows 主機

有些內部網站像是 http://hostname 而不是 http://www.domain.com 這種形式,通常較多人用 Windows,瀏覽器找得到 http://hostname 這種位置,但在 Linux 上就不行了。只好先查 hostname 對應的私有 IP 位址,瀏覽器再找 http://x.x.x.x 才行,有沒有更好的解法呢?

首先要知道一般 Windows 為什麼認得較短的電腦名稱?這種是 NetBIOS name,與較長的 FQDN 不同,只要在內網唯一就可以了,負責管理的是 WINS。

在 Linux 上要認得 WINS 可以透過安裝 SAMBA(這是個逆向工程的經典),然後在 smb.conf [global] 設定 wins server = x.x.x.x 就可以了,其他常用的 workgroup、netbios name 或是 security 都與主題無關,注意不要設 wins support = yes。

在驗證效果時我也一直有個錯誤的觀念,以為在 Linux 應該可以 ping hostname?但還不行,nsswitch.conf 也要改,其中有一項 hosts: 必須把 wins 加進去。

[2018/05/21]
如果在 Linux 上僅安裝 samba-client 也是可以的,例如先查好 WINS 的位址在 172.16.1.2,要找的機器名稱為 Win10,指令是:
  • nmblookup -U 172.16.1.2 -R 'Win10'

星期五, 4月 22, 2016

Excel 的日期舊臭蟲

聽說有人用 KendoGrid 從 SQL Server 抓資料呈現沒問題,但再匯出 Excel 時竟有些日期會自動加一天,懷疑 KendoGrid 有問題?深入追查後發現:SQL Server 日期欄位沒資料時的 1900/1/1 竟然撞上 Excel 繼承 Lotus 1-2-3 留下的一個 bug,能活這麼久,這應該算程式界的小強吧?這篇有許多詳盡又有意思的說明。

星期三, 4月 20, 2016

SonarQube 5.x upgrade

為了升級 SonarQube 4.5 -> 5.4,被眾插件卡了蠻久的:
  • 過去 LDAP plugin 1.5 的設定不能只照搬到 1.5.1,要額外加上 ldap.windows.auth=false。
  • 因為架構改變,還蠻多插件不能在新版繼續使用的,詳情可參考這篇
  • 其實 JIRA plugin 只支援到 SonarQube 4.x LTS,新版遙遙無期。雖然開單是沒問題,但寫入 JIRA 的 SonarQube 連結是連不回來的。原來舊版網址 http://${host}/issue/show/${uuid} 之中的 issue 在 SonarQube 5.x 已悄悄改成 issues,就這樣!改人家已 Deprecated 的程式似乎也不好,後來請出 Nginx 做 URL Rewrite 解決。

星期五, 4月 15, 2016

MySQL 資料復原

最近一直被逼著玩我不太欣賞的 SonarQube,因為太慢所以想升級,因為版本跳得多所以升了之後有一堆問題,煩到打算先降回來擇日再看,結果竟然遇到 MySQL 備份無法還原?資料弄得不上不下,SonarQube 新舊版同時罷工!
還原的錯誤訊息是「Unknown command '\''」,幸好是有解。有說法是備份資料庫有中文就會這樣?陽春的還原指令不行:
  • mysql -u root -p dbName < backup.sql
改這樣就可以了:
  • mysql -u root -p --default-character-set=latin1 dbName < backup.sql

星期四, 4月 07, 2016

Extra Packages for Enterprise Linux (EPEL)

為了補充官方版套件的不足,由 SIG 維護的 EPEL 也是重要的安裝來源。現在 CentOS 要啟動是再簡單不過了:yum install epel-release。

星期一, 3月 28, 2016

收集 Windows 效能資訊

雖然有 Cacti 這種萬用工具,但有時受限於安裝,也要有替代方案。Windows 都有內建「效能監視器」,記得先挑一下取樣對象與頻率,大概常用的就是 Processor Time % 之類的,不要留太多(檔案會爆大);時間範圍可以搭配排程來切割。
實際抓朝九晚五的 CPU 使用率,每秒取樣一次,產出預設的 .blg 紀錄大約不到 30MB。
若事後要縮減時間範圍,可以用 Relog 這個微軟官方工具。

星期五, 3月 25, 2016

如何在多人共用的 Windows 找到誰開啟(鎖定)了檔案

微軟官方有提供一個工具 Handle 可以適用在 Vista 或 Server 2008 以上的作業系統,執行的方法也很簡單:Handle.exe -u Part_Of_FileName(完整檔名當然也可以,不需路徑)。
如果找不到,試著用 Administrator 權限執行,看會不會有比較好的結果?

星期四, 2月 18, 2016

FxCop 設定

有時我們在開發的程式會遇到如下圖的狀況
這個問題在編譯或執行階段常見且不算複雜,但若是在 FxCop 因此卡住,就有些棘手。其實有兩種辦法(參考此處):
  • 增加命令列參數 /AssemblyCompareMode:StrongNameIgnoringVersion
  • 修改 FxCop 的設定檔 AssemblyReferenceResolveMode 設定,將 StrongName 改為 StrongNameIgnoringVersion 即可。

星期二, 2月 16, 2016

安裝 Node.js + Oracle Client

Node.js 的火紅,雖然 Oracle 原廠都出來支援了,但在 Mac 的部份,這篇實在也卡了我好久:
  • 裝在 /opt 這段應該是少寫了什麼,目前只有在 user directory 成功的經驗。
  • 最後的 npm install oracledb 請好心點,直接寫成 sudo -E npm install oracledb。
  • 只要稍有差池,莫名其妙的錯誤訊息「node-gyp rebuild」幾乎是誤導大王,還是仔細地核對每個步驟比較實際。
在 Windows 也是依照原廠指示,幾個容易忽略的地方:
  • Visual Studio 預設安裝選項應該是沒有 C++ 的,不符 PreCondition 的要求。
  • 要以「系統管理員」身分在 Developer Command Prompt 先設好 OCI_LIB_DIR / OCI_INC_DIR,再執行 npm install oracledb,否則誤導大王將再次出現!

星期一, 2月 15, 2016

藉由 WebServices 開放資料

通常在跨系統整合面臨的抉擇:到底要直接開放應用系統後端的資料庫,或是在應用系統上準備一些 WebServices 來服務其他的應用系統?比較安全的作法當然是後者,不過通常被認為成本較高,但果真如此嗎?其實這些輪子通常是已經存在的。以 Oracle 來說可以參考這篇,以 MS SQL 來說可以參考這篇以及這篇

星期三, 1月 20, 2016

IIS + Oracle 的系統開發

  1. .NET Framework 內建 System.Data.OracleClient,已被標為 Obsolete,就別再留戀了。
  2. 開發環境一般會安裝 Oracle Client 與 ODAC (Oracle Data Access Component) 兩者,但事實上只要 ODAC 就夠了。若是要直接連 Oracle 查、改資料這個理由,除了 Oracle Client 之外,DBeaver、TOAD、甚至 Visual Studio 都可以用才對。
  3. ODAC 也有分 XCopy 或其他一大堆帶不同元件的包裝,看來 XCopy 的比較單純,利用解壓後批次檔安裝所有部份比較保險,記得要用系統管理權限,事後還要對安裝路徑加入全域 PATH 環境變數,甚至較舊的作業系統可能還要調整該目錄的安全性,開放給所有 Authenticated Users,如果已經開了 Visual Studio 也要重開才能讀到新的環境變數。
  4. 在 64 位元的作業環境,32 / 64 位元的 ODAC 都可運作,但事實上 32 位元的比較方便,原因是 Visual Studio 附帶的 IIS Express 預設還是 32 位元(設定在 Tools -> Options -> Projects and Solutions -> Web Projects),兩者必須搭配。
  5. ODAC 畢竟還是 Native,其實早就有 Oracle ManagedDataAccess NuGet Package 可用,安裝管理都方便。就算是舊程式轉換也只要改 Namespace (Oracle.DataAccess -> Oracle.ManagedDataAccess) 就好。
  6. 也不再仰賴 tnsnames.ora 設定連線資訊,可以查查 Oracle 有個名詞叫 EZCONNECT。例如我們以前在設定檔寫 DataSource=abc;User Id=... 還要搭配 tnsnames.ora 其中一段 abc=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=...,現在只要改成 DataSource=<HostNameOrIP>:<Port>/abc;User Id=... 就夠了,幹嘛要分兩個地方設定?

星期日, 1月 17, 2016

調校 64 位元環境下的 Visual Studio + IIS Express 執行 32 位元應用程式

過去常在 64 位元環境下的 IIS 接觸到這個議題,通常都是多人共用的測試機或正式機,沒想到為了難搞的 Oracle,連個人開發環境也要講究 32 / 64 位元的參考與執行環境搭配,而且驚訝於許多人們因此被迫放棄了 IIS Express。其實這個問題不難,但由於 IIS Express 一直沒有管理介面,讓人總搞不清楚設定,就參考一下這篇吧。