顯示具有 linux 標籤的文章。 顯示所有文章
顯示具有 linux 標籤的文章。 顯示所有文章

2014/10/29

使用 Docker


Docker 是基於 LXC(Linux Container)的一個工具,
Docker 妥善運用了 LXC,並提供了一個友善的操作介面(Command Line)以及額外的功能。

---

# LXC

先了解一下 LXC:
LXC is a userspace interface for the Linux kernel containment features.
Through a powerful API and simple tools, it lets Linux users easily create and manage system or application containers.
LXC is often considered as something in the middle between a chroot on steroids and a full fledged virtual machine.
The goal of LXC is to create an environment as close as possible as a standard Linux installation but without the need for a separate kernel.

LXC 是一個讓你可以輕鬆操作 userspace 的工具,只要你的 Linux kernel 支援 LXC,就可以透過 LXC 封裝 kernel 層以外的任何東西。

我舉一個比較糟糕的例子來說明:

想像 Linux 作業系統就是一個煮東西的大鍋子,你想要用鍋子煮出什麼東西,就要往鍋子裡加什麼料。
你加了 Apache,加了 MySQL,加了 PHP;接著又加了 Ruby,加了各式 Ruby gems;加了 Python,加了各種 Python eggs …
於是大鍋子漸漸開始變成了大雜燴,各種食材的味道開始互相影響。

LXC 就像是在大鍋子上面加了一個大蒸架(LXC API),讓你可以放置各種容器(Container)盛煮各種料理(Packages,Programs)。
Docker 就是讓你可以非常簡單地使用這個蒸架,放置這些各別的料理容器,以及其他一些額外的好用功能(例如 docker pull)。



Reference:
https://linuxcontainers.org/
http://zh.wikipedia.org/wiki/LXC
http://en.wikipedia.org/wiki/UnionFS

---

# Docker 基礎

Docker 有 Server 端跟 Client 端。

Docker Server 端的主機也叫做 Docker Host;
Docker Server 預設透過 2375 跟 2376 port 提供 Docker REST API。
Docker Client 可以透過 Docker REST API 操作 Docker Server 上的 Docker images 或 containers。

image 跟 container 可以想像成這樣:

image 就是事先準備好的料理容器,這些容器是五花八門的。
它可以是乾乾淨淨的料理容器(精簡安裝的 Ubuntu、CentOS、FreeBSD 等),
它也可以事先放了幾杯水、加了幾勺鹽巴(安裝了 Apache、MySQL 等)。
這些料理容器(image)都可以直接拿來放到架上蒸煮(執行),
image 每次被執行時,會將它自己當成藍本,複製產生一個 container,
執行中的 container 可以持續改變(被料理),而 image 則一直以本來的樣子存在著。

container 是 Docker 執行(docker run 指令)時,以指定的 image 為藍本,產生出來的。
image 可以看成是虛擬機的硬碟檔(例如 VirtualBox 的 vdi 檔,或 Vagrant 的 box 檔),
container 就是根據某個指定的硬碟檔複製產生的虛擬機,產生這個虛擬機的成本是很低的。
執行中的 container 可以看成是開機運行中的虛擬機,可以使用 docker ps 指令查看;
執行完畢的 container 就是已經關機的虛擬機,可以使用 docker ps -a 指令查看。

container 可以透過 docker commit 指令轉換成 image,
相當於將運行到某個階段虛擬機 snapshot 起來,並匯出變成一個虛擬機硬碟檔。

剛開始使用時,Docker Client 跟 Docker Server 通常會在同一臺主機上。
在 Ubuntu 中安裝 Docker Client(docker.io)跟 Docker Server(lxc-docker)是非常簡單的:

1. sudo apt-get update
2. sudo apt-get install docker.io
3. sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
4. sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
5. sudo sh -c "echo deb https://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list”
6. sudo apt-get update
7. sudo apt-get install lxc-docker

正常來說,安裝完 lxc-docker,就會自動啟動 Docker Server,可以執行 sudo docker info 指令來確認。

因為 docker daemon(Docker Server)預設使用 root 權限啟動的,
所以透過 Docker Client 對它進行操作時,通常都要加上 sudo 命令。
http://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo

先檢查本機有哪些可用的 image:
sudo docker image

搜尋遠端是否有自己感興趣的 image:
sudo docker search ubuntu

將遠端的 image 複製到本地端:
sudo docker pull ubuntu

以 ubuntu image 為基礎,創建一個 container,並進入這個 container 的 shell;
相當於使用 ubuntu image 創建一台虛擬機,並登入這台虛擬機的 console:
sudo docker run -i -t ubuntu

接著在 container 的 shell 中,就可以跟平常操作 Ubuntu 一樣進行使用了。
使用告一段落後,如果使用 exit 指令離開,這個 container 就會結束執行(相當於虛擬機關機),
想要離開 container 的 shell,但是讓它保持執行,可以先按 Ctrl + P,再按 Ctrl + Q 離開。

顯示執行中的 container(container 對於 Docker 而言就像是 process):
sudo docker ps

顯示全部的 container:
sudo docker ps -a

啟動沒有執行的 container:
sudo docker start {container id}

接續回到執行中的 container 的畫面:
sudo docker attach {container id}

將進行到某個階段的 container 轉成 image:
sudo docker commit {container id} {image name}

移除 container:
sudo docker rm {container id}

移除 image:
sudo docker rmi {image name}

執行一個 container,將它的 80 port 對應到 Docker Host 主機的 8080 port,並將 Docker Host 的 /www 共享到 container 的 /var/www/ 目錄:
sudo docker run -i -t -p 8080:80 -v /www:/var/www ubuntu

Reference:
https://docs.docker.com/articles/basics/
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-getting-started
http://slopjong.de/2014/09/17/install-and-run-a-web-server-in-a-docker-container/

---

# Docker Best Practice

2013/05/22

Git 使用手冊

本篇文章以 Markdown 編寫,較佳的閱讀體驗請前往:
http://zx1986.github.io/blog/using-git.html

[Git][1] 是一套版本控制系統(Version Control System),
常用在對程式碼或文件進行版本管理及協作。
從前比較常用的版本控制系統是 SVN(Subversion),
但 SVN 是中央式的,而 Git 是分散式的,
且 Git 比 SVN 強大、先進許多。

我簡單解釋版本控制的概念,請想像一下:

你電腦內的資料夾類似一個書櫃,書櫃裡有許多書(檔案),
偶而有新書進來(新增檔案),有舊書捐出去(刪除檔案),
有時候會在某些書上作筆記、寫心得、畫畫(檔案內容變動)。

你在書櫃的側邊貼上一張「大大的白紙」,對書櫃裡的所有變動作紀錄。

紀錄新書擺入的時間,擺放的位置,甚至後面加個註記:『購於網路拍賣』;
紀錄舊書清除的時間,原本的位置,加個註記:『捐給讀書會』;
紀錄某書寫入筆記的時間,筆記的內容,心得或隨手塗鴉;
紀錄 ......

你可以把這張書櫃側邊貼著的「大大白紙」想像成版本控制系統(Git),
而且版本控制系統(Git)做的記錄會更鉅細靡遺。

