YAML 的地雷

因為碰 SaltStack,而官方建議用的格式是 YAML (雖然也支援 JSON,但文件幾乎都是 YAML),所以被迫要學一堆奇怪的 YAML hack,在官方文件上甚至寫了一篇「YAML Idiosyncrasies」讓大家參考,用 Idiosyncrasies 這個詞彙比較中性,但需要專文來寫就可以想像 YAML 有多 !@#$%^...

然後文章裡面也發現 SaltStack 在亂搞,於是就快起笑了...

首先是建議 indent 為 2 spaces,另外禁用 tab,這些到是沒什麼好抱怨的。但 dict 的設計就讓人崩潰,像是這樣的結構:

foo:
  - bar:
    baz1: abc
    baz2: def

你以為對應的 JSON 是:

{
  "foo": {
    "bar": {
      "baz1": "abc",
      "baz2": "def"
    }
  }
}

但實際對應的 JSON 中,bar、baz1、baz2 視同一層:

{
  "foo": {
    "bar": null,
    "baz1": "abc",
    "baz2": "def"
  }
}

因為其實對應的 YAML 是:

foo:
  - bar:
  - baz1: abc
  - baz2: def

你就不能把最上面的 YAML 定義成 syntax error 嗎... =_=

接下是 SaltStack 的惡搞時間,因為 YAML parser 會把 644 當作數字傳進去,所以這樣的設定:

/etc/vimrc:
  file:
    - managed
    - source: salt://edit/vimrc
    - mode: 644

SaltStack 會收到 644 (十進位),而如果你寫成 0644 時,就會被讀成八進位,也就是 420 (十進位):

/etc/vimrc:
  file:
    - managed
    - source: salt://edit/vimrc
    - mode: 0644

我覺得後面這個是比較正確的寫法,所以應該要會動,但 SaltStack 對這部份 workaround,會變成 chmod 420 /etc/vimrc,然後就噴飯了...

另外 2013_01_12 這種字串會被解讀成 20130102 (十進位),這會不會太歡樂...

反正用下去後應該會再踩更多地雷,繼續看下去吧...

3 thoughts on “YAML 的地雷”

  1. 其實建議用 Ruby 的 irb 載入看看(或是 Python 應該也有相對的載入法)…比如說我通常會進 irb 中下這樣:
    > require 'yaml'
    > require 'pp'
    > a=YAML.load_file('some_file.yaml')
    > pp a
    輸出成檔案也很容易的

  2. 值的地方若是覺得有些特殊符號無法確認是否會被「過度解讀」的話,就認命前後加上雙引號 "string" 這樣

    Mentions

  • 💬 YAML 常見的問題

Leave a Reply

Your email address will not be published. Required fields are marked *