2014年5月29日 星期四

[Linux] 讓 git checkout/diff 略過 file permission 屬性

最近把 git 當作 deployment 過程的一環,接著就會碰到一個問題,有時因為需求要調整 file permission ,此時就會造成 git checkout 失敗,要求要先 merge 在行動。雖然 file permission 容易出現在 Windows / Linux ,但在 Linux 環境用 git 當作 deployment 時,也常有身份、權限的改變而造成一樣的影響。

解法:

$ git config core.fileMode false



$ git -c core.fileMode=false diff
$ git -c core.fileMode=false checkout

2014年5月25日 星期日

[NodeJS] 使用 WebShot 進行網頁截圖、顯示正確的中文(CJK)等編碼 @ Ubuntu 14.04 Server



把玩一下 node.js ,發現有個套件不錯叫做 webshot,非常簡易地就可以把網站截取下來。然而,在 Ubuntu 14.04 server 版上運行時,發現無法正常顯示中文字,需要額外處理,就筆記一下:

安裝 Node.js:

$ sudo apt-get install nodejs npm
$ sudo ln -s /usr/bin/nodejs  /usr/bin/node


使用 webshot:

$ mkdir ~/webshot
$ cd ~/webshot
$ npm install webshot
$ vim test.js
var webshot = require('webshot');
webshot('tw.yahoo.com', 'yahoo.png', function(err) {
if(err)
       console.log(err);
} );
$ nodejs test.js


然而,無法顯示中文字,簡言之就是缺字型,安裝一下即可:

$ sudo apt-get install xfonts-wqy

成果一切正常:

2014年5月23日 星期五

使用 Wget 進行簡易的 Web Crawling

$ wget --recursive --no-clobber --html-extension --convert-links --no-parent --wait 5 --domains example.com www.example.com

如此一來,會在當前目錄建立 www.example.com 目錄,將依照網站目錄結構存儲起來。

使用 lnyx 抽取 Web Page 所有的 Links

沒想到 lynx 真好用 XD 比用 Wget 好的地方是不用去重組一些 relative link,那缺點就會是要避開同一個 page 的 anchor (<a href="#me></a>) 用法,但是...有些 Javascript 的或是其他 MVC 架構的網站,仍會用 anchor 來取資料。

$ lynx -dump -listonly https://tw.yahoo.com | grep -o '^\s\{1,\}[0-9]\{1,\}..*$' | sed -e 's/^[[:space:]]\{1,\}[0-9]\{1,\}\.[[:space:]]//g' | uniq

2014年5月22日 星期四

使用 Wget 抽取 Web Page 所有的 Links (關鍵字 href="")

簡易用 Wget 達成:

$ wget -q --no-check-certificate -O - https://tw.yahoo.com | grep -o 'href=['"'"'"][^"'"'"'#]*['"'"'"]' | sed -e 's/^href=["'"'"']//' -e 's/["'"'"']$//' | grep -v "javascript:" | uniq 註:wget 有 --convert-links 可用

2014年5月19日 星期一

[Linux] 透過 AWK 和 HOSTNAME 資訊執行 Sleep 指令 @ Ubuntu 14.04

最近開始埋一些 crontab 任務到各台機器,但是,有些指令是對 DB 動作的,而通常擺在 crontab 的 DB 指令是為了建出一些 snapshot 且多為 slow query 的,那如果多台機器全部都同時發送 DB query 時,反而又累到了 DB 系統。

這時候想到的方式就是搭配 sleep 的方式,並透過每檯機器的資訊避開一同發送要求,用法就想到 hostname 了:

$ awk '{s=0;for(i=1;i<=length($0);i++){c=sprintf("%c",substr($0,i,1));s+=c ;}; system( "sleep " s); }' /etc/hostname 

最後,在 crontab 上,就可以在待執行指令前面,先安插上述的 script 來跑,如:
  # m h dom mon dow command
*/10 * * * * sh /path/sleep.sh ; /path/job_exec

2014年5月17日 星期六

微型創業(Micro Startup? Personal Startup?) 費用規劃

中午吃飯時,想起前幾天跟學弟閒聊 startup 的趣事,有些人 startup 是為了工作機會,有些人是為了錢,有些人是為了興趣,不論是哪種想法,都是人生的一種規劃與執行。

這幾個月摸了 AWS 、Linode 和 Aliyun 後,深深覺得資金方面的規劃可以透過這些 VPS 服務來"限制"管理,反而人力、人才、成果進度才是最不穩定且需要花心力的地方 :P

就先來聊聊 Micro Startup 的可能的固定花費:
第一年一整年的費用約 (99+25+5) + (20+25*2)*12 + (12+10) = 991 美金/年,也等於一個月約 83 美金(做起來後再煩惱隔年的花費吧)。其它未計算的包含開發用的設備(如 OSX 系列的裝置等)

以 1:30 來算,算起來一個月約 2500 台幣的花費,其實負擔並不會太重 :)

