AI 资讯
Podcast: How eBPF Empowers Developers to Observe Inside the Linux Kernel in a Safe and Unintrusive Way
Dan Fineran explores how eBPF has evolved far beyond its roots in packet filtering into a robust, safe way to extend the Linux kernel. He explains how the eBPF "verifier", the security guardrail, enables implementation of deep observability and networking without the risks of traditional kernel modules or the slow upstreaming process. By Dan Fineran
开发者
👾 Server Access Logs with GoAccess
Part 1: Self-hosting on Jetson Orin Nano 👽 Jetson Orin Nano Web Server Follow-up...
AI 资讯
Meet mytuis: A Sleek Terminal Application Manager Built with Bash and Gum
Having spent over 25 years in software development and managing countless Linux environments, I've accumulated a vast collection of custom bash scripts, containers, and CLI tools. Remembering their exact paths and managing them efficiently directly from the terminal is a common challenge. To solve this, I built mytuis . mytuis is a small, attractive terminal UI for managing a personal catalogue of applications. It is built with gum and plain bash, with persistent storage in a human-readable YAML file. GITHUB REPO : https://github.com/horaciod/mytuis Why mytuis? I wanted a tool that didn't require heavy dependencies or a complex setup, but still looked great and provided a smooth user experience. Here is what mytuis brings to the terminal: CRUD operations: You can create, read, update, and delete application entries from a single menu. Quick launch: Pick an app from the filterable list and it is launched immediately. It replaces the manager process via exec, meaning no extra shell window is left behind. Smart path handling: It accepts absolute paths (like /usr/bin/firefox), relative paths (./scripts/myscript.sh), tilde paths (~/bin/foo), or plain command names looked up in your $PATH (firefox). Persistent metadata: Every entry stores its name, description, absolute path, creation date, and last-used date. Friendly TUI: You get clear menus, color-coded messages, and clean borders, all powered by gum. Under the Hood: Plain Text and Standard Utils Simplicity and standard compliance were key goals. mytuis requires bash ≥ 4 and standard Unix utilities like awk, sed, grep, date, and tput. Your catalogue is stored at ~/.mytuis.yaml. Because it is a standard YAML file, it can be inspected, edited, or backed up with any text editor. It is also completely safe to sync with a dotfiles repository or version-control. To ensure data integrity, all file operations are performed atomically by rewriting the YAML file from scratch on every change, so there is no risk of leaving the fi
AI 资讯
100 Days of DevOps, Day 1: Linux User Management and AWS Key Pairs
Doing the work and being able to explain the work are two different skills. I've had the first one for 8 years. I'm building the second one now. I'm a Cloud Platform Engineer. AWS, Kubernetes, Terraform, Linux. Regulated environments, healthcare, production systems. Real experience. Almost zero public documentation of it. That's the gap I'm closing, starting from Day 1. The platform is KodeKloud. Each session gives you tasks across multiple tools. I'm posting the Linux and AWS tasks here. Here's what I built and what actually matters about each one. Task 1 (Linux): Create a User with a Non-Interactive Shell The task was to create a system user that can own processes but cannot log in interactively. This is what you do for service accounts. bash ssh user@hostname sudo su - useradd username -s /sbin/nologin cat /etc/passwd | grep username The /sbin/nologin shell is the important part. The user exists in the system, can own files and run processes, but cannot open a shell session. You verify by checking /etc/passwd because the last field in each line is the assigned shell. I've been doing this in production environments for years. I still verify every time. Not because I'm unsure. Because in a regulated environment, you don't assume, you confirm. Task 2 (AWS): Create an EC2 Key Pair via CLI aws ec2 create-key-pair \ --key-name my-key-pair \ --key-type rsa \ --key-format pem \ --query "KeyMaterial" \ --output text > my-key-pair.pem aws ec2 describe-key-pairs --key-names my-key-pair The private key is returned exactly once at creation. AWS does not store it. If you lose it, you generate a new one and replace it everywhere it was used. I've seen this cause real problems in production environments where the key wasn't backed up properly. Always run chmod 400 my-key-pair.pem after saving it. SSH will refuse to use a key file with open permissions. It won't tell you that's the reason straight away. What Day 1 Taught Me That 8 Years Didn't Nothing here was technically new to
AI 资讯
Cử chỉ Trackpad trong Workflow Code: ROG Zephyrus G14 hay MSI Creator 16 AI?
Đối với một developer, trackpad không chỉ là thiết bị điều hướng mà còn là công cụ tối ưu hóa workflow. Khi làm việc với các IDE nặng như VS Code hay IntelliJ, khả năng phản hồi của trackpad quyết định tốc độ xử lý tác vụ. Trong bài so sánh giữa ROG Zephyrus G14 GA403 hay MSI Creator 16 AI? Đâu là lựa chọn cho sáng tạo chuyên nghiệp? , trải nghiệm trackpad là một điểm nhấn quan trọng. Trải nghiệm cử chỉ và độ chính xác trong lập trình Khi làm việc với code, các cử chỉ như chuyển đổi desktop ảo (Virtual Desktops) là cực kỳ quan trọng để tách biệt môi trường chạy Docker, trình duyệt và editor. Vuốt 3-4 ngón: Cả hai dòng máy đều hỗ trợ tốt, nhưng trên MSI Creator 16 với diện tích lớn hơn, việc nhận diện cử chỉ vuốt ngang giữa các workspace mượt mà hơn đáng kể. Độ chính xác chọn văn bản: Với một developer, việc bôi đen một đoạn code dài hoặc chọn chính xác một ký tự nhỏ là yếu tố sống còn. Trackpad trên G14 có độ nhạy cao nhờ kích thước gọn nhẹ, trong khi Creator 16 cho cảm giác vững chãi, ít bị trượt hơn khi thao tác nhanh. Độ trễ (Latency): Cả hai đều đạt chuẩn cao, tuy nhiên trên Windows, trải nghiệm đôi khi không mượt bằng macOS. Để khắc phục, việc sử dụng driver tùy chỉnh là cần thiết. So sánh hệ điều hành và mẹo cấu hình cho Developer Trải nghiệm trackpad thay đổi rõ rệt giữa Windows và Linux : Windows: Hỗ trợ tốt Precision Drivers. Bạn nên vào Settings > Bluetooth & devices > Touchpad để tinh chỉnh độ nhạy.\n- Linux: Nếu bạn dùng Ubuntu hay Fedora, hãy cài đặt libinput . Để tối ưu hóa cho workflow code, bạn có thể cấu hình file .wslconfig nếu chạy môi trường Windows Subsystem for Linux nhằm đảm bảo tài nguyên không bị nghẽn khi thao tác giao diện.\n Thông số kỹ thuật tóm tắt: ROG Zephyrus G14 GA403: Ryzen 9 8945HS, RTX 4070, 32GB LPDDR5X, OLED 14" 120Hz, nặng 1,5 kg. MSI Creator 16 AI Studio: Core Ultra 9 185H, RTX 4080/4090, lên đến 64GB DDR5, Mini LED 16" 120Hz, nặng 2,1-2,5 kg. Bài viết này là bản tóm tắt kỹ thuật. Xem chi tiết tại bài gốc.
开发者
Memory Profiling: Valgrind & Heaptrack trên WSL2 vs Native Linux
Là một developer thường xuyên đối mặt với các lỗi memory leak trong hệ thống C++/Rust, việc chọn môi trường profiling là yếu tố sống còn. Nếu bạn đang cân nhắc giữa việc chạy Valgrind hay Heaptrack trên WSL2 so với Native Linux (hoặc máy trạm có RAM SO-DIMM nâng cấp được), đây là những trải nghiệm thực tế từ quá trình debugging. Hiệu năng Valgrind và Heaptrack: Sự khác biệt rõ rệt Khi sử dụng valgrind --tool=memcheck , tốc độ thực thi thường giảm xuống còn 10-50 lần so với bình thường. Trên Native Linux , việc quản lý bộ nhớ diễn ra trực tiếp trên kernel, giúp các công cụ này hoạt động ổn định nhất. Ngược lại, trên WSL2 , do lớp ảo hóa và cơ chế quản lý memory của Microsoft, bạn sẽ thấy overhead đáng kể hơn. Đặc biệt là khi tạo Heaptrack flame graph , việc phân tích bộ nhớ lớn có thể khiến WSL2 bị giới hạn bởi file .wslconfig nếu không cấu hình đủ RAM.\n Lệnh thực thi nhanh: # Chạy Valgrind trên hệ thống của bạn valgrind --leak-check = full --show-leak-kinds = all ./your_app # Sử dụng Heaptrack để lấy flame graph chi tiết hơn heaptrack ./your_app WSL2 Overhead và bài toán phần cứng (Onboard vs SO-DIMM) Một vấn đề thực tế là khi profiling các ứng dụng nặng, bộ nhớ hệ thống bị chiếm dụng cực nhanh. Nếu bạn đang dùng laptop với RAM onboard 16GB , việc chạy đồng thời Docker + IDE + Valgrind trên WSL2 dễ dàng dẫn đến tình trạng swap liên tục do giới hạn cứng của phần cứng. Từ kinh nghiệm thực tế, nếu công việc yêu cầu profiling chuyên sâu thường xuyên, một chiếc máy có RAM SO-DIMM cho phép nâng cấp lên 32GB hoặc 64GB sẽ là cứu cánh tuyệt vời. Bạn có thể tham khảo thêm về sự khác biệt giữa ReviewLaptop để hiểu rõ tại sao việc chọn đúng loại RAM lại quan trọng cho workflow của một developer. Bảng so sánh nhanh: | Đặc điểm | Native Linux | WSL2 (Ubuntu) | --- | --- | --- | | Speed Overhead | Thấp hơn (Direct Kernel) | Memory Management | Trực tiếp, ổn định | Có lớp ảo hóa, dễ bị giới hạn bởi .wslconfig | | Flame Graph Rendering | Mượt mà | Đôi khi chậm do I/O file qua hệ th
AI 资讯
Most AI dev tools assume you have a repo. Ops engineers have a broken node and a 3am page.
Most AI coding tools assume you're sitting in front of a repo. There's a working directory, some source files, tests, maybe a CI pipeline. The AI reads your code, suggests changes, ru****ns tests. Great model — if you're a developer writing code on a Tuesday afternoon. Now picture the other scenario. It's 2am. PagerDuty fires. You SSH into a box you haven't touched in three months. Something is broken, you're not sure what, and the runbook was last updated by someone who left the company in 2022. You're not thinking about repos. You're thinking: what OS is this thing running? What just failed? Is it safe to restart that service or will I make it worse? These are two fundamentally different workflows. But almost every AI terminal tool I've seen is built for the first one. The 30 minutes nobody builds for There's a ton of tooling for the world before you log into the box: Prometheus, Grafana, PagerDuty, incident.io, runbooks, dashboards. All useful. No complaints. But there's this practical 30-minute window after you SSH in where you're basically doing archaeology with journalctl and grep. You check systemd. You look at disk. You read logs that were clearly written by someone who hated future-you. You copy-paste terminal output into Slack so your teammate can squint at it from a different timezone. This is where I think AI could actually help. Not by replacing Grafana. Not by building another dashboard. Just by being present in the shell while you're debugging. Please, for the love of uptime, don't replace my shell I've seen a few AI terminal projects that basically build an entire new terminal experience from scratch. New keybindings, new UI, new everything. Here's the thing: ops people have muscle memory. We have aliases we wrote in 2019 and forgot about. We have tmux configs we'd defend with our lives. We SSH through jump hosts with key forwarding chains that barely work but have worked for years so nobody touches them. If your AI tool requires me to abandon all of
AI 资讯
Linux 7.1, tRPC's Query Overhaul, and Biome 2.0 Beta: What Developers Need to Know
This week's tooling landscape is quieter on the AI-native side but dense with infrastructure moves that affect how AI-driven workloads actually run in production. Cloudflare's Workflows scaling overhaul is the clearest signal: agent-triggered execution is now an assumed pattern, not a novelty, and platforms are rearchitecting accordingly. The rest of the week rounds out with a kernel maintenance drop, a meaningful abstraction removal in tRPC, and a Biome beta that's finally making ESLint replacement feel plausible. Linux 7.1 Released with Driver and Networking Fixes 7.1 is a maintenance release. No architectural changes, no new subsystems—just patches you should care about if you're running affected hardware or kernel-adjacent tooling. The two fixes worth flagging are heap overflows in the USB serial io_ti driver ( get_manuf_info() and build_i2c_fw_hdr() ), plus memory leak corrections scattered across drivers and networking subsystems. Trace tooling also gets updates, which matters if you're doing kernel-level performance analysis on production systems. One operational note: Torvalds is traveling, so merge window latency may be irregular. If you're tracking pull request timelines for custom kernel builds, plan for slippage. Verdict: Ship — if you're on 7.0 and running USB serial hardware or affected networking paths, upgrade on your normal kernel cycle. No breaking changes, no new dependencies, nothing to validate beyond your existing regression suite. tRPC Drops Abstraction Layer for React Query This is the kind of change that looks small in a changelog and feels large in daily development. The new tRPC client exposes native TanStack Query interfaces— QueryOptions and MutationOptions —directly, rather than wrapping them in tRPC-specific hooks. The practical effect: if you're already using TanStack Query elsewhere in your app, you stop context-switching between two similar-but-different mental models. You call .queryOptions() and .mutationOptions() factories and pa
AI 资讯
Use the Telegram Bot API in OpenClaw via Cloudflare WARP (1.1.1.1)
You run a Telegram bot through OpenClaw on your own Linux server. One day it goes quiet. The bot can't send or receive. But the server itself is fine — SSH works, apt works, other sites load. The reason: your server can't reach api.telegram.org . Some networks block or throttle it, so every call times out while everything else is fine. The clean fix: route only OpenClaw's Telegram traffic through Cloudflare WARP (1.1.1.1) . Everything else on the box stays direct and fast — including your SSH login. Here is the full setup, step by step. First, confirm it's a Telegram-only problem curl --max-time 8 https://api.telegram.org/ # hangs / times out curl --max-time 8 https://www.google.com/ # works instantly If Telegram times out but other sites are quick, this guide is for you. How it works We chain three small tools: OpenClaw ──▶ iptables ──▶ redsocks ──▶ WARP (SOCKS5) ──▶ Cloudflare ──▶ api.telegram.org WARP gives us a local proxy that exits through Cloudflare's network (which can reach Telegram). redsocks turns normal connections into proxy connections (so the app needs no proxy support — OpenClaw has none). iptables picks only OpenClaw's Telegram traffic and sends it to redsocks. The trick is in that last step. We match by the app's user and Telegram's IP ranges, so nothing else is touched. Step 1: Install WARP in proxy mode # Add Cloudflare's package repo curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg \ | gpg --yes --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] \ https://pkg.cloudflareclient.com/ $( lsb_release -cs ) main" \ > /etc/apt/sources.list.d/cloudflare-client.list apt-get update && apt-get install -y cloudflare-warp # Sign up (free) and switch to proxy mode warp-cli --accept-tos registration new warp-cli --accept-tos mode proxy # opens a SOCKS5 proxy on 127.0.0.1:40000 warp-cli --accept-tos connect Now check that WARP can reach Telegram: curl --socks5-
AI 资讯
The Hidden Linux Routing Issue That Broke My Deployment
The deployment should have taken a few minutes. The application was running, DNS was configured correctly, and the domain was already pointing to the server's public IP. Caddy was configured as a reverse proxy and was listening on ports 80 and 443. Every item on my deployment checklist appeared healthy. Yet every Let's Encrypt validation attempt kept failing. The error looked simple enough: authorization failed timeout during connect likely firewall problem At first, I believed it. I checked DNS resolution, verified firewall rules, confirmed that Caddy was listening on the expected ports, and made sure the application itself was reachable. Every check came back clean. That was the first clue that the problem might not be where the logs were pointing. The Obvious Things The first assumption was DNS. I verified that the domain resolved to the correct public IP. dig +short my-domain.com Everything looked correct. Next came the firewall. sudo ufw status Ports 80 and 443 were open. There were no unexpected deny rules, and nothing suggested inbound traffic was being blocked. Then I checked whether Caddy was actually listening. sudo ss -tulpn | grep -E ':80|:443' Again, everything looked normal. The application itself was healthy too. curl http://localhost:3001 returned a valid response. At this point I had checked most of the things engineers typically check when certificate validation fails. DNS looked good, the firewall looked good, the reverse proxy was healthy, and the application was running. Yet the validation errors continued. The Part That Sent Me In The Wrong Direction The error messages kept mentioning connectivity problems and possible firewall issues. That wording influenced my thinking more than it should have. I spent time investigating firewall rules, reverse proxy configuration, TLS settings, and domain configuration. Every new hypothesis felt reasonable, but none of them explained why local tests consistently succeeded while external validation continued
AI 资讯
How to Use Claude to Troubleshoot Linux Servers
Claude is genuinely useful for production Linux troubleshooting — when you use it right. Here's the workflow that works, after a year of using it on real incidents across Ubuntu, RHEL, and Rocky. The mental model: Claude is a senior pair, not an oracle The mistake most engineers make on day one: they paste a 5-line error message and expect a fix. Claude can do better than that — but only if you give it the same context you'd give a senior engineer joining your incident bridge. A senior engineer would want: What OS and version? What does this server do? What changed recently? What's the actual symptom? What command output have you already gathered? Give Claude that, and the quality of analysis changes completely. The workflow Step 1: Establish context with a system prompt Use our Linux Server Troubleshooting Prompt as your system prompt, or paraphrase: "You are a senior Linux sysadmin. Rank root-cause hypotheses by probability. Recommend safe diagnostics first. Label destructive commands as DANGEROUS." Step 2: Paste structured context, not noise Good: OS: Ubuntu 22.04, kernel 5.15 Role: production MySQL replica, 64GB RAM, 16 cores Recent changes: kernel upgrade 6 hours ago Symptom: server load average 40+, MySQL replication lag growing, queries timing out $ uptime 14:22:01 up 6:02, 4 users, load average: 41.23, 38.51, 35.04 $ free -h total used free shared buff/cache available Mem: 62Gi 58Gi 1.2Gi 128Mi 3.1Gi 1.8Gi $ iostat -xz 2 3 [...] Bad: my server is slow can you help Step 3: Let it ask follow-up questions The good prompts in our library tell Claude to ask for missing data before guessing. When it asks "can you share dmesg | tail -50 and vmstat 1 5 ?" — that's a feature, not a flaw. Give it the data. Step 4: Validate suggested commands before running Claude will sometimes suggest a command with subtly wrong syntax, a destructive flag, or a path that doesn't exist on your distro. Read every suggestion before running. Never paste straight into a root shell. Step 5
AI 资讯
From Mint to NixOS: Why a Long-Time Linux User Made the Switch
Background I started daily driving Linux back in 2019. The start of that journey was rough, and I still deeply appreciate the help I received in those early days from the old guard who kept me moving forward. Early on, I quickly found my home with Linux Mint and its Cinnamon desktop. As the saying goes, "You don't choose a Linux desktop; the desktop chooses you." Built on top of a stable foundation with a rich package infrastructure, Cinnamon provided a familiar experience that bridged the gap from Windows. It also afforded me excellent customization options right out of the box, such as configuring custom keyboard shortcuts or setting up auto-login startup scripts, while always getting out of my way. No adverts, no pop-ups, just a fast and efficient desktop environment. I won't lie, though: I distro-hopped multiple times just to see if the grass was greener. Through those escapades, I quickly realized I am definitely not a GNOME person; I do not like polyfilling my desktop experience with a suite of extensions. And as much as I appreciate KDE Plasma, I learned that with great customization comes great responsibility because it was far too easy for me to break my environment with just a few theme toggles. This is not a dig at those desktop environments; it just means I am not wired for that kind of experience. As I continued my Linux journey, my priorities shifted. I wanted a predictable operating system that could act as a trusted companion, both for my daily life as a software developer and as a casual user wanting to watch Netflix on the weekends. This is what made me appreciate Linux Mint even more. It featured a predictable release cycle, a stable package base built on Ubuntu LTS, and Timeshift to guard against system breakage during upgrades. However, two major friction points always bothered me: Stable but Stale Packages: Linux Mint's software is incredibly stable, but it is rarely fresh. For example, the okular package is consistently several versions behind
AI 资讯
The Only Productivity Hack That Actually Worked for Me
The Only Productivity Hack That Actually Worked for Me I've tried every website blocker in existence. They all have the same flaw: one click and they're off. That settings toggle might as well not exist when the urge to procrastinate hits. I needed something I couldn't override. So I built the opposite. The Problem Every blocker follows the same pattern: it blocks, you unblock, you procrastinate. The issue isn't discipline — it's that your future self and your present self want different things. And that future self will happily undo anything you set up. What I needed was a system where both selves agreed on the rules upfront and then neither could break them. The Solution kblocker is a Linux kernel module that hooks into netfilter and drops TCP connections to whatever sites I configure. The key feature isn't the blocking — it's how you turn it off. When blocking is enabled, kblocker generates a 128-bit key. With PGP mode, it automatically encrypts that key to people I trust and then erases it from kernel memory. The raw key no longer exists anywhere on my system. To disable the blocker, one of those people has to decrypt it and send it back to me. I outsourced my willpower. When I want to focus, I run: sudo kblockerctl enable 120 Two hours of blocked distractions. If I feel the urge to procrastinate, I can't — I'd have to text a friend, explain why, wait for them to decrypt it, and paste the result. By then the urge is gone. The Result I've gone from losing entire afternoons to YouTube to actually finishing things. The blocker has caught me mid-reflex to type youtube.com more times than I can count. It's free if anyone wants it: github.com/Dan-J-D/kblocker If you keep breaking your own focus tools, this is for you.
AI 资讯
OS Architecture, Kernel, Shell & File System
🐧 Linux for DevOps — Session 2: Understanding the Kernel, Shell, OS Architecture & File System 📓 Learning in public — These are my personal notes from my Linux for DevOps & Cloud journey. I'm sharing them in a way that's easy to revisit later and hopefully useful for anyone else starting out. In the previous session, I got comfortable with Linux basics and terminal access. This session focused on understanding what actually happens behind the scenes when we run commands , how Linux is structured internally, and how files are organized on the system. These concepts might sound theoretical at first, but they're the foundation of everything you'll do in DevOps—from managing EC2 instances and Docker containers to troubleshooting production servers. The Linux Kernel: The Heart of the Operating System The kernel is the most important component of Linux. Think of it as a translator sitting between software and hardware. Applications can't directly talk to the CPU, RAM, disks, or network interfaces. Instead, every request goes through the kernel. When you run a command, open a browser, start a Docker container, or deploy an application, the kernel is responsible for making it happen. Its main responsibilities include: Responsibility Purpose Resource Management Decides which process gets CPU time Memory Management Allocates and releases RAM Process Management Creates, schedules, and terminates processes Device Management Communicates with hardware through drivers Without the kernel, Linux would simply be a collection of files with no way to interact with hardware. Types of Kernels Not every operating system uses the same kernel design. Monolithic Kernel (Linux) keeps most operating system services inside a single kernel space. This approach is extremely fast because components communicate directly. Microkernel keeps only essential functionality in kernel space and moves other services outside. This improves isolation and stability but introduces additional overhead. Hybrid K
AI 资讯
Rebuilding the Hull at Sea
The box that ran everything started dying in April. Not dramatically. Machines almost never die dramatically. It started with instability... the kind you explain away once, side-eye twice, and start losing sleep over the third time production goes down while you're in the middle of something else. The host under my entire stack... public site, analytics, security tooling, the AI crew's memory layer... was getting flaky. And flaky hardware only trends one direction. Here's the thing about a homelab that lives in a 40ft fifth wheel: there is no second team. No vendor escalation. No change advisory board. No maintenance window negotiated three weeks out. There's me, a crew of governed AI instances, and a reclaimed Dell T3600 about to get the biggest promotion of its second life. So we didn't try to heal the sick box. We built a new hull alongside it and started moving the ship... plank by plank... while it was still sailing. One ground rule, set day one: the old host stays untouched and keeps serving production until the new hull is proven. Not "mostly proven." Proven. Hold that thought, it matters at the end. Moving containers is the easy part. Docker made that boring years ago, and boring is a compliment in infrastructure. What's never boring is the inventory of everything you assumed and never wrote down. A migration doesn't test your stack. It tests your assumptions. Here's what mine were hiding. 01: The umbilical nobody documented Security stack went first. Suricata, Zeek, Wazuh, CrowdSec, Falco, the whole alphabet, up clean on the new hull. Then the MCP server, the piece that gives the AI crew its hands, refused to come up right. It was hard-wired over HTTP to the crew's memory backend. A live dependency, in production for months, documented exactly nowhere. The crew that documents every f*cking thing had never documented its own umbilical cord. Fix was trivial once we could see it: deploy the brain before the hands. Reorder, redeploy, done. But the lesson isn't
AI 资讯
Stop Hand-Editing Fragile APT Lines: Practical deb822 `.sources` Files for Debian and Ubuntu
If you still manage APT repositories as long one-line deb ... entries, you are working with a format APT now explicitly marks as deprecated. It still works, but it is harder to read, harder to automate safely, and easier to get wrong when you add options like arch= or signed-by= . The better option is deb822 style .sources files. This post shows how to: read the structure of a .sources file migrate a legacy .list entry safely use Signed-By without falling back to apt-key disable a repository cleanly without deleting it verify that APT accepts the new configuration I am focusing on practical host administration, not packaging theory. Why move to deb822 now? The sources.list(5) man page now says the traditional one-line .list format is deprecated and may eventually be removed, though not before 2029. More importantly, deb822 solves real operational annoyances: fields are explicit instead of positional one stanza can describe multiple suites or types Enabled: no is cleaner than commenting lines in and out machine parsing is much easier Signed-By is clearer and safer in structured form On a current Debian host, you may already be using it without noticing: find /etc/apt/sources.list.d -maxdepth 1 -type f -name '*.sources' On my test system, the default Debian repository is already stored as /etc/apt/sources.list.d/debian.sources . The old format vs the new format A traditional one-line entry looks like this: deb [arch=amd64 signed-by=/etc/apt/keyrings/example.gpg] https://packages.example.com/apt stable main The same source in deb822 format becomes: Types: deb URIs: https://packages.example.com/apt Suites: stable Components: main Architectures: amd64 Signed-By: /etc/apt/keyrings/example.gpg That is the core win. Instead of cramming everything into one line and hoping spacing stays correct, each field says exactly what it means. Example 1, a clean Debian .sources file Here is a practical example for Debian using separate stanzas for the main archive and the security arch
AI 资讯
Nix Series: Basic Nix Language
Pada series sebelumnya, kita sudah melakukan instalasi nix di VirtualBox dan setup SSH agar dapat diakses diluar VirtualBox. Sebelum kita lanjut untuk melakukan konfigurasi system lagi, kita butuh mengetahui bagaimana syntax dalam menulis program Nix dan di artikel ini kita akan mempelajari dasar syntax-nya. Nix Language Nix adalah purely functional language yang lazy-evaluated , digunakan untuk mengkonfigurasi Nix package manager dan NixOS. Karakteristik utama: Purely functional : sebuah function hanya bisa mengembalikan nilai berdasarkan inputnya, tidak bisa mengubah variabel di luar scope-nya (no side effects), dan tidak ada variabel yang bisa diubah setelah didefinisikan (no mutation). Kalau kamu familiar dengan const di beberapa bahasa pemrograman, semua variabel di Nix berperilaku seperti itu. Lazy evaluation : Nix tidak menghitung nilai suatu ekspresi sampai nilai itu benar-benar dibutuhkan. Ini artinya kamu bisa mendefinisikan ribuan package di nixpkgs tanpa semuanya dievaluasi sekaligus. Hanya yang kamu gunakan saja yang akan diproses. Semua adalah expression : tidak ada statement di Nix, setiap baris kode selalu menghasilkan sebuah nilai. if/else bukan statement seperti di bahasa pemrograman pada umumnya, melainkan expression yang harus mengembalikan nilai dari kedua cabangnya. Tidak ada loops : karena variabel tidak bisa diubah, loop seperti for atau while tidak ada artinya di Nix. Sebagai gantinya, kamu menggunakan fungsi seperti map dan filter , atau rekursi untuk mengolah kumpulan data. 1. Basic Data Type Konsep JavaScript Nix String "hello" "hello" Number 42 , 3.14 42 , 3.14 Boolean true , false true , false Null null null List [1, 2, 3] [ 1 2 3 ] Object { a: 1 } { a = 1; } ⚠️ Perbedaan Penting List di Nix menggunakan spasi sebagai pemisah, bukan koma Attribute set menggunakan = bukan : , dan setiap entry diakhiri dengan ; Nix let name = "Alice" ; age = 30 ; scores = [ 10 20 30 ]; person = { name = "Bob" ; age = 25 ; }; in person Javascript const name
AI 资讯
I Built a Git Sync Tool for My Obsidian Vault
I Built a Git Sync Tool for My Obsidian Vault You write notes, you save them, you forget to push to GitHub. Then your laptop dies, and your notes are gone. I built a single Bash script that automates the entire sync workflow, and it works with any Git repo. If you use Obsidian (or any plain-text note-taking system) and sync via Git, you know the drill: write notes, stage changes, commit, fetch, check status, pull, push. Every time. It's 6 repetitive commands that you will inevitably skip until disaster strikes. I got tired of this and built git-sync , a single Bash script that does everything in one go. What It Does git-sync is a terminal-based Git sync tool that: Auto-commits all changes with a timestamp Fetches remote state Detects divergence (ahead/behind) Shows you only the relevant sync options Executes your choice with safety guard rails How It Works Run it from inside any Git repo: ./git-sync Phase 1 - Auto-commit: Staged or unstaged changes are committed automatically with a message like "Last Sync: Jun-12 (Arch)" . The device name is configurable. Phase 2 - Fetch & Detect: It fetches from remote, counts how many commits ahead and behind you are, and categorises the state: ahead, behind, diverged, or in-sync. Phase 3 - Smart Menu: Only relevant options are shown: State Options Ahead only Upload, Sync, Force push, Cancel Behind only Download, Sync, Hard reset, Cancel Diverged All six options Phase 4 - Execute: The chosen action runs with a spinner and status messages. Destructive operations (force push, hard reset) require explicit confirmation. Why It's Useful for Notes Syncing Obsidian + Git is a powerful combo. Your notes are plain markdown, version-controlled, accessible from any device. The friction is the sync ritual. git-sync removes it. Multi-device workflows: I run this on my Arch desktop (DEVICE_NAME="Arch") and my work laptop (DEVICE_NAME="Laptop"). The auto-commit message tells me exactly which machine made each sync, so I can trace conflicts back
AI 资讯
Recovering data from a failed RAID array with ddrescue: a practical walkthrough
When a RAID array fails, the worst thing you can do is panic and start poking at it immediately. I've seen too many cases where an impatient rebuild attempt overwrote the only good copy of data. This walkthrough covers how to safely approach a degraded or failed RAID — with ddrescue as your best friend. Step 0: Stop. Don't touch the array yet. Before running mdadm --assemble , before doing anything, clone your physical disks . A RAID 5 with one failed drive can lose everything the moment a second drive throws a read error during rebuild. This isn't hypothetical — it's how most total RAID losses happen. The golden rule: image first, recover second . Step 1: Assess the damage # Check current RAID state cat /proc/mdstat # More detail mdadm --detail /dev/md0 Look for: [UUU_] — one drive failed (underscore = missing) [UU__] — two drives failed (catastrophic for RAID 5) State: degraded , recovering , or failed Do NOT run mdadm --manage /dev/md0 --add /dev/sdX yet. Stop the array instead: mdadm --stop /dev/md0 Step 2: Clone each disk with ddrescue ddrescue is the right tool because it handles read errors gracefully: it maps bad sectors, retries them, and lets you resume interrupted sessions. Never use dd for a failing disk. Install it: # Debian/Ubuntu sudo apt install gddrescue # RHEL/CentOS sudo dnf install ddrescue Clone each RAID member to a separate image file (you need enough storage — same total size as all disks combined): # First pass: copy everything readable, skip bad sectors fast sudo ddrescue -d -r0 /dev/sda /mnt/backup/sda.img /mnt/backup/sda.log # Second pass: retry bad sectors up to 3 times sudo ddrescue -d -r3 /dev/sda /mnt/backup/sda.img /mnt/backup/sda.log Key flags: -d — direct disk access (bypass kernel cache) -r0 / -r3 — retry bad sectors 0 or 3 times The .log mapfile is critical: it lets you resume if the clone is interrupted Repeat for every disk in the array ( sdb , sdc , etc.). Step 3: Work from the images Once you have image files, assemble a soft
产品设计
High-severity vulnerability in Linux caused by a single errant character
Use-after-free bug can be exploited to evade sandbox defenses.