Có quá nhiều YAML
(noyaml.com)- Trong cấu hình DevOps và CI, YAML được dùng gần như một tiêu chuẩn, nhưng do ép kiểu ngầm định và khác biệt giữa các parser, cùng một cấu hình vẫn có thể bị diễn giải khác với dự đoán
- Trong YAML 1.1, các giá trị như
NO,07,08,04:30,0666có thể bị đổi thành boolean, số, thời gian, bát phân, nên cần làm rõ ý định chuỗi - Các ví dụ từ GitHub Actions, Kubernetes, CloudFormation và nhiều dịch vụ CI cho thấy cú pháp YAML và cấu trúc riêng của từng dịch vụ có thể dẫn tới commit lặp đi lặp lại, lồng escape, và cách biểu diễn job không thống nhất
- Các liên kết tham khảo gom lại những nội dung như YAML có thể thực thi, khác biệt hành vi theo từng parser, ký pháp chuỗi nhiều dòng, vấn đề phiên bản
1.70bị parse thành1.7, và cơ sở thiết kế của StrictYAML - Các lựa chọn thay thế như Nickel, Dhall, CUE, Jsonnet cũng được đưa ra, nhưng bản thân trang này lại trông như một trường văn bản khổng lồ có thể chỉnh sửa, tiếp tục giữ nguyên chất châm biếm về tính khả dụng của YAML
Châm biếm YAML như một ngôn ngữ cấu hình DevOps
- YAML thường được dùng trong cấu hình DevOps, nhưng trang này bộc lộ sự mệt mỏi với YAML bằng những câu kiểu như “không ai thực sự muốn dùng YAML”
- Trang liệt kê một cách mỉa mai các lý do dùng YAML như một công nghệ DevOps
- Châm biếm rằng nó luôn có thể compile và triển khai
- Mỉa mai việc không có xử lý lỗi cưỡng bức trong lúc phát triển, và sự cố chỉ bùng ra khi runtime ở production
- Nói kiểu rằng thông báo “có gì đó bị hỏng” còn tốt hơn stack trace có số dòng
- Thể hiện sự bực bội vì phải đốt thời gian mỗi khi tạo một pipeline CI mới
- Châm biếm tình huống nó được xem như lựa chọn an toàn chỉ vì Kubernetes dùng nó
- Đồng thời cũng nhắc tới ưu điểm là hỗ trợ comment, khác với JSON
Những cái bẫy do ép kiểu ngầm định tạo ra
- Trong YAML 1.1,
NOcó thể được parse thành kiểu booleanNO: Norwaycó thể gây ra vấn đề diễn giải boolean thay vì mã quốc gia- Nếu muốn là chuỗi thì phải bọc trong dấu nháy như
"NO" - Trang chỉ ra rằng trong đặc tả YAML 1.1 có tới 22 cách để viết
truehoặcfalse
- Các giá trị trông giống số cũng có thể được parser hiểu khác nhau
- Ví dụ
07và08cho thấy kết quả có thể khác nhau như[ 7, "08" ] - Điều này được châm biếm thành việc cụm Kubernetes triển khai được tới bản thứ bảy rồi hỏng ở bản thứ tám
- Ví dụ
- Chuỗi trông giống thời gian cũng là đối tượng bị chuyển đổi tự động
04:30có thể bị đổi từ chuỗi thời gian người dùng viết thành giá trị16200là số giây sau nửa đêm- Nếu muốn là chuỗi thì phải chỉ rõ như
!!str 04:30
- Khác biệt về ký pháp bát phân trong YAML cũng gây rối
- YAML 1.1 dùng dạng
0666 - YAML 1.2 dùng dạng
0o666 - Việc Kubernetes dùng YAML 1.1 được nói như một “nghi thức trưởng thành của DevOps”
- YAML 1.1 dùng dạng
Vấn đề xử lý phiên bản, SHA và chuỗi
- Phiên bản gói có thể bị parse như số thực
foo: 1.7vàbar: 1.70có thể bị hiểu là cùng một phiên bảnfizz: 1.7.0vàbuzz: 1.70.0lại có thể được xử lý như các chuỗi phiên bản khác nhau
- Git SHA ngắn dùng trong CI cũng có thể không an toàn
- SHA 8 ký tự có thể toàn là số
my.flaky_versionchèn${GIT_SHORT_SHA}mà không có dấu nháy có thể không còn là chuỗi- Trang nêu rằng giá trị này là chuỗi khoảng 98% số lần, còn nếu bọc như
"${GIT_SHORT_SHA}"thì là chuỗi 100%
- Ví dụ về Rust toolchain cũng được đưa vào phần liên kết tham khảo
Chi phí bộc lộ trong cấu hình CI và hạ tầng
- Có ví dụ kể rằng khi học GitHub Actions, tác giả đã commit/push 8 lần trong một giờ, và message commit cuối cùng là “I don't really like yml”
- Trang cũng đưa ra ví dụ nếu viết SQL bằng YAML sẽ trông như thế nào
- Các cấu trúc SQL như
SELECT,FROM,WHERE EXISTS,AND,EQUALS,LTbị chuyển thành cấu trúc lồng nhau kiểu YAML - Điều này châm biếm việc một biểu thức SQL ngắn lại biến thành dạng YAML dài dòng và rườm rà
- Các cấu trúc SQL như
- Cách biểu diễn job và step cũng khác nhau giữa các dịch vụ CI
- Azure DevOps dùng dạng
jobsbên dưới làjob,steps,script - CircleCI dùng dạng
jobs,job1,steps,checkout,run - Ví dụ về “hệ thống CI của tương lai” cho thấy cùng một tác vụ có thể lại được biểu diễn bằng một cấu trúc lồng khác nữa
- Azure DevOps dùng dạng
- Với CloudFormation, khi đặt hàm
SEARCHbên trongDashboardBodycủa CloudWatch, có ví dụ phải escape lại nội dung vốn đã được escape và đóng toàn bộ JSON trong dấu nháy kép
YAML có thể thực thi và khác biệt giữa các parser
- Cụm từ “executable yaml” được nối với các vấn đề parse YAML liên quan đến bảo mật
- Vấn đề tương thích giữa các YAML parser cũng được tách ra thành tài liệu riêng
- Every YAML parser is a custom YAML parser
- Được đặt như tài liệu cho thấy hành vi giữa các parser có thể không giống nhau
Tài liệu liên quan và các lựa chọn thay thế
- Các tài liệu tham khảo về vấn đề của YAML được gom lại cùng nhau
- Today we’re going to look at some general problems with the YAML format
- We replaced 1,000 lines of YAML with 10 structs and people started contributing again
- What if you used the same language and tools you use to define your app to define your infrastructure?
- A YAML file is almost always still 'valid' even if it is trunca
- the bug was that the YAML parser ignored the negative signs ... so negative GPS coordinates became positive ones
- There are 63 different ways to write multi-line strings in YAML
- StrictYAML Design Justifications
- Nhiều công cụ và hướng tiếp cận được liệt kê như các lựa chọn thay thế cho DevOps xoay quanh YAML
Phản ứng với chính trang web
- Tổng hợp phản ứng trên Reddit cũng chỉ trích cả thiết kế của trang
- Có ý kiến cho rằng website trông như một trường văn bản khổng lồ có thể chỉnh sửa
- Có phản ứng nói rằng không thể bấm vào hyperlink
- Có câu đùa rằng có thể chọn toàn bộ văn bản của trang rồi xóa đi là vấn đề được giải quyết
- Có phản ứng nói rằng đồng ý với tinh thần ghét YAML nhưng thấy quyết định thiết kế website vẫn khó hiểu
- Câu cuối cùng nói rõ rằng trang được cố ý làm cho “có thể dùng ngang với YAML”
1 bình luận
Các ý kiến trên Hacker News
Rắc rối “ưa thích” nhất của tôi là cái này:
0708Kết quả trở thành
[ 7, "08" ]Vì giả định về số bát phân và chuỗi
Giả định này được phát hiện trong YAML được tạo bằng template ở sâu bên dưới ba tầng, và dẫn tới sự cố toàn bộ cụm k8s của chúng tôi, nhưng chỉ cụm
08bị hỏng. 7 cụm trước đó vẫn chạy tốt0Đọc bình luận này tôi có cười, nhưng xét việc gần như chẳng ai dùng số bát phân trong file cấu hình vào năm 2023, hành vi và giả định như vậy thật vô lý. Nếu là thập lục phân thì còn hiểu được, thập phân thì hiển nhiên, còn bát phân thì hơi quá
Phía tạo ra thứ đó chắc chắn đã không tuần tự hóa dữ liệu bằng thư viện. Nếu dùng thư viện thì nó đã chuyển kiểu sang định dạng đúng rồi
YAML có nhiều vấn đề, nhưng tôi nghĩ vấn đề cốt lõi thật sự nằm ở việc cố nhét logic vào cấu hình
Nếu chỉ dùng YAML cho dữ liệu chứ không dùng cho logic, nó là một trong những định dạng dữ liệu dễ đọc và dễ viết đối với con người
CI/CD luôn có một mức logic nào đó, hiếm khi chỉ thuần YAML là xong, lại còn trộn cả template kỳ quặc. Tôi tự hỏi sao không cung cấp một API thật sự cho một ngôn ngữ lập trình thật sự
15 năm trước khi dùng Ant dựa trên XML cũng có cùng vấn đề, và đó không phải lỗi của XML
Tôi nghĩ vấn đề chính của YAML là thiếu an toàn kiểu. Những thứ như thụt lề sai, gõ nhầm khóa, chuỗi bị parse thành boolean
Ngoài ra, tôi nghĩ đây là một định dạng tốt vì ngắn gọn và ít nhiễu cú pháp hơn nhiều so với các định dạng khác. Vì vậy tôi đã tạo https://github.com/crdoconnor/strictyaml để mọi người dùng YAML an toàn kiểu và nhận được thông báo lỗi tức thì, rõ ràng cho các vấn đề như vậy
Vì họ kéo các trừu tượng vào vì nghĩ rằng mình cần chúng. Do đó tôi luôn tránh dùng ngôn ngữ lập trình Turing-complete làm định dạng cấu hình
Tôi từng mất vài giờ bước từng dòng qua AWS CDK bằng JavaScript debugger. Nếu đó chỉ là một file yaml/Json/gì cũng được đơn giản và ngớ ngẩn thì đã không có vấn đề đó. Đó là một dự án nhỏ và không cần độ phức tạp ấy
Vì vậy trong cấu hình công cụ JS tôi cũng thích JSON hơn JS. Đây cũng là lý do cấu hình webpack trở nên hỗn loạn. Khi được dùng ngôn ngữ thật, “cảm biến DRY” của mọi người sẽ kích hoạt và làm mọi thứ phức tạp hơn
Nếu là khai báo, việc tuân theo thực hành chuẩn cũng dễ hơn và hỗ trợ công cụ tốt hơn. Nếu package.json thật sự trở nên giống build.gradle thì sẽ tệ hơn nhiều
Chỉ cần quy định rằng “chạy script trong một trình thông dịch Python bên trong cgroup bị giới hạn chặt, và kết quả phải là một dictionary tên
CONFIG”. Logic wrapper sẽ tuần tự hóa nó theo cách thuận tiện cho chương trình đích cần cấu hìnhNó giống như phàn nàn về độ phức tạp hay cứng nhắc của
helm. Helm chart không tự viết ra. Có lẽ vì phàn nàn và phớt lờ dễ hơn là hiểu vấn đề rồi triển khaiLà một định dạng file, YAML có ưu và nhược điểm. Nhưng vấn đề thật sự là cố biểu diễn những thứ như điều kiện, vòng lặp, hàm, lớp/lớp con thông qua template trong một định dạng file tương đương JSON
YAML ổn cho các cấu hình nhỏ. Nhưng ngay khi cần bất kỳ loại luồng điều khiển nào, nó rất nhanh phình thành spaghetti theo từng vendor
Jinja trong YAML rõ ràng là một anti-pattern
Có vẻ ngay từ đầu nó đã không được thiết kế với đủ khả năng lập trình, rồi về sau mọi người bắt chước các dự án đã chọn con đường đó và thành công
Bài viết có nhắc đến các lựa chọn thay thế như Dhall và Jsonnet, nhưng có thể nghĩ thêm hai hướng nữa
Thứ nhất là tạo một thư viện cấu hình cho một ngôn ngữ lập trình thực thụ, và để thư viện này sinh ra file cấu hình JSON. JSON đó không phải thứ để chỉnh tay, mà chỉ được xem như một artifact có thể kiểm tra. Người dùng sẽ đưa cấu hình dưới dạng code, có hỗ trợ công cụ, vào quản lý phiên bản. Việc khó hotfix trực tiếp trên server vừa là nhược điểm vừa là ưu điểm
Thứ hai là Starlark. Đây là một ngôn ngữ phái sinh từ Python, không Turing-complete, ban đầu được phát triển cho hệ thống build Bazel. Có nhiều implementation và tôi không rõ mức độ tương thích sâu đến đâu, nhưng cũng có binding cho Python: https://github.com/caketop/python-starlark-go, https://github.com/inducer/starlark-pyo3
{%và{{đều là ký tự YAML, nên mọi chỗ dùng đều phải được đặt trong dấu ngoặc képTôi thấy các cách như
${{của GitHub Actions, hay<%,<<tốt hơn nhiều. Tất nhiên có rủi ro là<<:là cú pháp YAML, nhưng nó không phải Jinja hợp lệNếu ý là không nên nhét bất cứ thứ gì có thể thực thi vào YAML, thì tôi nghĩ con thuyền đó đã rời bến rồi. Vì mọi người đã nhận ra rằng cách để phần literal làm mặc định và thỉnh thoảng chỉ chèn phần thực thi vào rất tiện để tạo nội dung, giống ASP/JSP/PHP
Nếu muốn khơi mào một cuộc flame war anh em trong thread này thì chỉ cần nói về HCL và
for_each, nhưng ít nhất ở đây thì tốt nhất là đừngTôi không rõ trong đó bao nhiêu là lỗi của CDK và bao nhiêu là do CloudFormation vốn đã không hay
Tôi thích Jsonnet và Starlark, nhưng thực tế là trong hầu hết use case không cần một ngôn ngữ lập trình mới. Thường thì chỉ muốn tạo tài liệu cơ sở rồi áp dụng patch để chỉnh sửa. Như vậy mọi thứ đơn giản hơn nhiều
Trải nghiệm dùng YAML thuần túy tự thân nó không quá tệ. Định dạng này có vài điểm khá đáng nghi, nhưng vẫn dùng được. Tôi nghĩ vấn đề nằm ở độ phức tạp của các giải pháp phải thêm vào để điều chỉnh tài liệu cho nhiều môi trường
Tôi nghe nói trước đây từng có một Python DSL thực sự có thể dùng thay YAML, nhưng hình như đã bị ngừng. Vì vậy giờ đây vòng lặp và if-then trở thành những đống YAML dài dòng kinh khủng, còn Jinja thì được diễn giải theo cách hoàn toàn không thể dự đoán
jsonnet, hay khôngBản thân YAML thì tôi thấy rất tuyệt. Điều không tuyệt là việc chúng ta đã biến phần triển khai của CD trở nên quá khó
Tôi thừa nhận cấu hình của chúng tôi trong Azure DevOps không hẳn là xuất sắc, nhưng thật đáng ngạc nhiên khi có những tổ chức mà nhiều nhóm hoặc 5–6 người vận hành phải xử lý các công cụ như thế này. Có thể những nơi như Google thì khác, nhưng với các doanh nghiệp thông thường có tối đa 50.000 người dùng đồng thời, hoặc thường là ít hơn nhiều, thì tôi thấy như vậy là quá mức
Vào đầu những năm 2000, việc triển khai một ứng dụng web doanh nghiệp lên IIS on-premises, nơi mọi thứ như cân bằng tải, networking, v.v. được xử lý bởi chưa tới 0,25 nhân viên toàn thời gian, còn dễ hơn triển khai cùng thứ đó lên một thiết lập “hiện đại” ngày nay
Tất nhiên các pipeline hiện đại có ưu điểm. Chúng ta đã vượt qua được nhiều vấn đề kiểu “trên máy tôi thì chạy”, và nâng chất lượng quản lý lên đáng kể nhờ các cổng phê duyệt tốt hơn. Nhưng bản thân việc triển khai, ngay cả năm 2023, vẫn là cơn ác mộng
Điều này có thể không phải là vấn đề với các lập trình viên HN ở những công ty công nghệ thực thụ hoặc những nơi có đội DevOps chuyên trách giỏi. Nhưng trong thế giới doanh nghiệp phi công nghệ, CI/CD chưa bao giờ tệ đến thế trong sự nghiệp của tôi
Có thể đổ lỗi cho YAML, hoặc đổ lỗi cho việc muốn làm gì cũng cần quá nhiều YAML và template thì khó. Nhưng theo tôi, vấn đề tổ chức lớn hơn nhiều so với vấn đề kỹ thuật. Công cụ CD cần được tự động hóa hơn rất nhiều để việc mô tả hạ tầng bằng code không còn là công việc của lập trình viên
Việc có thể làm vậy là tốt, nhưng thực tế là chúng ta đang yêu cầu hàng triệu lập trình viên triển khai hạ tầng mà có thể chính họ hầu như không hiểu. Tôi chưa từng thấy lập trình viên nào không muốn chỉ đưa container sang rồi để networking và “việc phía server” tự xử lý
Nếu không làm như vậy, cuối cùng sẽ có hàng đống VNET và subnet mà chẳng ai hiểu rõ cách chúng hoạt động, và tổ chức sẽ mất rất nhiều tiền vì các lập trình viên không biết rằng có thể làm bằng
/xTa viết một loại “định nghĩa công việc” nào đó offline, gửi lên một hệ thống chia sẻ độc quyền, chờ trong hàng đợi, rồi nhận các file log do một hệ thống mà mình không kiểm soát tạo ra. Vì không thể chạy mã hệ thống độc quyền đó cục bộ trên workstation, vòng lặp nội bộ ngắn thì cũng mất hàng chục phút, dài thì hàng giờ hoặc hàng ngày
Không có chế độ xem trước hay “what if”, cũng không có “dry run”. Dù có gọi là “kiểm thử”, vì chỉ có một hệ thống nên về thực chất là đang thao tác trên production
Vấn đề thật sự không phải là YAML. Kể cả pipeline được script bằng ngôn ngữ lập trình của thần thánh thì cũng chẳng khác mấy
Lý do cách phát triển phần mềm trên workstation thay vì mainframe chia thời gian tập trung trở nên rất phổ biến là vì nó làm vòng lặp nội bộ nhanh hơn một cách ngoạn mục, tách biệt khỏi môi trường production, và trao quyền kiểm soát lại cho lập trình viên
Thế hệ pipeline CI/CD hiện nay về cơ bản đã đảo ngược tất cả những điều đó
Kubernetes chạy trên một máy duy nhất khôi phục phần lớn lợi ích của phát triển dựa trên workstation, nhưng đây vẫn là một hệ thống rất mới nên còn nhiều đau đớn trong quá trình trưởng thành
Một vấn đề liên quan là: có những giải pháp rất tốt cho lập trình viên một mình vận hành một ứng dụng bằng thao tác click, và cũng có những giải pháp rất tốt cho các siêu công ty làm tự động hóa quy mô lớn cho hàng nghìn lập trình viên. Nhưng khoảng giữa, nơi vài lập trình viên doanh nghiệp quản lý vài chục ứng dụng, thì chỉ là hỗn loạn
Đã có khá nhiều lần mọi thứ chạy tốt nhiều lần trong Docker image của tôi, nhưng lại vỡ khi là image đã triển khai
Đây là loại vấn đề chỉ có thể vượt qua nếu toàn bộ pipeline build và triển khai hoàn toàn minh bạch, có toàn quyền truy cập vào image repository, và thực sự kiểm soát được các chỉ thị build. Điều này cũng hạn chế chẳng kém gì việc kiểm soát hệ điều hành cục bộ, và tôi nghĩ nó sẽ thất bại ở nhiều tổ chức như số nơi từng gặp cảnh code vỡ khi chuyển sang máy khác
Việc thiết lập như vậy trong bất kỳ hệ thống CI/CD nào trông cũng khá trực quan
Tôi nghĩ có một giải pháp để giữ hòa khí nếu mọi người đều tôn trọng phổ quát chỉ một quy tắc: đừng dùng YAML bên ngoài hệ sinh thái Python
Như vậy những người thích một định dạng scripting khó hiểu, ưu tiên tính dễ đọc hơn tính chính xác, độ bền và khả năng bảo trì, vẫn có thể tiếp tục dùng ký tự tab, kiểu lỏng lẻo và cú pháp rối rắm. Phần còn lại thì không cần phải vậy nữa. Những người thích cú pháp kiểu C có thể giữ được sự tỉnh táo
Có vẻ cuối cùng tôi đã chạm đúng cốt lõi vấn đề. Với tôi, một lập trình viên cú pháp C, khoảng trắng có ý nghĩa cú pháp là sự điên rồ thuần túy. Khoảng trắng là định dạng, không phải thông tin hay mệnh lệnh. Định dạng tốt thì hữu ích và có ích, và lập trình viên cú pháp C giỏi cũng quan tâm đến định dạng dễ đọc
Trong Python và YAML, định dạng là thông tin chỉ thị. Nó có ưu điểm là mọi đoạn code chạy được đều trở nên dễ đọc. Nhưng tại sao code muốn chạy được thì nhất thiết phải dễ đọc?
Cứ tưởng tượng làm việc với một đồng nghiệp giống YAML. Bạn gửi một tin nhắn dài, rồi người đó trả lời “Gì cơ? Cái này vô lý.” Hóa ra vì bạn không chèn dòng trống giữa các đoạn nên ý nghĩa bị hỏng. Bạn thêm lại các dòng trống và gửi tin nhắn thì lúc đó họ mới đọc được. Nếu không có định dạng đúng về mặt cú pháp, thông tin bạn gửi đã trở nên vô nghĩa
Có vô số cách để định dạng, và tôi thích mọi người dùng linter khi viết code. Nếu được thì tốt nhất là cùng loại linter với tôi đang dùng
Những ngôn ngữ đó buộc dùng các cấu trúc cú pháp chuẩn. Số cách để viết code khó đọc giảm đi, nên đó là điều tốt
Nhưng giờ tôi nghĩ sự khác biệt đó không phải là triết học mà là vấn đề công cụ. Một số công cụ, chẳng hạn trình soạn thảo văn bản hay chương trình email, hỗ trợ tốt khoảng trắng có ý nghĩa, còn một số thì không
Tất cả trình soạn thảo văn bản tôi dùng đều được thiết lập để hiển thị dấu cách và ký tự tab, và hiển thị chúng khác nhau. Thường là kiểu chấm mờ và gạch mờ. Tôi đã quen nên hoàn toàn không thấy vướng
Theo quan điểm của tôi, code không phải văn bản tùy ý. Ta dùng phông chữ monospace mà ta sẽ không dùng trong sách, và phân biệt cú pháp bằng màu sắc. Cũng chẳng có lý do gì để không làm cho khoảng trắng hiện ra
Tôi vẫn thích các ngôn ngữ không có khoảng trắng có ý nghĩa hơn, nhưng cũng không ghét những ngôn ngữ đó. Với tôi nó hoàn toàn không thành vấn đề
Nhưng nếu công cụ bạn thích không hỗ trợ tốt khoảng trắng có ý nghĩa, không làm cho khoảng trắng hiện ra, hoặc thậm chí bạn code bằng phông chữ tỷ lệ, thì bạn sẽ không còn cách nào khác ngoài việc căm ghét khoảng trắng có ý nghĩa và xem nó là sự điên rồ thuần túy
Điều khiến tôi đổi ý lại bất ngờ là khi dùng CoffeeScript. Tôi không thích JavaScript lắm, nhưng cảm giác dùng CoffeeScript giống như phiên bản đã chắt lọc của The Good Parts của Crockford. Không thể vô tình tạo ra những phần xấu
Hơn nữa cách indentation trở thành code khá dễ chịu. Bất tiện duy nhất là trong Vi, tôi không thể nhấn
%ở dấu ngoặc nhọn mở hoặc đóng để tìm đầu kia của block. Ngược lại, nhờ indentation, nếu code trông kỳ lạ thì thường đúng là nó có vấn đềDù vậy tôi vẫn chưa học Python nhiều. Dạo này tôi dùng TypeScript, nhưng nếu một ngày nào đó CoffeeTypeScript xuất hiện thì…
Vì vậy tôi bắt đầu tự tạo một định dạng tên là BCL: https://github.com/wkhere/bcl
Nó sẽ không giúp ngay cho mọi trường hợp dùng YAML, nhưng ít nhất có thể là một cách đẹp hơn để định nghĩa tài nguyên theo phong cách như Terraform. Thực tế nó đã hữu ích như một thay thế HCL trong một dự án nội bộ, và đó là động lực cuối cùng khiến tôi làm nó
Nhìn rộng hơn, tôi không biết nó sẽ giúp thế nào với vấn đề YAML xuất hiện khắp nơi trong Kubernetes. Hơn một nửa vấn đề trong
$daily_jobcủa tôi nằm ở việc ghép biểu đồ Helm cuối cùng từ nhiều nguồn quá thô sơTôi không có ý nói Helm về bản chất là công cụ tệ, hay công ty chúng tôi đã chọn Helm theo một cách khá tệ. Tôi nghĩ mọi người đều đang cố hết sức trong hoàn cảnh của mình
Nhưng thao tác với template văn bản có khoảng trắng có ý nghĩa thì quá dễ lỗi, và lỗi cũng được phát hiện quá muộn. Tôi nghĩ Kubernetes lẽ ra đã tốt hơn nhiều nếu dùng một định dạng tùy chỉnh dựa trên cú pháp kiểu C, thay vì cố chứng minh YAML tuyệt vời đến mức nào. Nhất là khi YAML cũng chẳng tuyệt vời
Bất cứ thứ gì tạo JSON đều có thể dùng để tạo YAML
Nickel có thể được đánh giá thành JSON: https://nickel-lang.org/
https://youtu.be/SEA1Qm8K4gY?feature=shared
Trông khá giống
Đây là hiệu ứng nền tảng nội bộ. Khi ứng dụng lớn lên, cấu hình cũng mở rộng rồi cuối cùng trở thành một ngôn ngữ lập trình, nhưng là một ngôn ngữ nhiều lỗi, thiếu đặc tả và có tính khả dụng khủng khiếp
Tuyên bố phá sản cấu hình rồi chọn một định dạng cấu hình mới. Và lặp lại
Tất nhiên bản thân định dạng cũng không phải vô can. Càng linh hoạt thì càng dễ bị tái sử dụng thành một ngôn ngữ lập trình tệ
Sau khi lặp đi lặp lại sai lầm này, ngày nay tôi sẽ chọn định dạng cấu hình đơn giản nhất có thể cho cấu hình cơ bản. Ngay cả
.inicũng có thể quá mạnh. Những “cấu hình” phức tạp hơn thì tôi sẽ giao cho một ngôn ngữ lập trình thực sự, nếu được thì là ngôn ngữ mà ứng dụng được viết bằngPhần lớn áp đảo các ví dụ kiểu “YAML dở” đều có thể giải quyết bằng cách đặt toàn bộ các literal kỳ quặc trong dấu ngoặc kép
Đúng là YAML đôi khi gây khó chịu. Ví dụ, danh sách trong map rất nhanh trở nên kỳ quặc, và khoảng trắng có ý nghĩa gần như chắc chắn một ngày nào đó sẽ gây rắc rối. Nhưng những bài viết kiểu này, nói nhẹ thì trông hơi thiếu nghiêm túc
Cả hệ sinh thái YAML khuyến khích viết giá trị không có ngoặc kép. Thường thì nó hoạt động tốt, rồi thỉnh thoảng hỏng vừa đủ để làm bạn vấp ngã trong production
EDN là một tập con của Clojure: https://github.com/edn-format/edn
Rõ ràng, có thể streaming, có thể mở rộng, và không nhạy cảm với khoảng trắng. Tuy vậy vẫn có các quy ước định dạng để dễ đọc
Nhưng tôi không rõ khác biệt về ngữ nghĩa giữa list và vector là gì. Trong đầu tôi, array và linked list là chi tiết triển khai của cấu trúc dữ liệu trong code, chứ không phải khác biệt của định dạng dữ liệu
Dù vậy hoàn toàn không có trò phù phép thụt lề mang tính ngữ nghĩa. Việc dấu phẩy được xem như khoảng trắng và không bắt buộc là một điểm rất đẹp
Khi sinh viên nộp bài qua nền tảng e-learning, chúng tôi nhận tất cả bài nộp dưới dạng một file XML khá lớn
Chúng tôi đọc bài nộp, chuyển chúng cho phân tích tĩnh và chạy ví dụ, rồi viết một file YAML cho từng bài tập, trong đó có tất cả bài nộp, gợi ý chấm điểm, nhận xét và các trường nhập điểm
Sau đó từ file YAML, chúng tôi tạo báo cáo, thống kê và PDF phản hồi thông qua markdown+rendering (Pandoc)
Với chúng tôi, YAML rất phù hợp. Lý do là có thể dễ dàng thêm phản hồi bổ sung bằng cú pháp Markdown. Ví dụ như
- you missed a \NOT` here` được thụt lề đúngNhờ nhiều cách escape block text, dù sinh viên dùng các dấu phân cách SQL khác nhau, chúng tôi vẫn có thể hiển thị bài nộp SQL đẹp mắt mà không cần ký tự escape
Tất cả đều là plain text nên chỉ cần dùng trình soạn thảo văn bản, và lưu trong git để bảo đảm trách nhiệm giải trình khi chấm điểm. Vì mọi thứ được lưu theo cách máy có thể đọc, chúng tôi cũng có thể thử nghiệm các công cụ phân tích tĩnh mới trên bài nộp cũ
Nhưng vì cả CI pipeline và cấu hình home automation cũng phải viết bằng YAML, nên tôi hiểu nỗi đau đó
Trong TOML, bạn phải từ bỏ việc thụt lề chuỗi nhiều dòng, làm giảm khả năng đọc, hoặc phải đặt dấu gạch chéo ngược ở cuối mỗi dòng. Không cách nào là lý tưởng
Vì vậy với DSL hoặc cấu hình cần chứa Markdown hay định dạng văn bản khác, YAML khá tốt và có lợi thế so với những thứ như TOML
Nhưng tôi sẽ không quy toàn bộ trách nhiệm của “sự mệt mỏi với YAML” chỉ cho các công cụ CI và DevOps đã chọn YAML làm định dạng vận chuyển cho DSL. Như bài gốc đã tổng hợp tốt, bản thân YAML cũng có vấn đề lớn
“Vấn đề Norway” nổi tiếng đã được giải quyết trong YAML 1.2, và vấn đề parse số có số 0 đứng đầu thành hệ bát phân cũng đã được giải quyết trong YAML 1.2. Việc ép kiểu quá mức đối với số, ngày, giờ, v.v. có thể gây bối rối. Các chế độ xử lý chuỗi nhiều dòng cũng có thể khá khó hiểu. Serialization không an toàn không còn là vấn đề với các parser hiện đại, nhưng khi dùng YAML trong các ngôn ngữ cũ có tính năng động như Ruby, Python, Java thì cần cẩn trọng
Tất cả những điều này là vấn đề của chính đặc tả YAML