所以,最重的花費其實是"人力時間"與"成果時間" Orz

2014年5月16日 星期五

[PHP] 簡易的 Web Service Unit Test: HTML validator、JSON Format @ Ubuntu 14.04

把 web service 移到 AWS 上後,想到時時刻刻都人工測試感到很 Orz 於是想了一些簡易 Unit Test 方式:
  • 檢驗網頁是否可讀取正常 (strlen)
  • 檢驗網頁 HTML 格式 (tidy 或 xmllint)
  • 檢驗網頁上的 link 個數 (preg_match_all)
  • 檢驗 JSON 格式 (json_decode && json_last_error)
剩下的就...再看看 XD

其他筆記:changyy / web-service-unit-test / phpunit / web-service-unit-test.php 

2014年5月15日 星期四

Linode - Free Upgrade、Restore from Backup、Resize 的時間花費

說真的 Linode 提供的服務對個人而言還滿好用的,只是對於公司營運 service 的不中斷的需求來說,則沒有 AWS 好用 Orz 雖然 Linode 也有 Node Balancer 可以用,但絕大部分的 High Availability 都仍透過 WebOps 負責處理,耗掉的人力並不低,而花在 AWS 的錢,其實就跟請 2~3 位 WebOps 的錢沒兩樣時,但底下的 WebOps 人力可以精簡又做得快樂時,何樂不為?

回到主題,這邊主要是趁 Free Upgrade 模式以及 Backup (Restore to) 機制,測試開一台機器所要耗費的時間,對 Linode 而言,原理都是把機器的硬碟資料 snapshot 起來,再搬到到另一台機器,啟動。所以最耗時的地方都落在資料搬移(複製)。



至於耗時為何需要在意?實在是使用 Linode 等 VPS 後,深深體會不能把這些機器都當做不會掛,某一派 SA 會覺得終於不用管"硬體"了,但這幾個月體驗了數次 Linode Hardware Issue 而直接強迫中斷服務,實在有夠痛 XD 雖然不用自己去修硬體,但服務中斷等同 WebOps 進入加班啊,因此,耗時對初期沒做 HA 的架構來說,就是代表要花多久解決中斷的服務,這時通常是透過 Backups 的 "Restore to" 。

此例分別以 Linode HDD Size 為例:
  • 48GB: 約 16 分鐘
  • 96GB: 約 23 分鐘
  • 384GB: 約 97 分鐘

2014年5月10日 星期六

[Linux] 使用 Nagios 監控 AWS EC2、RDS 服務狀況 @ Ubuntu 12.04

雖然 AWS 已經有不錯的服務監控系統,但原先已經用 Nagios 監控服務,就順手研究一下對於 EC2、RDS 的監控吧。

