Skip to main content

Posts

Showing posts from March, 2025

Điều gì tệ hơn "mất bò mới lo làm chuồng"

Nửa tháng sau khi GitHub action tj-actions/changed-file bị hack , thế giới có gì thay đổi? Xưa các cụ có câu "mất bò mới lo làm chuồng", nhằm phê phán việc không quan tâm đến chuồng của con bò. Nhưng điều tệ hơn là gì? mất bò xong vẫn không làm chuồng Trong ngành IT (hay việc gì cũng thế), thất bại là chỗ người ta rút kinh nhiệm để tiến bộ hơn, phát triển hơn hôm qua. Thôi thì qua đã mất bò thì làm chuồng để mai không mất nữa. Nhưng như mọi "kinh nghiệm", nó không được học qua "chuyện kể"/"lời khuyên" mà chỉ thực sự thấm nếu đã phải trả giá. Internet vẫn tiếp tục dùng GitHub action không pinning tới SHA1 commit hash... Blog FAMILUG do 1 phút lười biếng cũng dùng GHA nelsonjchen/gh-pages-pelican-action@master , để rồi hôm nay trả giá 30 phút gỡ bỏ GHA này. GHA build blog FAMILUG giờ chỉ còn dùng action chính thức của GitHub. Mà nếu GitHub bị hack... thì mọi lo lắng khác đều không có nghĩa lý gì khi blog familug.github.io chạy trên GitHub pag...

Rust tuple, array, slice và compile time size