當你對一個資料夾啟用 Git 進行追蹤管理與控制時(Git 初始化時),
Git 程式會在該資料夾底下新增一個名為「.git」的隱藏資料夾,
「.git」類似於前面提到那張「大大的白紙」,裡面紀錄了檔案的變化史。
Git 會對該資料夾內所有的檔案與其底層的所有資料夾進行紀錄追蹤,
而追蹤、記錄的結果都會儲存到「.git」這個資料夾內。

不過,Git 並不會主動記錄,必須是由使用者操作它去執行記錄的動作。
使用者類似史官的角色,而 Git 則是書寫史冊的工具。

Git 背後的運作方式是非常聰明而複雜的,
它的功能也不僅僅在於記錄(還有恢復、合併、差異處理等等)。

團隊合作時,同樣一個文件,在你手上跟在他人手上,可能有不一樣的變化史。
當你的檔案要與他人的合併時,內容有出入的地方,Git 會協助進行處理。
(例如開發同一個程式,你寫的 code 可能被他人改動,或反之。)

### 安裝與設定 Git

Ubuntu 底下安裝 Git 非常簡單,只要在終端機執行:
sudo apt-get install git-core git-doc
接着,建議執行以下指令,將系統預設編輯器設定為 Vim:
sudo update-alternatives --config editor
每個使用者帳號都會有自己的 Git 設定檔,通常是:
~/.gitconfig
例如我的設定檔內容是:
[user]
name = 張旭
email = zx1986@gmail.com

[color]
diff = auto
初始化 Git
(資料夾內會多出一個名為 .git 的隱藏資料夾):
git init
之後只要每次修改或新增檔案後,
執行以下兩個指令,Git 就會做一次紀錄:
git add 修改或新增的檔案名
git commit -m '關於此次修改的描述訊息'
可以開一個新的資料夾進行練習:
mkdir test
cd test
touch hello
git init
git add hello
git commit -m 'hello, Git!'
好了,您已經開始在使用 Git 啦!

### Git 輔助說明