由於資安角度,預設都不給 PING 的,此外 RDS (此例是 MySQL port 3306) 則只開放特定 TCP Port 而已,對 Nagios 而言,就可以改測試 TCP Port (HTTP,HTTPS,SSH) 等用法,如此一來就可以解決 Host is Down 囉。

define host {
        host_name aws-rdb
        alias aws-rdb-dns
        address aws-rdb-dns
        use rdb-host
        contact_groups db-services
}

define host {
        host_name aws-dev
        alias aws-dev-dns
        address aws-dev-dns
        hostgroups ssh-servers,http-servers
        use ec2-host
        contact_groups pc-services
}

define command {
        command_name check-rds-host-alive
        command_line /usr/lib/nagios/plugins/check_tcp -H $HOSTADDRESS$ -p 3306
}

define command {
        command_name check-ec2-host-alive
        command_line /usr/lib/nagios/plugins/check_tcp -H $HOSTADDRESS$ -p 80
}

define host{
        name                            rdb-host    ; The name of this host template
        notifications_enabled           1       ; Host notifications are enabled
        event_handler_enabled           1       ; Host event handler is enabled
        flap_detection_enabled          1       ; Flap detection is enabled
        failure_prediction_enabled      1       ; Failure prediction is enabled
        process_perf_data               1       ; Process performance data
        retain_status_information       1       ; Retain status information across program restarts
        retain_nonstatus_information    1       ; Retain non-status information across program restarts
                check_command                   check-rds-host-alive
                max_check_attempts              10
                notification_interval           0
                notification_period             24x7
                notification_options            d,u,r
                contact_groups                  admins
        register                        0       ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE!
        }

define host{
        name                            ec2-host    ; The name of this host template
        notifications_enabled           1       ; Host notifications are enabled
        event_handler_enabled           1       ; Host event handler is enabled
        flap_detection_enabled          1       ; Flap detection is enabled
        failure_prediction_enabled      1       ; Failure prediction is enabled
        process_perf_data               1       ; Process performance data
        retain_status_information       1       ; Retain status information across program restarts
        retain_nonstatus_information    1       ; Retain non-status information across program restarts
                check_command                   check-ec2-host-alive
                max_check_attempts              10
                notification_interval           0
                notification_period             24x7
                notification_options            d,u,r
                contact_groups                  admins
        register                        0       ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE!
        }

[Linux] AWS RDS + PHPMyAdmin + HTTPS + HTTP Basic authentication @ Ubuntu 14.04

為了配合 AWS RDS 而開始用 mysql-server-5.6 ,就試著用 EC2 + Ubuntu 14.04,安裝 PHPMyAdmin 時,採用的 DB 不是在本機的,而是 RDS 上。雖然我也不常用 PHPMyAdmin ,但為了提供其他人使用,所以就來架設一下 XD

$ sudo apt-get install mysql-client-5.6 php5 apache2 apache2-utils git php5-mysql
$ sudo a2ensite default-ssl.conf
$ sudo php5enmod mcrypt
$ sudo service apache2 restart

$ sudo vim /etc/phpmyadmin/config-db.php
// 在底部新增:
$dbuser='rds_account';
$dbpass='rds_password';
$dbserver='rds_location';

$ sudo vim /etc/phpmyadmin/config.inc.php

// 採用 HTTP Basic authentication
//$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['auth_type'] = 'http';

// ...
// 最底層加上強制 HTTPS
$cfg['ForceSSL'] = true;


如此一來,使用 http://hostname/phpmyadmin 時,就會強制轉成 https://hostname/phpmyadmin,並且會採用 HTTP Basic authentication 機制。

註:不知為何,採用 HTTP Basic authentication 機制時,logout 後再進行 login 時,url後面會帶有 old_usr 資訊時,無法正常登入,所以後來就放棄了 XD

2014年5月7日 星期三

AWS 筆記 - 使用 Amazon EC2 進行 Deploying Web services