Hay làm thế nào để "stack overflow" trong Rust. Tuple và array là 2 kiểu dữ liệu primitive compound trong Rust. Compound types can group multiple values into one type. Compound type có thể gộp nhiều giá trị vào 1 kiểu. Xem code online và làm theo tại playground . Tuple Tuple là 1 cách để gộp nhiều giá trị có kiểu khác nhau vào 1 kiểu compound (kiểu gộp?). Các phần tử của tuple nằm trong cặp () , phân cách nhau bằng dấu phẩy , . Tuple hỗ trợ phép destructuring , để tách 1 tuple thành nhiều phần (tương tự Python unpacking). Truy cập từng phần tử theo thứ tự bằng cú pháp T.0 T.1 T.2 ... fn main() { let tup = ("Pika", 42); // type (&str, i32) let (name, number) = tup; println!("Name: {name}: number {number}"); println!("Name: {}", tup.0); } // Name: Pika: number 42 // Name: Pika Tuple không chứa phần tử nào gọi là 1 unit () . Các biểu thức không trả về gì sẽ tự động return unit () . Array An array is a fixed-size s...

[TIL] Bài học từ vụ GitHub Action tj-actions/changed-file bị hack

Ngày 14/3/2025, cộng đồng mạng hoảng loạn vì 1 GitHub Action có tên tj-actions/changed-file bị hack, thay đổi code, để in ra các token dùng khi chạy GitHub action. Lý do hoảng loạn: có tới hơn 23 nghìn repo sử dụng action này... để tìm các file đã đổi trong pull request. Bài viết report sự việc: https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised Các vấn về GitHub Action Có rất nhiều vấn đề khi nhìn lại ở đây, đơn giản như: tj-actions là ai? gõ mấy câu lệnh để tìm được file đã thay đổi trong 1 git pull request? uses: tj-actions/changed-files@v45 đã cố định ở v45? git tag không cố định (mutable) @v45 là sử dụng git tag v45 . v45 là 1 git tag, và có thể thay đổi, có thể point tới commit khác. Theo git tag --help : On Re-tagging What should you do when you tag a wrong commit and you would want to re-tag? .. 2. The insane thing. You really want to call the new version "X" too, even though others have already se...

[TIL] podman có thể tạo ra systemd unit config file

podman - chương trình phổ biến ngày nay để thay thế docker, có tính năng sinh systemd unit configuration file giúp deploy container 1 cách thuận tiện. $ podman run -p 8000:80 docker.io/nginx $ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2d81df8a1a11 docker.io/library/nginx:latest nginx -g daemon o... About a minute ago Up About a minute ago 0.0.0.0:8000->80/tcp wizardly_ptolemy # ở cửa sổ khác $ podman generate systemd 2d81df8a1a11 # container-2d81df8a1a117e290052df6e18f592ddb21f83b1b159169cc3391f605aaa47a7.service # autogenerated by Podman 3.4.4 # Wed Mar 19 20:08:06 JST 2025 [Unit] Description=Podman container-2d81df8a1a117e290052df6e18f592ddb21f83b1b159169cc3391f605aaa47a7.service Documentation=man:podman-generate-systemd(1) Wants=network-online.target After=network-online.target RequiresMountsFor=/run/user/1000/containers [Service] Environment=PODMAN_SYSTEMD_UNIT=%...

[clojure] update map với cond->

Kiểu dữ liệu map trong clojure tương tự dict trong Python. Do Clojure mọi kiểu dữ liệu đều là immutable, nên mọi thao tác với map đều trả về 1 map mới. Để update 1 map dựa theo điều kiện sẽ khá phức tạp cho đến khi dùng cond-> macro. Ví dụ code Python tương ứng options = {"max-keys": 100} if 1 == 1: options["next-token"] = "abcd" if 1 != 1: print("won't run") if 5 > 3: options["other-op"] = "hehe" def call_api(url, options): print(url, options) call_api("https://url", options) # https://url {'max-keys': 100, 'next-token': 'abcd', 'other-op': 'hehe'} Macro cond-> nhận vào các cặp điều kiện - function để chạy khi điều kiện đúng, sử dụng để update dict: (def init-options {:max-keys 100}) (def options (cond-> options (= 1 1) (assoc :next-token "abcd") (not= 1 1) (prn "won't r...

Tổng hợp tài liệu tự học tiếng Nhật giao tiếp N5 N4

Bài này tổng hợp các tài liệu học tiếng Nhật trên máy tính/ điện thoại, bằng cả tiếng Việt và tiếng Anh, miễn phí lẫn có phí. Hai bảng chữ cái Hiragana, Katagana Học ngôn ngữ thì việc đầu tiên rõ ràng là cần thuộc bảng chữ cái, không thẻ nhìn vào cả bảng rồi "học" mà sẽ nhớ dần từng chữ qua 3-6 tháng trở đi. Free|Eng: Learn ALL Hiragana in 1 Hour - How to Write and Read Japanese của #JapanesePod101 https://www.youtube.com/watch?v=6p9Il_j0zjc Free|Eng: Learn ALL Katakana in 1 Hour - How to Write and Read Japanese của #JapanesePod101 https://www.youtube.com/watch?v=s6DKRgtVLGA Free|Vie: Bảng chữ https://www.nhk.or.jp/lesson/vi/letters/hiragana.html Các tài liệu khác https://www.tofugu.com/japanese/best-hiragana-and-katakana-learning-resources/ Từ điển Jisho https://jisho.org/ có thể tra cứu bằng tiếng Anh lẫn tiếng Nhật (kana & kanji) Các mẫu câu hội thoại kèm nghe đọc Free|Vie: NHK WORLD-JAPAN Cùng nhau học tiếng Nhật https://www.nhk.or.jp/lesson/vi/lesson...

[TIL] Argo Rollouts có nút bấm restart trên giao diện ArgoCD

Argo CD là gì Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. https://argoproj.github.io/cd/ Argo CD và FluxCD là 2 lựa chọn phổ biến để thực hiện "Continuous Delivery" (CD) trên Kubernetes. Argo CD có giao diện nên thường được ưa chuộng hơn. Argo Rollouts là gì Argo Rollouts is a Kubernetes controller and set of CRDs which provide advanced deployment capabilities such as blue-green, canary, canary analysis, experimentation, and progressive delivery features to Kubernetes. https://argoproj.github.io/argo-rollouts/ Kubernetes Deployment mặc định hỗ trợ strategy deploy RollingUpdate, nhưng chiến thuật này có nhiều hạn chế. Argo Rollouts hỗ trợ nhiều chiến thuật deploy như blue-green, canary với nhiều tính năng phức tạp hơn. Restart rollout Khi cần restart các pod trong 1 rollout, các cách làm: xóa từng pod đi để replicaset sẽ tạo lại pod mới (không khả thi với số lượng pod lớn, bấm mỏi tay) xóa replicaset đi để rollout tạo lại replicase...

Luôn test ít nhất 3 case

Khi viết 1 tool hay viết code, một câu hỏi có thể nảy sinh là: test bao nhiêu trường hợp cho đủ? Câu trả lời luôn nhận được là: càng nhiều càng tốt! Nhưng test ít nhất là bao nhiêu? 1 2 3 4? bài viết này xin đưa ra 1 con số kèm theo lý do: 3. Giả sử đang viết 1 tool cli kiểm tra syntax của file yaml/json. Tạm gọi là checker . checker nhận vào argument là các file cần check. 3 case chụm lại nên hòn đá to Tại sao lại là 3? vì 3 gồm những trường hợp sau: 0 1 0 và 1 phân biệt giữa không và có. 1 2 trở lên 1 và 2 (trở lên) phân biệt giữa ít và nhiều. Tool hỗ trợ nhận 1 file đầu vào HẦU HẾT chưa chắc nhận 2 (vd: --config). Ngoài ra, có thể thêm test case thứ 4 khi bài toán có số N là max thì hãy test N. 0 - trường hợp luôn đặc biệt checker nhận 0 đầu vào: chương trình sẽ làm gì? fail với yêu cầu phải có đầu vào? hay test tất cả các file trong thư mục hiện tại (thường chọn cách này) 1 khác với nhiều Trong tiếng Anh, 1 bottle không có s , nhiều bottles thì có s . Khi tes...

[TIL] SQL join có cả cross join

Một bức hình đáng giá ngàn lời nói, bức vẽ SVG này copy từ tài liệu của sqlite https://www.sqlite.org/syntax/join-operator.html 3 loại JOIN, 3 loại OUTER JOIN NATURAL LEFT OUTER JOIN , RIGHT FULL INNER CROSS Có 3 loại join: (LEFT|RIGHT|FULL) [OUTER] INNER CROSS Ví dụ cross join $ sqlite3 SQLite version 3.37.2 2022-01-06 13:25:41 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite> -- Create temporary tables for our sets WITH set1 AS ( SELECT 1 AS a UNION ALL SELECT 2 UNION ALL SELECT 3 ), set2 AS ( SELECT 4 AS b UNION ALL SELECT 5 UNION ALL SELECT 6 ) -- Perform cross join to create Cartesian product SELECT set1.a, set2.b FROM set1 CROSS JOIN set2 ORDER BY set1.a, set2.b; 1|4 1|5 1|6 2|4 2|5 2|6 3|4 3|5 3|6 Kết luận Hết. HVN at https://pymi.vn and https://www.familug.org . Ủng hộ tác giả ...

Popular posts from this blog

Tài liệu và hướng dẫn học Python

Để tiết kiệm thời gian, tốt nhất là đi học PyMI Updated: 130617 Sau đây là các tài liệu khuyên dùng: Vì nhiều lý do, nên học python2.7 tại thời điểm hiện tại (giờ là tháng 6/2013 - muốn biết tại sao thì tự tìm hiểu) python 3.5+ (giờ là tháng 2/2017) Chuẩn bị: 1. biết bật tắt máy 2. biết cài python 3. tập gõ 10 ngón - gõ 2 ngón hay 1 ngón cũng không sao, nhưng 10 ngón là cách dễ nhất để gõ nhanh nhất. Tài liệu - Nên dùng tài liệu tại trang chủ của Python làm chính, tham khảo thêm các tài liệu khác tại http://www.familug.org/2016/12/free-ebook.html Căn bản, mới học 1.1 Python PyMI.vn https://pymi.vn/tutorial/ 1.2. Python offical tutorial kết hợp làm bài tập trên HackerRank  (đề bài bằng tiếng Anh, nhưng Google translate 1 lúc cũng ra vì có nhiều ví dụ mẫu đi kèm). Học viên của Pymi.vn có rất nhiều học viên đã tự học với Learn Python the hard way nhưng chưa thấy ai thành công cả. Hai link dưới nên đọc sau khi đã nắm được những phần cơ bản của ngôn ngữ pytho...

The PyMiers

New FAMILUG