需要注意,Git 不會把空的資料夾加入控管,
例如 log、cache 這類資料夾,我們通常不會想要追蹤裏面的檔案,
但還是需要這個資料夾存在,可以在底下建立一個隱藏檔,例如 .gitkeep:
cd log
tocuh .gitkeep
在跟「.git」同一層的目錄中,可以建立一個 .gitignore 檔案。
.gitignore 用來設定「不希望被 Git 控管的檔案與資料夾」。
一個簡單的 .gitignore 內容可以是這樣:
cache/
log/*.log
tmp/
*.tmp
*.swp
*.o
*.so
*.a
*.exe
*~
執行 `git help` 會顯示常用的 Git 指令與簡單說明:
add        Add file contents to the index
bisect     Find by binary search the change that introduced a bug
branch     List, create, or delete branches
checkout   Checkout a branch or paths to the working tree
clone      Clone a repository into a new directory
commit     Record changes to the repository
diff       Show changes between commits, commit and working tree, etc
fetch      Download objects and refs from another repository
grep       Print lines matching a pattern
init       Create an empty git repository or reinitialize an existing one
log        Show commit logs
merge      Join two or more development histories together
mv         Move or rename a file, a directory, or a symlink
pull       Fetch from and merge with another repository or a local branch
push       Update remote refs along with associated objects
rebase     Forward-port local commits to the updated upstream head
reset      Reset current HEAD to the specified state
rm         Remove files from the working tree and from the index
show       Show various types of objects
status     Show the working tree status
tag        Create, list, delete or verify a tag object signed with GPG
在 Git 指令後加上 -h 參數,能夠查詢該指令詳細的用法,例如:
git add -h
git commit -h
git pull -h
git push -h
要查詢更完整的指令手冊,則執行:`git help 指令名稱`

### 練習 Git

我推薦一個非常棒的線上練習:[Try Git](http://try.github.io)

這是由線上學習網站 [Code School](http://codeschool.com) 開發的,
他們還有一個 Git Real 的系列課程,我也非常推薦,
但 Git Real 系列課程是需要收費的。

Try Git 會帶着你練習基礎的 Git 指令,
畫面上半部是簡單明瞭的指令與情境說明,
畫面中間是一個模擬的 Console 端介面,
畫面下半部是當前情境下資料夾內的狀況。
雖然內容都是英文,但用字遣詞並不難,
就當成是玩電動闖關,邊玩邊學。

當進行到 Remote Repositories 這個關卡時,
如果對 Repository、Local、Remote 不大瞭解,
可以再回來這,繼續閱讀後面的內容。

### 關於 Git Repository 與 Branch

被 Git 所管理的專案,就是 Git Repository(倉儲)。
簡單點說,一個含有「.git」的資料夾,就是一個 Git Repository。
而一個 Git Repository 內,可以建立很多 Branch(分支),
不同的分支代表不同的變化史。

分支是可以任意建立、刪除、合併的。

Git Repository 裡預設的 Trunk Branch(主幹)稱為「master」,
其他的 Branch(分支)則由使用者自行命名,
master 這個 branch 也是可以被改成其他名字的。
(其實 Git 的世界並沒有 Trunk 這種講法,那是 SVN 的習慣,
在 Git 的世界,應該說那是“一個被叫做 master 的 branch”。)

Git 是一個分散式的版本控制系統,不同於 SVN 的 Server/Client 架構,
Git 不需要像 SVN 必須有一個 Repository Server 作為主要的倉儲伺服器。
Git 預設就可以使用 ssh 互相進行 Repository 傳輸了。

當使用 git clone 指令從遠端複製一個 Git Repository 到本地端電腦上時,
遠端的 Git Repository 通常稱為「origin」,「origin」可能有若干的 branch。
本地端 Git Repository 沒有特別的名稱,本地端也有自己的 branch。

`git remote -v` 指令可以查詢當前 Git Repository 的遠端來源。

假設一個簡單的應用情境:

假設遠端的電腦叫做 Remote;本地端的電腦叫做 Local。
Remote 上面有一個 Git Repository 資料夾叫做 remote_repository。

要將 remote_repository 複製到 Local 並命名為 local_repository,
在 Local 執行:
Local$ git clone 「Remote 使用者帳號@Remote 位址」:「remote_repository 在 Remote 上的路徑」   local_repository
如果您執行過 scp 指令,相信對這個 git clone 格式會覺得很熟悉。

複製完成(git clone)後,Local 與 Remote 已經可以分開獨立工作了。
Git 不必拘泥於一定要把修改過的檔案存回當初取得檔案的地方。
Remote 可以在 remote_repository 裡發展它的檔案;
Local 可以在 local_repository 裡發展它的檔案。

等到哪天 Remote 突然想取得並合併 Local 發展的檔案,
可以在 Remote 上執行:
Remote$ git pull 「Local 使用者帳號@Local 位址」:「local_repository 在 Local 上的路徑」
當然,如果 Local 想取得與合併其他人發展的檔案,
可以在 Local 上執行:
Local$ git pull 「使用者帳號@位址」:「路徑」

* 補充說明

git fetch - Download objects and refs from another repository.
git merge - Join two or more development histories together.
git pull - Fetch from and merge with another repository or a local branch.

`git pull` 等於先執行了 `git fetch`,然後再自動執行 `git merge` 。
[有前輩建議][4]少用 `git pull`,改用 `git fetch` 搭配 `git merge` 。
[也有前輩建議][5]應當多使用 `git rebase` 或 `git pull --rebase` 。

### SVN 式的往日時光

之前,我在不同的電腦上修改程式:研究室的電腦、宿舍的電腦、筆記型電腦。
因此我在研究室的一台主機上架了 SVN 伺服器,程式主要版本儲存在 SVN 伺服器上。
每當在不同的電腦進行程式編輯時,會先從 SVN 伺服器上抓最新版本的程式下來。
編輯告一段落後,再把修改過的程式上傳回 SVN 伺服器。
程式集中在一台 SVN 伺服器上,要編輯時從上面更新下來,編輯完再更新回去。

從 SVN 轉換到 Git 時,會很習慣於從前 SVN 那種模式:

1. 使用 svn checkout 從 SVN 伺服器將整個 Repository 複製到本機端。
2. 本機端對 Repository 的內容進行編輯、修改、新增、刪除等等。
3. 使用 svn update 檢查 SVN 伺服器有沒有其他更新與自己修改的內容有衝突。
4. 解決內容衝突的情況。
5. 使用 svn commit 將自己本機端的所有修改上傳到 SVN 伺服器。

怎麼用 Git 做到類似 SVN 那樣的情形?
有個簡單的方法。

首先,選定一台要當 Repository Server 的機器,假設叫 Server。
在 Server 開一個空的資料夾,假設叫 origin,並切換到該資料夾下。
Server$ mkdir origin
Server$ cd origin
在空資料夾底下執行:
Server$ git init --bare
這個動作會產生一個 [Bare Git Repository][2],
該資料夾下會產生:
branches/
config
description
HEAD
hooks/
info/
objects/
refs/
本地端的電腦,假設叫 Local。
Local 上一個叫 local_project 的資料夾要上傳到 Server 進行統一管理。

切換到該資料夾底下,執行:
Local$ git add .
Local$ git commit -a -m 'initialization'
Local$ git remote add origin 「Server 使用者帳號@Server 位址」:「Server 上 origin 資料夾的路徑」
Local$ git push origin master
完成以後,其他的電腦就可以使用以下指令,
從 Server 上的 origin 複製 local_project 的內容:
Other$ git clone 「Server 使用者帳號@Server 位址」:「Server 上 origin 資料夾的路徑」 「自訂的資料夾名稱」
其他電腦要將其修改的內容傳回 Server,可以執行:
Other$ git push origin master

### Git Repository Hosting

Git Repository 除了使用 git 協定或 ssh 協定,
還可以使用 http、https 等方式傳輸、瀏覽、管理。
如果不想要用簡單的 Bare Git Repository 架設 Repository Server,
有些 Open Source 的工具可以選擇:

- [Gitosis](https://github.com/res0nat0r/gitosis)
- [Gitorious](http://gitorious.org/)
- [Gitlab](http://gitlab.org/)

全世界最知名的 Git Repository Hosting 網站:

- [Github](https://github.com/)

中國大陸版的 Github:

- [GitCafe](https://gitcafe.com/)

Github 與 GitCafe 都非常棒,
它們的使用教學也有很多 Git 技巧可以參考:

https://help.github.com/
https://gitcafe.com/GitCafe/Help

GitCafe 的 Git [作弊表][3]。

_Git Cheating Sheet_

git init         # 將當前資料夾進行 Git 初始化

git add .        # 將當前資料夾內所有檔案加入 Git 追蹤(tracking 或 staging)
git add 檔案名稱 # 把當前資料夾內某個檔案加入 Git 追蹤(tracking 或 staging)

git status       # 查詢從上一次 commit 到現在,資料夾裡有哪些變化,各個檔案處於什麼狀況

git commit -a         # 將目前的變動送繳 Git 進行紀錄,會進入編寫修改訊息的畫面
git commit -a -m "*"  # commit 時直接寫入修改訊息,不進入編寫修改訊息的畫面

git tag v1.0          # 將當前 commit 過後的檔案版本命名為 v1.0

git diff                             # 比較所有檔案的內容與上一次 commit 時有何差異
git diff v1.0 v2.0                   # 比較 v1.0 與 v2.0 兩個版本間所有檔案的內容
git diff v1.0:檔案名稱 v2.0:檔案名稱 # 比較 v1.0 與 v2.0 兩個版本間某個檔案的內容

git log                         # 查詢所有版本的修改狀況,顯示各版本的 hash 編號
git log -p                      # 查詢哪幾行被修改
git log --stat --summary        # 查詢每個版本間變動的檔案跟行數

git show v1.0                   # 查詢 v1.0 版裡的修改內容
git show v1.0:檔案名稱          # 查詢某個檔案在 v1.0 時的內容

git show HEAD          # 看此版本修改的資料
git show HEAD^         # 看此版本前一版的修改的資料
git show HEAD^^        # 看此版本前前一版的修改的資料

git grep "*" v1.0      # 查詢 0.01 版裡頭有沒有某些內容
git grep "*"           # 查詢現在的版本裡有沒有某些內容

git branch                # 查看現有的分支
git branch 分支名稱       # 建立新的分支
git branch 分支名稱 v1.0  # 依照 v1.0 版本裡的內容來建立一個分支
git branch -d 分支名稱    # 刪除某個分支

git merge 某個分支名稱    # 將當前所在的分支與某個分支合併,如果出現衝突,會紀錄在有衝突的檔案中

git checkout master       # 切換到主幹上
git checkout 分支名稱     # 切換到某個分支上

git checkout HEAD         # 將所有檔案恢復到上次 commit 的狀態
git checkout -- 檔案名稱  # 將某個檔案恢復到上次 commit 的狀態

git reset --hard 某個版本的 hash 編號   # 整個 Repository 恢復到某個版本的狀態

git count-objects     # 分析 Git 資料庫狀況,計算鬆散的物件
git gc                # 維護 Git 資料庫,重組物件
git fsck --full       # 應該是類似 Git 磁碟重組之類的東西

Reference:
http://github.com/schacon/whygitisbetter
http://git-scm.com/documentation
http://gitcafe.com/riku/GitTips
http://gitimmersion.com/
http://gitref.org
http://rypress.com/tutorials/git/

[1]: http://git-scm.com/
[2]: http://www.saintsjd.com/2011/01/what-is-a-bare-git-repository/
[3]: https://gitcafe.com/GitCafe/Help/blob/master/Git/Git_Cheat_Sheet.md
[4]: http://longair.net/blog/2009/04/16/git-fetch-and-merge
[5]: http://ihower.tw/blog/archives/3843

2012/07/15

Haskell

apt-get install haskell-platform

http://hackage.haskell.org/platform/linux.html
http://www.vex.net/~trebla/haskell/haskell-platform.xhtml
http://www.haskell.org/ghc/

http://yannesposito.com/Scratch/en/blog/Yesod-tutorial-for-newbies/

2012/07/14

RHEL 6 安裝 LDAP



同事 Peter Lai 寫了篇非常清楚的 LDAP Wiki,一定要 Open Source 一下的!
LDAP 服務
LDAP 為輕量級名錄存取協定(Lightweight Directory Access Protocol)的簡稱。
若要簡單的說,LDAP是一種存取資料的方式。 LDAP 伺服器存放著特定格式的資料,提供給許多下游來查詢。 我們可將 LDAP 視為一種特別的資料庫,只是它存放資料的方法較為不同。
名錄資訊樹與項目
LDAP 中所儲存的資料被稱為名錄資訊樹(Directory Information Tree, DIT), 是由多個項目(entry)以階層方式所組成的樹狀資料結構。
物件類別與屬性
每一個項目可以被指派至少一個以上的的物件類別(objectClass), LDAP 已經內建許多物件類別,以供設計出不同類型的項目。
舉例來說,當我們需要設計一個項目用以存放組織或單位資訊,就可指派內建的 organizationalUnit 物件類別給該項目; 若是我們需要有關存放人事資料的資訊,例如員工基本資料,內建的 person 物件類別便是個不錯的選擇。 當然,LDAP 也支援自訂的物件類別。
不同的物件類別可以賦予擁有該類別的項目不同的屬性群(attributes) 在這些屬性群中,有些屬性是一定要存在的,稱為必要屬性(MUST attribute) 而其他不一定要存在的的則稱為選用屬性(MAY attribute) 屬性的值便是我們會在 LDAP 中儲存的資料。
如圖1-2,我們可以看到項目 D 被指派的物件類別為 person 而 person 物件類別被定義可擁有的屬性有: cn, sn, userPassword, telephoneNumber, seeAlso, description,其中 cn 與 sn 為必要的屬性。 值得一提的是,一個 DIT 的根項目(此例中的項目A),必須指派為 domain 物件類別,其必要屬性 dc 屬性。
相對識別名稱與識別名稱
每一個項目都都會有個自己的名字,稱作 相對識別名稱(relative distinguished name, RDN) 是取用項目數個(通常只用一個)屬性名稱與屬性值作為該項目的 RDN
例如項目 D 的 RDN 便可取作 “cn=Peter Lai”(cn 指的是 commonName) 此外,每一個項目在整個 DIT 中亦具有一個 唯一 的名字,稱為 識別名稱(distinguished name, DN) DN 是取用自根項目至該項目中所有項目節點之 RDN,將其以逗號(,)串接而成的字串。
如圖 1-3,我們假設: 項目 A 的 RDN 為 “dc=cwb,dc=gov” 項目 B 的 RDN 為 “ou=mfc”(ou 指的是 organizationUnit) 項目 D 的 RDN 為 “cn=Peter Lai” 則項目 D 的 DN 便為 “cn=Peter Lai,ou=mfc,dc=cwb,dc=gov”
在 DIT 中,項目間的 RND 可能也可以重複,但是 DN 必定是唯一的。 藉由 DN 我們可以找到 DIT 中特定的項目,再取出其中某個屬性值來取得資料。

yum install openldap openldap-clients openldap-servers
yum install httpd php php-ldap
yum insatll phpldapadmin

Reference:
http://tutarticle.com/linux/rhel-6-ldap-server
http://serverfault.com/questions/323497/how-do-i-configure-ldap-on-centos-6-for-user-authentication-in-the-most-secure-a

2012/07/06

gitflow

git-flow 下載:

git clone https://github.com/nvie/gitflow.git


git-flow 有綁一個 submodule 叫 shFlags(https://github.com/nvie/shFlags)
必須執行以下指令來設定:

git submodule init && git submodule update


如果無法執行 git submodule update
可以直接切換到剛 clone 下來的 gitflow 內,手動下載 shFlags:

cd gitflow
rm -rf shFlags
git clone https://github.com/nvie/shFlags.git


git-flow 安裝:

cd gitflow
sudo make install


使用說明:
http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/
http://codesherpas.com/screencasts/on_the_path_gitflow.mov
http://vimeo.com/16018419

Reference:
01. https://github.com/nvie/gitflow
02. http://ihower.tw/blog/archives/5140
03. https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh

2012/06/15

導致 PHP 語法錯誤的 xml 標籤

處理到一個很奇怪的問題。

有個負責 echo 出 xml 內容的 php 程式,一直出現語法錯誤:
Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING your_file.php on line 123

your_file.php 是在 Windows 環境來的,在 Linux 內使用 Vim 開啓時,行尾會出現 Windows 的蠢符號 ^M

我如同往常一樣使用以下指令將 ^M 清除:
:%s/^M//g
(^M 是壓 Ctrl + V 再壓 Ctrl + M 的效果)

但是 123 行一直報錯,123 行的 php code 類似這樣:
<p id="$_GET['id']">

如果把 123 行註解掉,在 Vim 內的重新輸入一模一樣的內容,就 ok 了!
看起來是有些神祕的行尾符號,人類的肉眼無法察覺,待查 .....

Vim 有沒有好的外掛顯示 space、tab、break 啊!?

熱心的朋友們給了許多解法:
曼珠:":set invlist"可達到要求嗎?我自己試用是看的到行尾的 $,但我沒有其他的不可見符號所以沒辧法進一步測試。原來 :set invlist 是 invert list 的簡寫(等同 :set list!),而查詢 'list' 後發現他能顯示 ^I 和行尾,但對於其他不可見字元就沒多寫了,所以可能要再查。

雲端CrBoy+:把那行複製出來塞進新的檔案 用 hexdump 去看!

__CA__.py:vim -b abc.php ?

Chester Chang:try hex editor

Reference:
http://www.perturb.org/display/679_Make_Vim_show_hidden_characters.html
http://grx.no/kb/2008/11/17/remove-windows-line-endings-in-vim/
http://www.grok2.com/blog/2010/04/21/getting-rid-of-m-ctrl-m-characters-in-windows-text-using-vim/
http://stackoverflow.com/questions/799417/gvim-showing-carriage-return-m-even-when-file-mode-is-explicitly-dos

====================================================

後來發現根本不是行尾的問題!

該 php 檔中混合了 php tag 與 xml tag,例如:
<?php
    // code
?>
<?xml version="1.0" encoding="UTF-8" ?>
<?php 
    // code
    echo $XML 
?>

如果修改成以下格式,將 xml tag 使用 heredoc 輸出就正確了:
<?php
    // code

    echo <<<HERE
<?xml version="1.0" encoding="UTF-8" ?>
 HERE

    // code
    echo $XML 
?>

看起來是 php 與 xml 的 tag 讓 Web Server 混亂了,不是行尾有問題 ....

2012/05/30

設定 Apache 與網頁的字元編碼

http://httpd.apache.org/docs/2.0/mod/core.html#adddefaultcharset
http://stackoverflow.com/questions/913869/how-to-change-the-default-encoding-to-utf-8-for-server
http://www.askapache.com/htaccess/setting-charset-in-htaccess.html
http://rackerhacker.com/2007/11/15/change-the-default-apache-character-set/

http://www.w3.org/TR/html4/charset.html#h-5.2
http://en.wikipedia.org/wiki/Character_encodings_in_HTML
http://www.w3schools.com/html5/att_meta_charset.asp

http://tlt.its.psu.edu/suggestions/international/web/tips/declare.html
http://www.i18nguy.com/markup/serving.html#tip01
http://www.personal.psu.edu/ejp10/blogs/gotunicode/2009/02/when-apache-and-utf-8-fight.html

2012/04/05

Ubuntu 的 ATi 驅動

https://wiki.ubuntu.com/X/Troubleshooting/FglrxInteferesWithRadeonDriver
https://help.ubuntu.com/community/RadeonDriver

我的 laptop 有一張非常古怪的顯示卡:ATI Mobility Radeon X2300
ATi 對 Linux 本來就很不友善了,再加上這張怪卡,更有得煩了。
lspci -nn | grep VGA
01:00.0 VGA compatible controller [0300]: ATI Technologies Inc Mobility Radeon X2300 [1002:718a]
我的環境是 Ubuntu 11.10 i386,先來認識一些名詞。

[Mesa]
Mesa is a software library for 3D computer graphics that provides a generic OpenGL implementation for rendering three-dimensional graphics on multiple platforms.

[Radeon Driver]
Open Source driver for many ATI graphics cards called "radeon" or "ati". It will provide 2D and 3D acceleration in your video hardware. This driver is not as fast as the closed-source, proprietary "fglrx" driver from AMD/ATI Inc. for some cards, but has better dual-head support, and supports some older chipsets that fglrx does not.

[Catalyst | fglrx]
fglrx is a proprietary, Linux binary-only driver for ATI graphic chips with support for 3D acceleration. fglrx is the name of the Linux display driver used for ATI Radeon and ATI FireGL family of video adapters and stands for "FireGL and Radeon for X". It contains both free and open-source and proprietary parts.

=== fglrx ===

fglrx 就是 Catalyst for Linux
ATi 很小氣,不願意開放它的驅動原始碼,只提供編譯好的二進位驅動檔給 Linux OS
每個不同的 Linux 發行版再自行打包它們的 ATi Driver,就是 fglrx(FireGL and Radeon for X)
你看 ATi 取的這爛名字 ....

fglrx 雖然還有其他問題:
http://www.thinkwiki.org/wiki/Problems_with_fglrx
http://askubuntu.com/questions/78906/ati-amd-proprietary-fglrx-graphics-install-fails-how-can-i-resolve-the-problem

但是大家最推薦、最簡便的解法還是使用 fglrx

不管是透過 PPA 使用 apt-get 安裝:
https://launchpad.net/~ubuntu-x-swat/+archive/x-updates
https://launchpad.net/~xorg-edgers/+archive/ppa

或下載官方原始檔來編譯安裝(ATi Radeon 系列):
http://support.amd.com/us/gpudownload/linux/previous/Pages/radeon_linux.aspx

只是根據硬體支援清單,我的 Radeon X2300 看起來已經不被新版的 fglrx 支援了:
http://wiki.cchtml.com/index.php/Hardware#Not_Yet_Supported_or_Unoffically_Supported

我測試了 apt-get 安裝的 fglrx:
sudo apt-add-repository ppa:ubuntu-x-swat/x-updates
sudo apt-add-repository ppa:xorg-edgers/ppa
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install fglrx fglrx-amdcccle
sudo apt-get install fglrx-updates fglrx-amdcccle-updates
sudo apt-get update
sudo apt-get upgrade
也測試了官方不同版本的的原始檔安裝:
ati-driver-installer-9-3-x86.x86_64.run
ati-driver-installer-10-12-x86.x86_64.run
ati-driver-installer-11-10-x86.x86_64.run
ati-driver-installer-11-12-x86.x86_64.run

=== Radeon Driver ===

使用 apt-cache search radeon,找到下列套件:
xserver-xorg-video-ati - X.Org X server -- AMD/ATI display driver wrapper
xserver-xorg-video-ati-dbg - X.Org X server -- AMD/ATI display driver wrapper (debugging symbols)
xserver-xorg-video-radeon - X.Org X server -- AMD/ATI Radeon display driver
xserver-xorg-video-radeon-dbg - X.Org X server -- AMD/ATI Radeon display driver (debugging symbols)
radeontool - utility to control ATI Radeon backlight functions on laptops

fglrx-amdcccle-updates - Catalyst Control Center for the AMD graphics accelerators
fglrx-amdcccle - Catalyst Control Center for the AMD graphics accelerators
fglrx-updates - Video driver for the AMD graphics accelerators
fglrx-updates-dev - Video driver for the AMD graphics accelerators (devel files)
fglrx - Video driver for the AMD graphics accelerators
fglrx-dev - Video driver for the AMD graphics accelerators (devel files)

libdrm-radeon1 - Userspace interface to radeon-specific kernel DRM services -- runtime
libdrm-radeon1-dbg - Userspace interface to radeon-specific kernel DRM services -- debugging symbols

根據 https://help.ubuntu.com/community/RadeonDriver
看起來 Radeon Driver 另外一個可以嘗試的選擇。

If you've previously installed the ATI binary/proprietary driver (a.k.a Catalyst/fglrx), you need to make sure it's fully purged before trying to use the open-source ati/radeon driver.
sudo apt-get purge fglrx*
sudo apt-add-repository ppa:xorg-edgers/ppa
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install xserver-xorg-video-ati* xserver-xorg-video-radeon* radeontool

但是,在使用 Chrome 或 Firefox 搭配 Flash 時,gnome 經常會當掉,很糟糕。
將 Flash 套件移除之後,目前還沒有出現當幾狀況!COOL!

Reference:
http://www.hardwareheaven.com/modtool.php
http://ubuntuforums.org/showthread.php?t=1556555
http://ubuntuforums.org/showthread.php?t=1250530
http://wiki.cchtml.com/index.php/Ubuntu_Oneiric_Installation_Guide
http://en.wikipedia.org/wiki/AMD_Catalyst
http://maketecheasier.com/install-custom-gnome-shell-themes/2011/09/27
http://mrrichard.hubpages.com/hub/How-to-Install-FGLRX-in-Ubuntu-1010
https://wiki.ubuntu.com/X/Troubleshooting/FglrxInteferesWithRadeonDriver
https://help.ubuntu.com/community/BinaryDriverHowto/ATI
https://help.ubuntu.com/community/RadeonDriver
https://help.ubuntu.com/community/RadeonHD
http://mrrichard.hubpages.com/hub/How-to-Install-FGLRX-in-Ubuntu-1010
http://support.amd.com/us/gpudownload/linux/previous/Pages/radeon_linux.aspx
http://askubuntu.com/questions/124292/what-is-the-correct-way-to-install-ati-catalyst-video-drivers-fglrx/129200#129200
http://askubuntu.com/questions/71457/how-can-i-set-up-dual-monitor-display-with-ati-driver

2012/04/02

在 RHEL 6 安裝 MySQL Cluster

各個 MySQL Cluster 套件的描述:
MySQL-Cluster-server-gpl.x86_64 : a very fast and reliable SQL database server
MySQL-Cluster-client-gpl.x86_64 : MySQL Cluster - Client
MySQL-Cluster-devel-gpl.x86_64 : Development header files and libraries
MySQL-Cluster-embedded-gpl.x86_64 : embedded library
MySQL-Cluster-gpl-shared-compat.x86_64 : MySQL shared client libraries for MySQL 5.1.61-1, 5.0.95-1, 4.1.23-0, 4.0.27-0
MySQL-Cluster-shared-compat-gpl.x86_64 : MySQL shared client libraries for MySQL 5.1.61-1, 5.0.95-1, 4.1.23-0, 4.0.27-0
MySQL-Cluster-shared-gpl.x86_64 : Shared libraries

http://forums.mysql.com/read.php?25,519007,519073
This one package replaces the following packages from previous versions.

$ rpm -qp --obsoletes MySQL-Cluster-server-gpl-7.2.4-1.el6.x86_64.rpm
MySQL-Cluster-server
MySQL-Cluster-management
MySQL-Cluster-storage
MySQL-Cluster-extra
MySQL-Cluster-tools
# MySQL-Cluster-server 中即包含了以上幾個舊版的 rpm 內容

[角色]

MySQL Cluster 內有三種角色:
Management Node
MySQL Node
Data Node

三種角色可以分別由三臺(或者三臺以上)的主機來擔任,也可以是一臺主機擔任三種角色。
三種角色是不會互相衝突的,亦即不同角色可以共存在同一臺主機中。
但是,傳統的 MySQL 及其相關的 lib 不可以混在 MySQL Cluster 的主機上。

Management Node 核心是 ndb_mgmd(ndb management daemon),


MySQL Node 核心是 mysqld(看起來很像是傳統單機版的 MySQL Server),


Data Node 核心是 ndbd(ndb daemon),

[安裝]

yum erase mysql* mysql-*
yum install MySQL-Cluster-server
yum install MySQL-Cluster-client

Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing     : MySQL-Cluster-server-gpl-7.2.4-1.el6.x86_64
                                                             
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h test-ndb-node02.mfc.cwb password 'new-password'

Alternatively you can run:
/usr/bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

Please report any problems with the /usr/bin/mysqlbug script!

[設定]

[管理]

2012/02/28

網路相關的 Linux 指令

此篇筆記主要是參照以下文章:
http://dougvitale.wordpress.com/2011/12/21/deprecated-linux-networking-commands-and-their-replacements/

文中提到,很多舊的網路相關指令雖然還是可以使用(而且很常用),但其實過時了(Deprecated)。
特別點出的老舊指令有:arp, ifconfig, iptunnel, iwconfig, nameif, netstat, route

作者將推薦的替代指令做成了表格給大家參考,非常用心。
我將自己常用的整理一下,完整的列表請閱讀原作者的 blog。

[arp]

ARP stands for Address Resolution Protocol. ARP is used to find the media access control address of a network neighbour for a given IPv4 Address. arp command manipulates or displays the kernel's IPv4 network neighbour cache. arp command can add entries to the table, delete one or display the current content.

簡單說,ARP 網路協定就是 MAC address 與 IP address 的 mapping,
而 arp 指令就是用來管理 Linux 主機上的 ARP table(或說 ARP cache)。

arp -a [host] 建議用 ip n 來取代,其中 n 代表 neighbor 的意思,應該很好理解。
arp -d [ip] 建議用 ip n del [ip] 來取代,就是刪除 ARP 表內指定的 IP 記錄。
arp -s 建議用 ip -stat n
arp -e

[ifconfig]

ifconfig 建議使用 ip a
ifconfig [interface] 建議使用 ip a show dev [interface]
ifconfig [interface] up 建議使用 ip link set [interface] up
ifconfig [interface] address [address] 建議使用 ip a add [ip_addr/mask] dev [interface]

[netstat]

ss:utility to investigate sockets.
通常預設 ss 會安裝,或使用 sudo yum install iproute 安裝。

netstat -a 換成 ss -a
netstat -l 換成 ss -l
netstat -t 換成 ss -t
netstat -u 換成 ss -u
netstat -s 換成 ss -s
netstat -n 換成 ss -n
netstat -N 換成 ss -r
netstat -r 換成 ip route
netstat -C 換成 ip route list cache

[route]

[iptunnel]

Reference:
http://dougvitale.wordpress.com/2011/11/28/troubleshooting-faulty-network-connectivity-part-1/
http://dougvitale.wordpress.com/2011/12/11/troubleshooting-faulty-network-connectivity-part-2-essential-network-commands/
http://www.study-area.org/network/network_ip_arp.htm
http://www.cyberciti.biz/tips/linux-investigate-sockets-network-connections.html
http://www.cyberciti.biz/files/ss.html

2011/12/21

Puppet

http://puppetlabs.com/

Puppet 是一個 Client/Server 式的[配置|設定|服務]管理工具,它是用 Ruby 寫的。

簡單講,所有(Linux)機器的配置集中管理在 Puppet Server 上,
Puppet Client 機器連線到 Server 上取得對應的配置,並根據其內容對自己進行設定。

Puppet 並不是 scp 一個設定檔回來然後 Apply。
Puppet Client 使用一套用 Ruby 寫的叫 facter 的工具取得主機基本資訊。
Puppet Server 根據傳來的資訊(ex:IP, OS, RAM, etc.)編譯出相對應的配置檔並回傳。

在 Ubuntu 系統上安裝 Puppet 非常簡單:
sudo apt-get install ruby-full # 安裝 Ruby 環境
sudo apt-get install facter # 安裝 Facter 後可以直接執行 facter 測試一下
sudo apt-get install puppet # Puppet Client 套件 
sudo apt-get install puppetmaster # Puppet Server 套件,Client 不需安裝

# 在 Redhat 環境,Puppet Client 套件叫:puppet
# 在 Redhat 環境,Puppet Server 套件叫:puppet-server

Puppet 看待裝置或服務的哲學跟 UNIX 很像:
每一個裝置、服務對 Puppet 來說,都是一個「資源(Resource)」。



【*.pp】

Puppet 解讀名爲 *.pp 的檔案,然後對不同的 Client 編譯產生不同的配置。
一個簡單的 test.pp 檔案內容如下:
file
{
    "/tmp/test.txt": content => "hello, world";
}
執行:
puppet test.pp
執行結果是在 /tmp 底下產生一個 test.txt 檔,且內容爲「hello, world」。
*.pp 有一套簡單的文法與規則,其中亦有類別跟繼承等,強烈建議閱讀文件瞭解!



【Puppet Client/Server 運作流程】

1」Puppet Client 的 puppetd 程式呼叫 facter 程式,facter 程式會偵測出 Puppet Client 主機的相關資訊,例如 hostname、RAM、Hard Disk、IP 等等。Puppet Client 的 puppetd 再透過“SSL”把這些訊息傳到 Puppet Server。

2」Puppet Server 的 puppetmaster 程式檢查 Puppet Client 送來的資訊,會使用 Puppet Client 的 hostname 來找到 /etc/puppet/manifest 裡面對應的 node 配置,然後分析以及解讀牽涉到的 *.pp 檔或 Puppet 程式碼,Puppet Client 使用 facter 生成的訊息會被當成變數傳入這些 *.pp 檔或 Puppet 程式碼。

3」當 Puppet Server 知道需要處理哪些 *.pp 檔後,就會將它們進行解析,這個 *.pp 檔解析的動作可以看成是程式的編譯(或是直譯?)。解析會分成幾個階段,首先是語法檢查,語法錯誤就會直接報錯了;語法檢查通過,會產生解析的結果(僞代碼檔?),這個結果同樣會透過 SSL 傳送回 Puppet Client。

4」Puppet Client 收到 Puppet Server 的解析結果,然後執行,並且把執行的結果回傳。

5」Puppet Server 把 Puppet Client 的執行結果寫到 log。



【Puppet Client/Server 配置】

Puppet Client 與 Puppet Server 的安裝、設定、配置,最好都使用 root 帳號。

進行 Client/Server 設置前,請務必千萬確定每臺主機的 hostname!
Puppet 的 Client/Server 配置有綁定 hostname 進行驗證。
Puppet 要求符合 FQDN 的 hostname。
請先執行 hostname 並檢查 /etc/hostname 進行確定。
並確認 /etc/hosts 檔案有正確的 hostname 與 IP 配對。

連線與驗證都需要 root 身份來進行。
Puppet Client 與 Server 的系統時間要校正一致,否則認證會出問題!
建議主機使用同樣的 NTP Server 進行時間同步。
請特別注意!

在 Client/Server 環境中,Puppet Server 預設讀取 *.pp 的路徑是:
/etc/puppet/manifests/

可以編寫一個 /etc/puppet/manifests/site.pp 檔測試:
node default
{
    file
    {
        "/tmp/puppet_server.message":
        content => "Hello, Puppet Client!";
    }
}

第一次進行 Client/Server 的配置連線會需要驗證。
先在 Puppet Client 執行:
puppetd --server 伺服器主機名稱 --test
再到 Puppet Server 執行:
puppetca --sign 客戶端主機名稱
最後回到 Puppet Client 執行:
puppetd --server 伺服器主機名稱 --test
此時,Puppet Client 應該會產生一個內容爲「Puppet Manifest」的 /tmp/site.txt 檔。



【Puppet CA 驗証】

Puppet 的驗證文件預設:
Puppet Client:/var/lib/puppet/ssl
Puppet Server:/var/lib/puppet/ssl/ca/

若驗證有問題,在該資料夾下找到相對應的 *.pem,刪除舊的 *.pem 檔後,重新認證。

puppetca --list --all
puppetca --list
puppetca --sign CLIENT_HOSTNAME
puppetca --print CLIENT_HOSTNAME
puppetca --clean CLIENT_HOSTNAME  # 刪除舊的認証
man puppetca



【建議的 /etc/puppet/ 目錄架構】
manifests/
        site.pp
        templates.pp
        nodes.pp

modules/
        {module_name}

modules/user/

services/

clients/

notes/

plugins/

tools/
來源:http://projects.puppetlabs.com/projects/1/wiki/Puppet_Best_Practice



【使用 Puppet Module】

來源:http://docs.puppetlabs.com/guides/modules.html



【使用 Puppet Template】

Puppet Template 可以用來動態產生不同的內容。
應用的情境比較像是同樣的設定檔,但是有些許的設定不盡相同。
例如都是 httpd 服務,不見得所有 Puppet node 的 httpd.conf 都完全相同。

Puppet Template 檔是使用 Ruby 的 ERB Template,並不難寫。
請參考:http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html

Puppet Template 的使用也很簡單:
$value = template("my_template.erb")
my_template.erb 可換成 erb 檔的絕對路徑,或把 erb 檔放到 Puppet 預設會找的路徑。
Red Hat 環境通常是 /var/lib/puppet/templates;
Ubuntu 環境通常是 /etc/puppet/templates。
可以使用 puppet --configprint templatedir 指令確認。
實作的建議是把 erb 檔放到各個 Module 資料夾中。

題外話,可以執行 puppet --configprint all 看看 :-)

來源:http://docs.puppetlabs.com/guides/templating.html



【Puppet 設定檔範例】

https://github.com/ghoneycutt/puppet-generic



【Puppet 名詞解釋】

catalog : A catalog is the totality of resources, files, properties, etc, for a given system.

manifest : A configuration file written in the Puppet language. These files should have the .pp extension.

module : A collection of classes, resource types, files, and templates, organized around a particular purpose.

node (general noun) : An individual server; for the purposes of discussing Puppet, this generally refers to an agent node.

node (Puppet language keyword) : A collection of classes and/or resources to be applied to the agent node whose unique identifier (“certname”) matches the specified node name. Nodes defined in manifests allow inheritance, although this should be used with care due to the behavior of dynamic variable scoping.

provider : A simple implementation of a type; examples of package providers are dpkg and rpm, and examples of user providers are useradd and netinfo. Most often, providers are just Ruby wrappers around shell commands, and they are usually very short and thus easy to create.

templates : templates are ERB files used to generate configuration files for systems and are used in cases where the configuration file is not static but only requires minor changes based on variables that Puppet can provide (such as hostname). See also distributable file.

type : abstract description of a type of resource. Can be implemented as a native type, plug-in type, or defined type.

agent or agent node : An operating system instance managed by Puppet. This can be an operating system running on its own hardware or a virtual image.

來源:http://projects.puppetlabs.com/projects/puppet/wiki/Glossary_Of_Terms



強烈推薦文件:
http://puppet.wikidot.com

Reference:
http://puppet-manifest-share.googlecode.com/files/puppet-1.0.pdf
http://www.comeonsa.com/category/puppet/
http://bitcube.co.uk/content/puppet-errors-explained
http://www.example42.com
http://docs.puppetlabs.com/guides/troubleshooting.html
http://docs.puppetlabs.com/guides/troubleshooting.html
http://blog.akquinet.de/2011/11/23/managing-an-apache-server-with-puppet/

2011/11/20

vsftpd

Very Secure FTP Daemon

yum install vsftpd
yum install libdb3-util

/etc/vsftpd/vsftpd.conf

Reference:
http://ubuntuforums.org/showthread.php?t=518293
http://ubuntuforums.org/showthread.php?p=3497743
http://www.linuxfocus.org/English/July2004/article341.shtml

2011/09/25

tmux 與 screen

sudo apt-get install tmux

tmux
# 啓動 Tmux

ctrl + b
# 作用鍵,先按作用鍵,再按功能鍵

作用鍵 + c
# 開新的視窗

作用鍵 + n / p
# 切換前一個 / 後一個視窗

作用鍵 + "
# 分割視窗,好用!

作用鍵 + Ctrl + 方向鍵上/下/左/右
# 可以調整當前分割視窗的長寬,好用!

作用鍵 + Space
# 切換分割視窗的佈置

作用鍵 + d
# 將目前的 Tmux Session 丟到背景去

tmux ls
# 列出主機上所有的 Tmux Session

tmux a -t 0
# 將背景的第 0 號 Tmux Session 叫回,a 代表 attach

作用鍵 + ?
# 查詢所有功能



【screen】

screen
# 啓動 screen

ctrl + a
# 作用鍵,先按作用鍵,再按功能鍵

作用鍵 + c
# 開新的視窗

作用鍵 + n / p
# 切換前一個 / 後一個視窗

作用鍵 + k
# 關閉視窗

作用鍵 + d
# 將目前的 Screen Session 丟到背景去

screen -ls
# 顯示背景所有的 Screen Session

screen -r 背景 Session 的名稱
# 將指定的 Screen Session re-Attach 回來

作用鍵 + S
# 水平分割畫面

作用鍵 + |
# 垂直分割畫面

作用鍵 + Tab
# 切換分割畫面

作用鍵 + "
# 將分割畫面接上指定的視窗

p.s.
Screen 的分割畫面很不直覺。
當使用者切出一個新的分割畫面,那個畫面會是整個 blank 的,什麼都沒有。
使用者必須先切到該分割畫面,然後爲該畫面接上指定的 Screen 視窗。
我的需求通常是在分割畫面裡,直接接上一個新的 Screen 視窗。
指令流程:
1] 作用鍵 + S 或 作用鍵 + |
2] 作用鍵 + Tab
3] 作用鍵 + c

Reference:
01. http://clyang.net/blog/2009/09/26/356
02. http://crazylion.wordpress.com/2010/06/04/tmux-2/

2011/09/20

快速架設 NTP Server

yum install ntp tzdata
chkconfig ntpd on
編輯 /etc/ntp.conf:
# 拒絕 IPv4
restrict default kod nomodify notrap nopeer noquery

# 拒絕 IPv6
restrict -6 default kod nomodify notrap nopeer noquery

# 放行指定的主機,一般會填寫上層 NTP Server
restrict your.time.server

# 預設放行本機
restrict 127.0.0.1
restrict -6 ::1

# 放行指定的私有網路主機
restrict 192.168.100.0 mask 255.255.255.0 nomodify

# 設定上層 NTP Server 
# 原本的 [0|1|2].centos.pool.ntp.org 的可以註解掉
server your.time.server

# 預設時間差異分析檔案與暫不用到的 keys 等
driftfile /var/lib/ntp/drift
keys      /etc/ntp/keys
/etc/init.d/ntpd restart
Reference:
http://linux.vbird.org/linux_server/0440ntp.php#server

2011/09/07

在 RHEL 作業系統內使用 LUN

安裝作業系統或對主機進行磁碟管理時,最好先關機,然後把光纖線拔下來,再做其它動作。

multipathd
dev-mapper

/dev/sda
/dev/dm-1
/dev/mpath/mpath1
/dev/mapper/mpath1

2011/06/29

rsyslog

rsyslog + logwatch

Reference:
01. http://wiki.rsyslog.com
02. http://linuxdiary.blogspot.com/2008/10/logwatch.html

關於 log 檔

/var/log
/var/log/dmesg
/var/log/message
/var/log/mail.log
/var/log/apache2/

2011/04/11

phpMyAdmin

【Red Hat Enterprise Linux】
yum install phpmyadmin
cp  /usr/share/phpmyadmin/config.sample.inc.php  /usr/share/phpmyadmin/config.inc.php
cat  /etc/httpd/conf.d/phpmyadmin.conf

【Ubuntu】
apt-get install phpmyadmin

【tarball】

新版的 phpMyAdmin 需要 PHP 5.2 以上的環境。

大致流程是:
1. 安裝 HTTP Server 與 PHP 環境
2. 下載最新版的 phpMyAdmin
3. 解壓縮到 HTTP Server 的 Document Root
4. 編輯 phpMyAdmin 的 config.inc.php 檔
5. 連線 http://localhost/phpmyadmin 測試

# using Ubuntu + Apache + MySQL
sudo apt-get install apache2 mysql-server php5-mysql
cd /var/www
wget URL_of_phpMyAdmin_Source_Package.zip (http://www.phpmyadmin.net/home_page/downloads.php)
unzip phpMyAdmin*.zip
mv phpMyAdmin* phpmyadmin
cd /var/www/phpmyadmin
cp config.sample.inc.php config.inc.php
vim config.inc.php

簡單的 config.inc.php 設定
$cfg['blowfish_secret'] = '123'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

/*
 * Servers configuration
 */