稍微把玩 AWS Elastic Load Balancing 跟 Auto Scaling 後,大概有一點粗淺的心得:
  • 開一台機器,如 micro 等級,並設定這台機器關機也不下線,可專門用於製作 AMI
  • EC2 micro 採用 EBS 管理,每一次製作 AMI 會產生新的 EBS snapshot,記得定時去清理
  • 程式碼若是透過 git 管理,可以在 /etc/rc.local 上設定開機自動更新方式,至少 AMI 不是最新程式碼時也還能堪用(但 git server 掛了就...)
  • 如果想要透過 web cgi 更新,記得把 source tree 的 owner 或 group (搭配775方式) 設定 www-data,可以用 sudo -u www-data /tmp/update.sh 進行測試
AWS Elastic Load Balancing:
  • 使用 AWS ELB 時,可以讓多台機器綁定在固定的 DNS Name,記得需要處理一下多台機器進行切換其 Session/Cookie 問題,例如單純的使用情境,可以透過設定 Stickiness: LBCookieStickinessPolicy, expirationPeriod='600' 等方式來應付等
  • 對於有使用 HTTP Authentication 的 web server 而言,因為帳密是一直隨 browser 傳給 web server 的(就像 cookie一樣),所以 ELB 再切換機器時,不會因機器不同台而再次詢問帳密
AWS Auto Scaling:
  • 對 Auto Scaling 而言,預設機器都是關機後就下線,除非改掉預設方式,不然更新系統時 reboot 的結果就是開一台新機器,此外,把 Auto Scaling Group 刪掉等同把機器都下線
  • 透過製作新的 AMI 來取代系統更新時,而原先設定好的 Auto Scaling Launch Config 不能更新採用的 AMI,但可透過新增新的 Launch Config 後,更新 Auto Scaling 設定後,再刪掉舊的 Launch config 等

2014年5月6日 星期二

[Linux] 從 Ubuntu 12.04 / MySQL 5.5 升級到 Ubuntu 14.04 / MySQL 5.6 過程 @ Ubuntu 12.04

由於某台機器接近閒置,原本單純想把 MySQL 5.5 升級到 MySQL 5.6 的,後來看一下 Ubuntu 14.04 裡頭有 MySQL 5.6 可以用,就把它升了。

連續過程:

$ sudo do-release-upgrade -d

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04 LTS
Release:        14.04

Codename:       trusty

$ service mysql stop

$ sudo apt-get remove mysql-common mysql-server-5.5 mysql-server-core-5.5 mysql-client-5.5 mysql-client-core-5.5
$ sudo apt-get autoremove

$ sudo apt-get install mysql-server-5.6
$ mysql_upgrade -u root -p


更正規的 MySQL 更新方式是要先把 /var/lib/mysql 跟 /etc/mysql 備份起來才行動的,此處因為機器上的服務已經遷移(在其他處有備份),所以就這樣升了。

2014年5月2日 星期五

iOS 開發筆記 - 使用 AdMob 與 IDFA 的處理



查詢 Admob 的 iOS release notes 可知 Admob 6.5.0 (2013/07/16) 時已經有用到 IDFA 了。但很妙地,上回上傳時沒碰到,但這次更新時又會碰到?這次就試著勾選處理了。

如果在一開始上傳 binary 前選 Dose this app use the Advertising Identifier (No) 時,上傳 binary 時,驗證過程會看到類似的訊息:
Improper Advertising Identifier IDFA Usage. Your app contains the Advertising Identifier IDFA API ...
解法在此刻只能遞交一份空專案,接著在 Reject by developer 後,才能再重新填這張單子。

簡言之,在 Admob 而言,就是勾選三項:
  • Does this app use the Advertising Identifier (Yes)
  • Serve advertisements within the app (checked)
  • Limit Ad Tracking setting in iOS (checked)
不過,話說那最後一條真的是背書啊 Orz 亂用第三方 libraries 挺抖的。