یه داشبورد Full-Stack برای Proxmox با Vibe Coding ساختم: چیزی که واقعاً مهمه

ai devops golang proxmox homelab

۱۴ کامیت، ۱۱ هزار خط کد، یه ایجنت هوش مصنوعی

چند هفته پیش PVE Pilot رو منتشر کردم، یه داشبورد مدیریت Full-Stack برای Proxmox VE با بک‌اند Go/Gin، فرانت‌اند Next.js 16 و صف پیام NATS برای provisioning ناهمزمان. ۱۲۳ تا تست داره. کل پروژه با “Vibe Coding” توسط Claude Code ساخته شده، ایجنت CLI شرکت Anthropic.

می‌خوام دقیق بگم منظورم چیه، چون اصطلاح “Vibe Coding” خیلی حاشیه داره. من ننوشتم “یه داشبورد Proxmox بساز” و دست‌به‌سینه نشستم. کاری که واقعاً کردم طراحی یه سیستم بود. Go رو برای بک‌اند انتخاب کردم چون type safety قوی، concurrency عالی و یه باینری واحد برای دیپلوی می‌خواستم. NATS رو برای پردازش ناهمزمان جاب‌ها انتخاب کردم چون provision کردن یه VM شامل چندین فراخوانی کند API از Proxmox می‌شه که نباید یه HTTP handler رو بلاک کنن. یه اینترفیس proxmox.API با ۴۰ متد طراحی کردم تا هر handler و worker به یه انتزاع وابسته باشه، نه یه کلاینت مشخص، و کل سیستم با mock قابل تست بشه.

هوش مصنوعی چشم‌انداز معماری من رو اجرا کرد. اون چشم‌انداز رو خلق نکرد.

Vibe Coding واقعاً چه شکلیه

روند کار شبیه pair programming با یه توسعه‌دهنده جونیور خیلی سریع ولی گاهی بیش از حد مطمئن بود. من در سطح بالا توضیح می‌دادم چی می‌خوام و هوش مصنوعی یه پیش‌نویس کاری روی کل استک تولید می‌کرد. فلو backup رو توی سه جمله توضیح دادم (“Proxmox از vzdump با حالت snapshot و فشرده‌سازی zstd استفاده می‌کنه، بکاپ‌ها روی NFS ذخیره می‌شن، گزینه‌های فوری و زمان‌بندی‌شده لازم دارم”) و چهل دقیقه بعد یه UI کامل با SSE progress streaming بلادرنگ داشتم. هندلر Go، فراخوانی‌های API از Proxmox، کامپوننت‌های React، همه چیز.

این وسعت جاییه که هوش مصنوعی واقعاً می‌درخشه. سوئیچ بین Go، TypeScript، Docker Compose و اسکریپت‌های شل توی یه مکالمه بدون سربار ذهنی که معمولاً با توسعه چندزبانه همراهه. boilerplate و سیم‌کشی‌ها فوق‌العاده سریع کنار هم قرار گرفتن. و وقتی الگوی مبتنی بر اینترفیس رو با proxmox.API پایه‌گذاری کردم، هوش مصنوعی ۹۳ تست Go و ۳۰ تست فرانت‌اند با mock‌های مناسب و تست‌کیس‌های table-driven تولید کرد. الگو به اندازه کافی واضح بود که بتونه به‌طور مداوم تکرارش کنه.

ولی اینجاست که داستان جالب‌تر می‌شه.

جایی که فهم عمیق پروژه رو نجات داد

مشکل UPID

عملیات clone و start توی Proxmox به‌صورت همزمان تکمیل نمی‌شن. اونا UPID برمی‌گردونن (شناسه‌های یکتای پروسس برای تسک‌های پس‌زمینه). اولین پیاده‌سازی هوش مصنوعی سعی کرد موفقیت clone رو با چک کردن وجود VM مقصد تأیید کنه. این کار می‌کرد… بیشتر وقت‌ها. جز وقتی که نمی‌کرد، چون کپی دیسک هنوز در جریان بود و VM قفل شده بود. race condition‌های خاموش، بدترین نوعشون.

