تا حالا شده سیستم تون رو به روز رسانی کرده باشید و بعد از ریبوت، دیگه قادر به لاگین کردن نباشین؟
يا شاید از یه توزیعی در طی سالیانِ سال استفاده میکردید و بر اثر حادثه ای دلخراش، توزیع تون رو به همراه تمام کانفیگ های سیستم، از دست داده باشید.
همه میدونیم که این مشکل منحصر به توزیع های مختلف گنو/لینوکسی نیست وبا شدتی کمتر/بیشتر در ویندوز یا او.اس.ایکس هم دیده میشه.
اما ریشه مشکلات در کجاست؟ تا حالا بهش فکر کردین؟!
برگردیم به سال 2003. جایی که اولین جرقه های خلق توزیع جدیدی که بتونه بر مشکلات بالا فائق بیاد به ذهن خلاق آقای Eelco Dolstra رسید.
برای طی طریق لازمه کمی با تاریخچه و ایده های زبان های برنامه نویسی آشنا بشیم. خسته که نمیشین؟
ایشون مدت ها با هسکل کار میکردند. اگر نمیدونید زبان هسکل چیه به طور خلاصه بهتون بگم که این زبان از شیوه مرسوم شی گرایی استفاده نمیکنه.
بلکه
رهیافتِ فانکشنال رو در پیش میگیره.
باز ممکنه براتون سوال پیش بیاد که مشکل شی گرایی چی هست که باید از روش فانکشنال یا تابعی استفاده کرد؟
مشکل ریشه ای در
مفهوم state خلاصه میشه.
تکه کد زیر رو در نظر بگیرید:
...
int i = 0;
i++;
// do some other stuffs
int b = i + 5;
...
i در اینجا متغیری هست که مدام دست خوش تغییر میشه و به عبارت بهتر مدام داره وضعیت(state) فعلی خودشو از دست میده. این رفتار که پیش فرضِ اکثر زبان های امروزی هست، تبعاتی در پی داره. از جمله اینکه باعث ایجاد
side effect میشه. side effect به نوبه خودش باعث میشه رفتار سیستم غیرقابل پیش بینی بشه.
معادل های فرنگیش: unproducible system, unpredictable system
سیستم هایی که در آن واحد نمیتونی بهشون نگاه کنی و رفتارشون رو پیش بینی کنی. چون اثرات جانبی، رفتار سیستم رو غیر قابل پیش بینی می کنند.
ایده تمام زبان های فانکشنال هم تا حدودی همینه. (جلوگیری از اثرات جانبی)
برای رسیدن به سیستم قابل پیش بینی، قابل اتکا و مطمئن، نیاز هست که وضعیتِ(state) سیستم دست نخورده باقی بمونه. اگر تکه کد بالا رو در زبان هسکل اجرا کنید به خطای زمان کامپایل برخورد میکنید. دلیل؟
تغییر استیت ممنوع!
این ایده رو گوشه ذهن تون داشته باشید..
حالا بیاید به دنیای سیستم عامل ها.
به دور و بر خودتون نگاه کنید. ابونتو، دبیان، آرچ، و حتی او اس ایکس و ویندوز این خاصیت تغییر استیت رو در خودشون دارند.
مثلا دستور فرضی زیر رو در آرچ در نظر بگیرید:
sudo pacman -Syu
این دستور تمام سیستم رو به روزرسانی میکنه.(استیت قبلی سیستم از بین میره و شما در هر لحظه فقط آخرین تغییرات رو میتونید ببینید) اما اگه سیستم رو ریبوت کنید چطور؟
به احتمال خیلی زیاد مشکلی پیش نخواهد اومد(بنا بر تجربه شخصیم و البته
رعایت یک سری اصول) اما حتی اگر به علم احتمالات تکیه کنیم، احتمال اینکه با یه سیستم غیر قابل بوت مواجه بشید، هم چنان وجود داره.
خب در این حالت معمولا باید یه ایزوی آرچ به صورت بوتیبل کنار دست تون داشته باشید تا بتونید chroot بزنید و سیستم رو مجدد احیا کنید.
می بینید؟
مطمئنا این رفتار رو در توزیع های دیگه هم تجربه کردید.
باز میرسیم به حرف هایی که بالاتر زدم:
unproducible system, unpredictable system..
سوال؟
آیا میتونم به آخرین حالت مطمئن و بدون مشکل سیستمم برگردم؟ هر چند ابزارهایی نظیر
downgrader بوجود اومدن که این مشکل رو تا حدی برطرف کنند، اما به صورت ریشه ای نمیتونن مشکل رو حل کنند.
یه مشکل دیگه که توزیع های موجود دارند این هست که تنظیمات سیستم به صورت کاملا پخش شده در زیر شاخه etc/ قرار داره.
مثلا تنظیمات tor, iptables, i3blocks , ...
فرض کنید دوست تون سیستم شما رو می بینه و ازتون درخواست میکنه که سیستمی مشابه سیستم شما داشته باشه.با تمام ملحقات و فایل های کانفیگ و ...
آیا این کار در توزیع های معمول، شدنیه؟ اگر جواب مثبت هست روال کار چطوریه؟
باز هم از آرچ مثال میزنم:
در این توزیع ابزاری وجود داره به نام
archiso. بوسیله این ابزار میتونید بسته ها، کانفیگ ها و فایل های موردعلاقه خودتون رو به صورت فایل iso. در بیارید و اونو با بقیه به اشتراک بذارم. کاری که قبلا من انجام دادم و
aseman os رو ساختم.
از روال کند و پر از سعی و خطای این روش که بگذریم، شما در نهایت یک فایل ایزو تولید کردید با کانفیگ A.
اما اگر کسی نیاز به سیستمی با کانفیگ B داشته باشه چطور؟
دوباره باید شروع کنید به کاستوم کردن توزیع تون از صفر و تولید مجدد خروجی، سعی/خطا، ساخت ایزو و انتشار اون.
روال بسیار کسل کننده و زمان بر.
این مشکلات باعث شدند آقای DOLSTRA تصمیم بگیره
یک بار برای همیشه این مشکلات رو حل کنه.
ایده این بود که
FHS رو باید طوری سازمان دهی کنم که بسته ها به هنگام آپگرید/حذف با هم دیگه تداخلی نداشته باشند. در واقع ایشون متوجه شده بودند که FHS شبیه همون متغیر i در زبان های شی گرا عمل میکنه. تغییر دهنده وضعیت(state)!
حالا چطوری؟
فرض کنید برای jcal بسته ای نوشتین و میخواین در توزیع nixos نصبش کنید:
{ stdenv, fetchFromGitHub, autoreconfHook
, readline
}:
stdenv.mkDerivation rec {
name = "jcal";
version = "0.4.1";
src = fetchFromGitHub {
owner = "fzerorubigd";
repo = "jcal";
rev = "v${version}";
sha256 = "0m3g3rf0ycv2dsfn9y2472fa3r0yla8pfqk6gq00nrscsc3pp4zf";
};
nativeBuildInputs = [ autoreconfHook ];
buildInputs = [ readline ];
preAutoreconf = "cd sources/";
meta = with stdenv.lib; {
description = "Jalali calendar is a small and portable free software library to manipulate date and time in Jalali calendar system.";
homepage = http://nongnu.org/jcal/;
license = licenses.gpl3;
maintainers = [ maintainers.linarcx ];
platforms = platforms.all;
};
}
تعجب نکنید. شما با زبان nix روبرو شدید(در nixos کل سیستم اعم از بسته ها و کانفیگ ها رو میشه با این زبان بیلد کرد.)
اگر این بسته رو به توزیع nixos بدین و بگین اینو نصب کن واسم، nixos میاد و به تمام ورودی های فایل (دیپندنسی ها، متغیرها)نگاه میکنه و درنهایت یک هش تولید میکنه و اون رو در مسیر nix/store/ نصب میکنه:
/nix/store/dpmvp969yhdq...-subversion-1.1.3/bin/jcal
این کار چندین مزیت داره:
1. از تداخل بین اجزای نرم افزارها با هم دیگه جلوگیری میکنه.
2. به شما این امکان رو میده به نسخه های قدیمی تر بسته برگردین(در nixos چیزی از بین نمیره! بسته های جدید نصب میشن ولی هیچ تغییری در تنظیمات بسته های قدیمی نمیدن-ایده ای که از هسکل گرفته شده. متغیرها نمیتونن در طول حیات برنامه تغییر پیدا کنن)
3. side effect از بین میره و رفتار سیستم قابل پیش بینیه.
قسمت هیجان انگیزتر ماجرا بحث مدیریت تنظیمات سراسری سیستم هست. به جای اینکه etc/ رو پیمایش کنید و دونه دونه تنظیمات تون رو اعمال کنید، nixos از یک مغز متفکر مرکزی استفاده میکنه به نام فایل configuration.nix که در مسیر etc/nixos/ قرار داره.
مثلا میخواید تور رو نصب و کانفیگ کنید؟ کافیه خطوط زیر رو به این فایل اضافه کنید:
services.tor = {
enable = true;
client.enable = true; # Enable privoxy
# extraConfig = builtins.readFile "/home/linarcx/.config/tor/torrc";
};
در پشت صحنه بسته تور نصب و برای شما کانفیگ میشود
میزکار kde plasma با دیسپلی منیجر sddm رو دوست دارید؟
{ config, pkgs, ... }:
{ services.xserver.enable = true;
services.xserver.displayManager.sddm.enable = true;
services.xserver.desktopManager.plasma5.enable = true;
}
تصور کنید کل تنظیمات سراسری سیستم تون رو میتونید با همین یه دونه فایل (یا حداکثر چند فایل مشابه) مدیریت کنید. اون وقت دیگه لازم نیست به دوست تون یه ایزوی 1.5 گیگی هدیه بدین. تنها بادریافت چند فایل و صدور دستور:
nixos-rebuild swith
به سیستمی مشابه سیستم شما دست خواهد یافت.
و دست آخر بریم سراغ هیجان انگیزترین ویژگی این توزیع. بازگشت به حالت های پایدار قبلی سیستم.
nixos-rebuild switch --rollback
هر چقدر که دوست داشته باشید میتونید به عقب برگردین. دوست دارین به کانفیگ اولیه سیستم تون(که ممکنه 5 سال پیش انجام داده باشین) برگردین؟
nix-env --rollback 1