$i = 0; 

/*
 * First server
 */
$i++;
/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'cookie';
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'localhost';  // MySQL 主機的位址
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['compress'] = false;
/* Select mysqli if your server has it */
$cfg['Servers'][$i]['extension'] = 'mysql';
$cfg['Servers'][$i]['AllowNoPassword'] = false;

Reference:
01. http://wiki.phpmyadmin.net/pma/Quick_Install
02. http://wiki.phpmyadmin.net/pma/Config

2011/04/08

使用 Kickstart 自動安裝 RHEL

The Red Hat Kickstart installation method is used primarily (but not exclusively) by the Red Hat Enterprise Linux operating system to automatically perform unattended operating system installation and configuration.

【製作 Kickstart 光碟】

事前准備:
Red Hat Enterprise Linux 安裝光碟
一些編寫好的 kickstart 檔案(例如:rhel5.cfg)
一台可以燒錄 ISO 檔的 Linux 主機

首先,把 Red Hat Enterprise Linux 安裝光碟放到 Linux 主機。
到裏面找到 /images 這個資料夾,復制裏面的 boot.iso 到 Linux 主機上。

使用以下指令把 boot.iso 挂載到 /opt/boot_iso:
sudo su -
mkdir -p /opt/boot_iso
mount -o loop -t iso9660 boot.iso /opt/boot_iso