سه بار تکرار لازم بود تا درست بشه. نه به این خاطر که هوش مصنوعی نمی‌تونست کد polling رو بنویسه، بلکه چون من باید می‌فهمیدم چرا clone متناوباً خراب می‌شه. دیسک هنوز داشت کپی می‌شد. VM توی حالت قفل بود. نمی‌شه cloud-init رو روی یه VM قفل‌شده تنظیم کرد. وقتی علت ریشه‌ای رو فهمیدم، رفعش ساده بود: از WaitForTask(upid) برای polling اندپوینت وضعیت تسک تا تکمیل استفاده کردم. هوش مصنوعی پیاده‌سازی رو توی چند دقیقه نوشت. ولی تشخیص نیاز به فهم نحوه کار واقعی Proxmox زیر کاپوت داشت.

LXC در برابر QEMU: دو دنیای کاملاً متفاوت

این از نظر معماری مهم‌ترین مورد بود. هوش مصنوعی مدام سعی می‌کرد الگوهای VM رو روی کانتینرهای LXC اعمال کنه و هر بار خراب می‌شد. کانتینرهای LXC guest agent ندارن. اندپوینت /config بعد از ساخت password یا ssh-public-keys قبول نمی‌کنه، فقط موقع POST /lxc اولیه. Restore پارامترهای متفاوتی داره (ostemplate با restore=1 به جای archive). فیلتر storage از rootdir به جای images استفاده می‌کنه.

هیچ مقدار تکرار این رو حل نمی‌کرد. باید یه مسیر کد کاملاً جدا طراحی می‌کردم: SSH از بک‌اند به هاست Proxmox، بعد استفاده از pct exec برای اجرای دستورات داخل کانتینر. این یعنی اضافه کردن یه کلاینت SSH (golang.org/x/crypto/ssh)، متغیرهای محیطی جدید، Docker volume mount برای کلید خصوصی و base64 encoding برای اسکریپت‌ها تا از مشکلات shell escaping جلوگیری بشه.

هوش مصنوعی تمام اون کد رو نوشت وقتی من رویکرد رو طراحی کردم. ولی خود رویکرد از فهم عمیق معماری Proxmox اومد، به اندازه‌ای عمیق که بدونم LXC و QEMU تکنولوژی‌های مجازی‌سازی کاملاً متفاوتی با API‌های مدیریتی کاملاً متفاوت هستن.

تله Guest Agent

اندپوینت /agent/exec مربوط به guest agent توی Proxmox یه بدنه JSON با command: "bash" و input-data به عنوان stdin نیاز داره. هوش مصنوعی درخواست‌های form-encoded فرستاد. Proxmox با کد وضعیت 596 و “Broken pipe” جواب داد. همین. نه پیام خطای مفید، نه اشاره‌ای به content type.

هوش مصنوعی حدس زد. encoding‌های مختلف، پارامترهای مختلف، اندپوینت‌های مختلف رو امتحان کرد. من با شناختن الگو تشخیصش دادم: “Broken pipe” روی یه POST معمولاً یعنی سرور بدنه رو قبل از خوندن کامل رد کرده، که فریاد content-type mismatch می‌زنه. سوئیچ به JSON با نام فیلدهای درست فوری حلش کرد.

همین پویایی رو با encoding کلید SSH دیدم. Proxmox برای فاصله‌ها %20 نیاز داره نه +، و url.QueryEscape توی Go + تولید می‌کنه. هوش مصنوعی سه رویکرد امتحان کرد؛ من RFC 3986 در مقابل HTML form encoding رو فهمیدم و فیکس رو توی یه حرکت تجویز کردم. وقتی مشکل “دو استاندارد معتبر و این API نادرترش رو انتخاب کرده” باشه، فهم استانداردها هر بار brute-force رو شکست می‌ده.

وقتی هیچ مستنداتی وجود نداره

