在 Ubuntu 上架設 NFS server
思路
NFS (Network File System) 可以透過網路,讓不同的作業系統,分享個別的檔案。
而我想要在 Ubuntu 上建立 NFS Server,透過 Mac 上的 NFS Client 連上。目前的環境:
- Ubuntu 18.04: 192.168.0.10
- Mac OS X Mojave: 192.168.0.20
NFS Server
安裝
1 | ubuntu bare metal |
安裝好之後,會在 /etc
底下會多一個 exports
的檔案,待會我們可以修改這個檔案,來調整想要分享的檔案。
至於 docker 的部分是來自於這個 repo
建立資料夾
我想要把 /tmp/nfs
這個資料夾分享出去,所以先建立這個資料夾:
1 | mkdir -p /tmp/nfs |
資料夾權限
目前 /tmp/nfs
的權限是 root:root
,第一個 root 是 owner 的權限,第二個 root 是 group 的權限:
1 | ls -la /tmp/nfs |
要把檔案分享出去的話,需要修改資料夾的權限為 nobody:nogroup
,且加上 -R
的參數把資料夾底下的所有子資料夾都設為 nobody:nogroup
:
1 | sudo chown -R nobody:nogroup /tmp/nfs |
如果後來又新增檔案的話,必須再重新執行一次這一行指令。
否則在之後 mount 的時後會出現 Operation not permitted
的錯誤:
1 | mount_nfs: can't mount /tmp/nfs from 192.168.0.10 onto ...: Operation not permitted |
設定
修改 /etc/exports
:
1 | sudo vim /etc/exports |
然後把想要分享的檔案加入:
1 | /etc/exports |
至於選項是選擇性填寫的,有很多參數可以選:
ro
:read onlyrw
:read and writeasync
:此選項允許 NFS Server 違反 NFS protocol,允許檔案尚未存回磁碟之前回覆請求。這個選項可以提高性能,但是有可能會讓 server 崩潰,可能會需要重新啟動 server. 或檔案遺失。sync
:只會儲存檔案會磁碟之後才會回覆請求。no_subtree_check
:禁用子樹檢查,會有些微的不安全,但在某些情況下可以提高可靠性。secure
:請求的 port 必須小於 1024,這個選項是預設的。insecure
:請求的 port 不一定要小於 1024。
User ID Mapping 參數:
root_squash
:將 uid 0 的使用者映射到 nobody 匿名使用者,這個選項是預設的。no_root_squash
:關掉 root squash 的選項,這個選項可以使用 root 身份來控制 NFS Server 的檔案。all_squash
:所有登入 NFS 的使用者身份都會被壓縮成為 nobody。anonuid and anongid
:調整匿名使用者的權限,可以讓所有透過 NFS 修改文件,都看起來是同一個使用者。
更多參數的選項可以參考 LInux exports
重新啟動 Server
1 | sudo systemctl restart nfs-kernel-server |
檢查
輸入以下的指令,確認使否把檔案加入 NFS Server:
1 | sudo exportfs |
目前 showmount 的指令會是空的,因為還沒有 NFS Client 連上,如果連上的話,NFS Server 這邊可以使用 showmount 指令查看哪個 Client IP 連過來的:
1 | showmount |
NFS Client
安裝
這台 Ubuntu 的 IP 是 192.168.0.30
1 | ubuntu |
Mount
我想要跟 share 資料夾做分享,使用 mount 指令將遠端的資料夾 /tmp/nfs
掛載到本地端的資料夾 share
:
1 | mac |
注意在 mac 上必須加上 -o resvport
的參數,否則會出現 Operation not permitted
的錯誤。
檢查
輸入以下指令檢查是否掛載成功:
1 | mac, ubuntu |
測試
在 /tmp/nfs
資料夾內建立 test
檔案:
1 | mac, ubuntu |
是否能成功建立
Unmount
1 | mac, ubuntu |
Mac 將 iso 轉 usb、dmg 轉 usb、iso 轉 dmg
ISO to USB
列出外部磁碟
1 | diskutil list external |
1 | diskutil list external |
使用指令分割磁碟 on Mac
Semantic Version
相依性
相依性是指在版本升級的時候,跟前一個版本的相關程度,如果套件的版本相依性過高,在升級的時候就會變得困難。但如果相依性過低,又會造成版本的混亂,就像這個本版相不相容以前的版本…..也就是因為這樣,所以才需要定義一個版本編號的系統來管理版本之間的相依性。
語意化版本 Semantic Versioning
語意化版本 Semantic Versioning 可以寫成 SemVer,看版本的數字編號就能知道之間的相依性,簡單來說就是使用一致的版本規則來描述相依性:
MAJOR.MINOR.PATCH
- MAJOR: 無法向下相容
- MINOR: 可以向下相容,增加新功能
- PATCH: 可以向下相容,修正一些小錯誤時
任何一個版本發佈之後就不能再做修改了。
Css 排版歷史
Ruby Regexp MatchData
=~ Operator
回傳比對的位置到的起始位置,沒有比對到則回傳 nil
1 | /cat/ =~ 'hiakiicat' # => 6 |
match method
有 match 到會回傳 MatchData,如果沒有 match 到則會回傳 nil。
1 | m = /akii(.+)$/.match('hiakiicat') |
括號起來的資料 (...)
才會另外存成一個值。如果不想要另外存成一個值,可以在括號裡面打 (?:...)
。
獲取資料:
m[0]
為 match 到的所有資料。m[1]
為第一個括號裡面所比對到的資料,以此類推。
1 | m[0] # => "akiicat" |
Ruby on Rails long string id
之前有講到使用 UUID 當作 primary key 的方法,因為 postgresql 有提供 uuid,可以直接拿來使用。
接下來的這個方法適用於所有的資料庫,在物件儲存之前先給定它的 id,如此一來就能定義我們所想要的內容了。
先隨便用鷹架產生點東西:
1 | rails g scaffold book title |
加上 id: :string
讓 id 的型態為 string。
1 | # db/migrate/20170218105724_create_books.rb |
Ruby on Rails 5 dynamic subdomains
一個使用者有名字 name 還有自己網頁的子網域 subdomain,我們想要的結果是讓每一位使用者有自己的子網域,而且還可以隨時更改。
假設現在有個使用者是 User.create(name: "akii", subdomain: "akiicat")
,在 rails 預設 show 頁面會是 http://localhost:3000/users/1
,但我們想把網址變成個人的子網域 http://akiicat.localhost:3000
。
接下來會用鷹架建立使用者來做示範:
1 | rails g scaffold user name subdomain |
修改 routes.rb
,加上首頁,然後把 show 的頁面加上 subdomains 的限制。
1 | # config/routes.rb |
Ruby on Rails 5 api subdomain
為了要 demo api subdomain 的頁面是否能夠運作,這邊用鷹架隨便建立個東西。
1 | rails g scaffold api::v1::books title |
使用 constraints 限制 subdomain: 'api'
。
然後用 scope module: 'api'
加上 app/controllers/api 這個資料夾。
1 | # config/routes.rb |
Ruby on Rails callback 筆記
可用的 callback
以下是 Active Record 可用的 callback,依照執行順序排序:
新建物件
1 | before_validation |
更新物件
1 | before_validation |