復制 /opt/boot_iso 裏面的 isolinux 資料夾:
cd /opt/boot_iso
cp -R isolinux /opt/

復制編寫好的 kickstart 檔案到 isolinux 資料夾:
cp rhel5.cfg /opt/isolinux

將 isolinux 資料夾制作成可開機的 boot.iso:
cd /opt/isolinux
mkisofs -r -T -J -V "kickstart" -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -v -o /opt/kickstart.iso .

[注意!]
RHEL 5 跟 RHEL 6 的光碟檢查碼與架構都不一樣!
每個不同的版號都得使用不同版本的 boot.iso 來制作 kickstart 光碟!
簡單說:
RHEL 5.5 得使用它自己的 boot.iso 制作自己的 kickstart 光碟。
RHEL 5.6 得使用它自己的 boot.iso 制作自己的 kickstart 光碟。
雖然它們的 rhel5.cfg 檔案可以共用。
這跟光碟的檢查碼有關系。

將產生的 /opt/kickstart.iso 檔案燒錄成光碟。

使用該光碟開機後,在安裝的 shell prompt 中輸入指定的 kickstart 檔名:
> linux ks=cdrom://rhel5.cfg

當開機檔案與指定的 kickstart 讀取到記憶體之後,開始安裝時,可能會碰到以下訊息:
The Red Hat Enterprise Linux CD was not found in any of your CDROM drives.
Please insert the Red Hat Enterprise Linux CD and press OK to retry.