بعضی مشکلات رو هوش مصنوعی به‌سادگی نمی‌تونه حل کنه. موقع راه‌اندازی پشتیبانی IP ثابت، VM‌هایی با IP خارج از محدوده DHCP نمی‌تونستن به اینترنت وصل بشن. هوش مصنوعی تنظیمات مختلف cloud-init، gateway‌های مختلف، subnet mask‌های مختلف رو امتحان کرد. هیچ‌کدوم کار نکرد، چون مشکلی توی تنظیمات نبود. روتر خونگی من برای IP‌هایی که خودش از طریق DHCP تخصیص نداده NAT نمی‌کنه. این رو فقط وقتی کشف می‌کنی که سخت‌افزار واقعی توی یه شبکه واقعی اجرا کنی. فیکس این بود که IP‌های ثابت رو داخل محدوده DHCP ولی خارج از pool داینامیک تخصیص بدم، چیزی که هیچ مستنداتی بهش اشاره نمی‌کنه چون روترهای سازمانی این محدودیت رو ندارن.

این الگو تکرار شد. کانتینرهای LXC روی Debian 12 مشکل ssh.socket در مقابل ssh.service دارن که SSH “running” به نظر می‌رسه ولی اتصال قبول نمی‌کنه. سندباکس Grafana توی کانتینرهای LXC بدون privilege بی‌سروصدا خراب می‌شه. اینا باگ‌های هوش مصنوعی نیستن. اینا دانشی هستن که از اجرای زیرساخت به دست میاد، نه از خوندن درباره‌ش.

چیزی که الان واقعاً کمیابه

تز اصلی که مدام بهش برمی‌گردم اینه: نوشتن کد داره به یه کالا تبدیل می‌شه. هوش مصنوعی می‌تونه کد از نظر نحوی درست، خوش‌ساختار و اصطلاحاً مناسب رو سریع‌تر از هر انسانی تولید کنه. ولی کد همیشه بخش آسون بوده. بخش‌های سخت همیشه چیزهای اطراف کد بودن، و اونا آسون‌تر نشدن.

تفکر سیستمی. دیباگ فراتر از پیام خطا. دانش حوزه‌ای از اجرای زیرساخت واقعی. قضاوت معماری درباره اینکه کدوم انتزاع‌ها ارزش سرمایه‌گذاری دارن و کدوم‌ها نشتی هستن. هر داستان توی این نوشته نمونه‌ای از یکی از ایناست، و توی هر مورد هوش مصنوعی گیر کرده بود تا من فهمی رو آوردم که خودش نمی‌تونست تولید کنه.

مبانی علوم کامپیوتر (concurrency، شبکه، طراحی سیستم، الگوهای طراحی API) با هوش مصنوعی منسوخ نمی‌شن. دارن تبدیل به تمایز بین کسی که می‌تونه به یه هوش مصنوعی پرامپت بده و کسی که واقعاً می‌تونه نرم‌افزار کارآمد تحویل بده می‌شن.

امتحانش کن، بشکنش، بهترش کن

PVE Pilot اوپن‌سورسه و توی github.com/ashkankamyab/pve-pilot در دسترسه. اگه یه homelab با Proxmox داری، یه امتحانی بکن. provision کردن VM و کانتینر با progress streaming بلادرنگ، بکاپ و ریستور (فوری یا زمان‌بندی‌شده)، ارتقا‌پذیری عمودی، مدیریت دیسک و تنظیم شبکه ثابت یا DHCP رو پشتیبانی می‌کنه، همه از طریق یه UI تمیز با تم تیره.

کدبیس خوب تست شده (۱۲۳ تست روی بک‌اند و فرانت‌اند) و معماری عمداً تمیز نگه داشته شده. اگه می‌خوای مشارکت کنی CONTRIBUTING.md رو ببین. PR خوش‌آمده، چه تخصص عمیق Proxmox داشته باشی، چه مهارت Go یا Next.js، چه دنبال یه پروژه واقعی باشی تا روند Vibe Coding خودت رو روش تمرین کنی.

اگه باگ پیدا کردی یا فیچری می‌خوای، یه issue باز کن. اوپن‌سورس همینجوری کار می‌کنه. یه کامیت در هر بار، هر کدوم چیز رو یه ذره بهتر از قبل می‌کنه. با هوش مصنوعی یا بدونش.