אריזה ותאימות סביבת היעד¶
קובץ executable שרץ בתיקיית הפיתוח עדיין אינו חבילה שאפשר להתקין. השירות צריך משתמש, תיקיות, הרשאות, יחידת הפעלה, נתוני תצורה ומדיניות להסרה. נבנה את ההפרדה בין קוד שהוא חלק מן הגרסה לבין נתונים שצריכים לשרוד שדרוג והסרה רגילה.
נבחר למעבדה binary בשם amitjobs, משתמש מערכת ייעודי ותיקיית מצב שנשמרת ב־/var/lib. ה־unit הבא הוא בסיס לשירות foreground שמטפל ב־SIGTERM ומבצע drain. הוא אינו מדווח readiness עסקי, ולכן משתמש ב־Type=exec; מעבר ל־Type=notify דורש להוסיף הודעה אמיתית באפליקציה.
[Unit]
Description=AmitTech durable job service
After=local-fs.target
[Service]
Type=exec
User=amitjobs
Group=amitjobs
ExecStart=/usr/libexec/amitjobs serve /var/lib/amitjobs
StateDirectory=amitjobs
StateDirectoryMode=0700
RuntimeDirectory=amitjobs
RuntimeDirectoryMode=0700
UMask=0077
NoNewPrivileges=yes
CapabilityBoundingSet=
AmbientCapabilities=
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
MemoryMax=128M
TasksMax=32
LimitNOFILE=128
TimeoutStopSec=15s
Restart=on-failure
RestartSec=2s
[Install]
WantedBy=multi-user.target
ה־StateDirectory יוצר אזור שניתן לכתוב אליו עבור השירות גם כאשר מערכת הקבצים הכללית מוגנת לפי מדיניות systemd המתאימה. ה־user וה־group צריכים להיווצר כחלק מן החבילה או באמצעות מנגנון ההפצה שנבחר. נבדוק התקנה על מערכת נקייה כדי לוודא שלא נשענו על משתמש שנוצר ידנית במהלך הפיתוח. ההסרה הרגילה לא תמחק יומן או נתוני משתמש; פעולה נפרדת ומפורשת תטפל במחיקת מצב אם המוצר מציע אותה.
המגבלות הן חלק ממטריצת הבדיקות. אם הוספנו worker שמקים namespace או מפעיל syscall חדש, נבדוק שה־sandbox מאפשר את הפעולה הנדרשת בלי לפתוח יכולות מיותרות. אין להעתיק רשימת hardening ארוכה ולהניח שהשירות עדיין פועל נכון רק משום ש־systemctl start הצליח. נבדוק גם recovery, reload, dump ו־shutdown בתוך אותן מגבלות.
תאימות של binary דינמי כוללת את ה־loader ואת symbol versions של libc ותלויות native אחרות. אפשר לראות דרישות באמצעות readelf ו־objdump, ולהריץ במערכת הוותיקה ביותר שהמוצר מצהיר עליה. בנייה על מערכת חדשה אינו מוכיח שהקובץ ירוץ על מערכת ישנה. יעד musl יכול לשנות את סיפור הקישור, אבל עדיין צריך לבדוק DNS, locale, plugins והתנהגות של ספריות שנקשרו בנפרד.
הוספת target באמצעות rustup מספקת את חלקי Rust עבור היעד, אך אינה מתקינה בהכרח linker, C sysroot או סביבת ריצה. נבנה x86_64 ו־AArch64 בנפרד ונבדוק על יעד אמיתי או אמולציה מתאימה, תוך ציון מגבלותיה. ה־atomic widths, היישור וה־endianness של פורמט חיצוני נשארים חוזים שיש לבדוק, לא תוצאה מובנת מאליה של שימוש ב־Rust.
לגילוי יכולת kernel נעדיף ניסיון API עם flags מבוקרים ופירוש errno לפי החוזה, במקום החלטה רק לפי uname. הפצה יכולה לבצע backport, ומדיניות seccomp יכולה לחסום API שקיים ב־kernel. המימוש החלופי צריך לשמר את הסמנטיקה; אם openat2 עם מגבלות resolution אינו זמין, פתיחה רגילה של אותו path אינה fallback בטוח בלי ניתוח נוסף.
התיעוד על אפשרויות בנייה של Cargo ועל סביבת systemd משלים את תכנון החבילה. מבחן הקבלה הוא התקנה, הפעלה, שדרוג והסרה בסביבות המוצהרות, עם נתונים שנשארים חוקיים בכל מעבר.