此時,把 kickstart 光碟拿出來,放入原始的 RHEL 安裝光碟,壓 Enter。
順利的話,RHEL 就會照指定的 kickstart 檔的設定安裝了。

Reference:
01. http://en.wikipedia.org/wiki/Kickstart_(Linux)
02. http://junktrap.naihl.net/doku.php?id=redhat:kickstartbootcd

2011/03/29

autofs

使用 autofs 工具來挂載 NFS 檔案系統。

服務的執行腳本:
/etc/init.d/autofs  [ start | stop | reload ]

auto.master 預設在 /etc 下,它記錄了 mapping files 的位置。
如果說,mount points 的對照是地圖,auto.master 不是地圖,它記錄的是地圖的位置。

/etc/auto.master
/misc    /etc/auto.misc    --timeout 60
例如,要在 /misc 資料夾內做 auto mount,則 autofs 啟動時會全權控制該資料夾。
并且根據它對應的地圖檔 /etc/auto.misc 的內容,自動挂載磁區。
--timeout 則是設定該 auto mount 根目錄(/misc)下所有 mount point 的卸載時間。
超過 60 秒沒有對該磁區存取,就自動 umount 了。

根據 /etc/auto.master 的地圖指引,還需要編寫一個真正的 auto mount points 對映檔。
/etc/auto.misc
the_directory_name_in_misc    -OPTIONS    remote_host:/path
第一個欄位記錄的是 auto mount point 的名稱,假設叫 foo。
則該 autofs 的根目錄(/misc)不能有名稱為 foo 的資料夾。
基本上,/misc 會保持空的,autofs 會自動在挂載時建立 mount point。

第二個欄位就是挂載的設定選項了,使用逗號","分隔,記得最前面要加一個 -
例如:-default,rw

最後一個欄位是遠端主機 NFS export 出來的挂載點。