আর্চলিনাক্সের কাস্টম প্যাকেজ রিপোজিটরি
Date: []
Tags: [linux], [packaging], [self-hosting]
বিভিন্ন ডিস্ট্রোতে প্যাকেজ ম্যানেজার দিয়ে প্যাকেজ ইনস্টল করার পুরো ব্যাপারটাই অত্যন্ত সোজা। একটা সহজ কমান্ড দিয়েই অফিশিয়াল রিপোজিটরি থেকে রাজ্যের সব প্যাকেজ একজায়গায় পাওয়া যায়। কিন্তু কিছু প্রোগ্রাম অফিশিয়াল রিপোজিটরিতেও থাকে না। সেক্ষেত্রে নিজস্ব একটা প্যাকেজ রিপোজিটরি বানিয়ে নেয়া যায়, ফলে ডিফল্ট প্যাকেজ ম্যানেজার দিয়েই সরাসরি নিজস্ব কাস্টম প্যাকেজ ইনস্টল করে নেয়া যাবে; aur থেকে makepkg দিয়ে ইনস্টল করা, বা make দিয়ে বিল্ড করা, বা কোন র্যান্ডম আর্কাইভ ডাউনলোড করে install.sh জাতীয় স্ক্রিপ্ট চালিয়ে ম্যানুয়ালি ইনস্টল করা, ইত্যাদি হরেক রকম বিকল্প ব্যবস্থা লাগবে না।
অবশ্য এই প্যাকেজ রিপোজিটরিগুলোর গঠন আর কনফিগারেশন দেখলে মনে হয়, প্যাকেজ ইনস্টল করা যত সোজা, রিপোজিটরি তৈরি করা হয়ত ততটাই কঠিন। কিন্তু আসলে নিজস্ব প্যাকেজ রিপোজিটরি তৈরি করে ফেলা মোটেই জটিল কোন কাজ না। যেমন, আর্চের জন্য একটা ফর্মাল রিপোজিটরি বানিয়ে ফেলা যায় খুবই সহজ কয়েকটা ধাপেই:
- প্যাকেজ তৈরি
- জিপিজি সাইনিং
- রিপোজিটরি ডেটাবেজ তৈরি
- (সবকিছু অনলাইনে রাখা)
- প্যাকম্যানে রিপোজিটরি যোগ করা
- রিপোজিটরি আপডেট এবং ইনস্টল
ডিরেক্টরি প্রস্তুতি
রিপোজিটরির কাজ করার জন্য একটা ডিরেক্টরি বানাই:
mkdir -p repo-workarea/repo repo-workarea/work
রিপোজিটরির চূড়ান্ত ফাইলপত্র থাকবে repo-workarea/repo
ডিরেক্টরিতে, আর repo-workarea/work
হচ্ছে প্রস্তুতিমূলক কাজকর্মের জন্য অস্থায়ী লোকেশন।
প্যাকেজ তৈরি
কোন প্যাকেজগুলো আমার রিপোজিটরিতে রাখবো সেগুলো সংগ্রহ বা তৈরি করতে হবে। এটা হতে পারে নিজস্ব কোন প্রজেক্ট, অথবা অফিশিয়াল কোন প্যাকেজের প্যাচ, ইউজার রিপোজিটরি থেকে আনা কোন প্যাকেজ ইত্যাদি।
উদাহরণ হিসাবে, firefox-nightly আর protonvpn-cli-ng, এই দুটো প্যাকেজ aur থেকে নিয়ে কাস্টম রেপোতে রাখবো ধরে নিলাম। শুরুতেই এদের ইনস্টলেবল প্যাকেজ তৈরি করতে হবে।
repo-workarea/work
এ গিয়ে প্যাকেজ দুটো aur থেকে ক্লোন করে বিল্ড করি:
cd repo-workarea/work
git clone https://aur.archlinux.org/firefox-nightly.git
git clone https://aur.archlinux.org/protonvpn-cli-ng.git
# build firefox-nightly
cd firefox-nightly
makepkg -frcs --noconfirm
mv *.pkg.tar.zst ../../repo
cd ..
# build protonvpn-cli-ng
cd protonvpn-cli-ng
makepkg -frcs --noconfirm
mv *.pkg.tar.zst ../../repo
cd ..
এই কমান্ডগুলো একাধারে প্যাকেজগুলো বিল্ড করছে এবং *.pkg.tar.zst আর্কাইভগুলো নিজ নিজ সাবডিরেক্টরি থেকে repo-workarea/repo এ সরিয়ে নিয়ে আসছে।
জিপিজি সাইনিং
প্যাকেজ তো হল, এবার রিপোজিটরি থেকে প্যাকেজ ডাউনলোডের ইন্টেগ্রিটি নিশ্চিত করা জন্য একটা জিপিজি কী দরকার, যা দিয়ে প্যাকেজ এবং রিপোজিটরি ডেটাবেজ সাইন করা হবে। নিজস্ব জিপিজি কী তৈরি করা না থাকলে জিপিজি ওয়েব কী ডিরেক্টরির পোস্টের পিজিপি কী জেনারেশন ধাপটা অনুসরন করলেই হবে।
অথবা এই কমান্ড দিয়ে শর্টকাটে কী বানিয়ে নেয়া যায়।
gpg --gen-key
কমান্ডটার শেষে টার্মিনালে A52A 51D0 8ECD D98D 0D72 559D D08C 7426 00CA A880
এ ধরণের একটা স্ট্রিং দেখা যাবে, এটা হচ্ছে এই কী এর ফিঙ্গারপ্রিন্ট। পুরো ফিঙ্গারপ্রিন্টের পরিবর্তে শর্ট ফর্মটা (শেষের আটটা ক্যারেক্টার) মাথায় রাখলেও কাজ হতে পারে: 00CA A880
।
রিপোজিটরি ডেটাবেজ তৈরি
প্যাকেজ আর্কাইভগুলো তো তাদের বিল্ড ডিরেক্টরি থেকে repo-workarea/repo
ফোল্ডারে সরিয়ে এনেছিলাম। এখন তাহলে ওই ফোল্ডারটা লিস্ট করলে দুটোমাত্র ফাইল দেখা যাবে:
cd repo-workarea/repo
ls
# output
firefox-nightly-76.0a1.20200406-1-x86_64.pkg.tar.zst
protonvpn-cli-ng-2.2.2-1-any.pkg.tar.zst
(ভার্সন নম্বর স্বভাবতই মেলার কথা না।)
এবার আগের ধাপে তৈরি হওয়া জিপিজি কী দিয়ে প্যাকেজগুলো সাইন করতে হবে:
gpg_id="0x00CAA880"
for package in $(ls *.pkg.tar.zst); do
gpg --detach-sign --no-armor -u $gpg_id $package
done
এইভাবে gpg কমান্ড চালানোর ফলে প্যাকেজগুলোর পাশে একই ফাইলনেম-অলা .sig সিগনেচার ফাইল জেনারেট হবে।
# ls
firefox-nightly-76.0a1.20200406-1-x86_64.pkg.tar.zst
firefox-nightly-76.0a1.20200406-1-x86_64.pkg.tar.zst.sig
protonvpn-cli-ng-2.2.2-1-any.pkg.tar.zst
protonvpn-cli-ng-2.2.2-1-any.pkg.tar.zst.sig
এখন রিপোজিটরির ডেটাবেজ তৈরির পালা। এজন্য রিপোজিটরির নাম বাছাই করতে হবে। ধরা যাক এই রিপোজিটরির নাম হবে “my-demo-repo”। তাহলে এইভাবে প্যাকেজ আর্কাইভগুলোর তথ্য নিয়ে ডেটাবেজ তৈরি করা যাবে:
gpg_id="0x00CAA880"
repo_name="my-demo-repo"
repo-add -p -s -k $gpg_id ${repo_name}.db.tar.gz *.pkg.tar.zst
একই সাথে জিপিজি পাবলিক কী-টাও ফাইলগুলির পাশে এক্সপোর্ট করি1:
gpg --export --armor $gpg_id > ${repo_name}.pubkey
ব্যাস, রিপোজিটরি তৈরি হয়ে গেছে! এখন /etc/pacman.conf
এ নিচের মত একটা সেকশন যোগ করে দিলেই হল:
[my-demo-repo]
Server = file:///path/to/repo-workarea/repo/
রিপোজিটরি হোস্টিং
রিপোজিটরি তো তৈরি হল, কিন্তু এই লোকাল ডিরেক্টরি থেকে প্যাকম্যান দিয়ে প্যাকেজ ইনস্টল করে খুব একটা উপকার হয় বলে মনে হচ্ছে না। তারচে পুরো ডিরেক্টরিটা অনলাইনে কোথাও আপলোড করলে, সেখান থেকে অন্য যেকোন আর্চলিনাক্স সিস্টেমে ওই প্যাকেজগুলি ইনস্টল করতে পারবো!
উপরের সবগুলি ধাপ ঠিকমত চালাতে পারলে repo
ফোল্ডারটায় ls
করে নিচের মত একটা লিস্ট পাবো:
my-demo-repo.db
my-demo-repo.db.sig
my-demo-repo.db.tar.gz
my-demo-repo.db.tar.gz.sig
my-demo-repo.files
my-demo-repo.files.sig
my-demo-repo.files.tar.gz
my-demo-repo.files.tar.gz.sig
my-demo-repo.pubkey
firefox-nightly-76.0a1.20200406-1-x86_64.pkg.tar.zst
firefox-nightly-76.0a1.20200406-1-x86_64.pkg.tar.zst.sig
protonvpn-cli-ng-2.2.2-1-any.pkg.tar.zst
protonvpn-cli-ng-2.2.2-1-any.pkg.tar.zst.sig
এই সবগুলো ফাইল অনলাইনে কোনো একজায়গায় রেখে দিলেই হল, ব্যাস। তবে অনলাইনে যেকোন জায়গায় আপলোড করলেই হবে না। ফাইলগুলোর রিলেটিভ লিংক অক্ষুন্ন থাকে আর সরাসরি ডাউনলোড হয়, এরকম কোথাও আপলোড করতে হবে। যেমন গুগল ড্রাইভে রেখে লাভ হবে না, কারণ ওখানে প্রতিটা ফাইলের জন্য র্যান্ডম ইউআরএল তৈরি করে দেয়া হয়। নিজস্ব ওয়েবস্পেস থাকলে সেখানে কোনো একটা পাবলিক ফোল্ডারে রাখা সবচে ভালো হয়। তাছাড়া উপায় না থাকলে গিটহাব বা বিনট্রে এর মত কোন সার্ভিসেও রাখা যায়।
উদাহরণ হিসাবে পুরো রিপোজিটরিটা এখানে আপলোড করে রাখলাম: https://github.com/bdeshi/my-demo-repo/tree/archlinux/archlinux
প্যাকম্যান রেজিস্ট্রেশন
রিপোজিটরি তৈরি তো হল, এখন প্যাকম্যান যাতে এটা খুঁজে পায়, সে ব্যবস্থা করতে হবে। এজন্য দুটো তথ্য দরকার।
- রিপোজিটরিটার রুট ইউআরএল দরকার। গিটহাবে আপলোড করা ফাইলগুলো এই এড্রেসে পাওয়া যাবে: https://raw.githubusercontent.com/bdeshi/my-repo/archlinux/archlinux/ – এটাই হচ্ছে রিপোজিটরির সার্ভার রুট ইউআরএল (এটা কিন্তু গিটহাবের রিপোজিটরির ইউআরএল না)।
- আর রিপোজিটরিটার নাম জানা দরকার। এই রিপোজিটরির নাম বাছাই করেছিলাম “my-demo-repo”
এই দুটো তথ্য মাথায় রেখে /etc/pacman.conf
ফাইলে নিচের মত একটা সেকশন যোগ করি:
[my-demo-repo]
Server = https://raw.githubusercontent.com/bdeshi/my-repo/archlinux/archlinux/
আর মাত্র একটা কাজ বাকি আছে। যে জিপিজি কী দিয়ে রিপোজিটরিটা সাইন করা হচ্ছে সেইটা প্যাকম্যানের কী রিং এ যোগ করতে হবে। যেহেতু বুদ্ধি করে পাবলিক কী টা রিপোজিটরির সাথেই আপলোড করে ফেলেছি (my-demo-repo.pubkey
), তাই এভাবে পাবলিক কী টা যোগ করতে পারবো:
sudo curl "https://raw.githubusercontent.com/bdeshi/my-demo-repo/archlinux/archlinux/my-demo-repo.pubkey" | sudo pacman-key -a -
sudo pacman-key --lsign-key 0x00CAA880
হয়ে গেল। এখন আমাদের এই রিপোজিটরি প্যাকম্যানের ব্যবহারোপযোগী হয়ে গেছে।
sudo pacman -Syu
pacman -S protonvpn-cli-ng
এই প্যাকেজটা এখন aur/makepkg ছাড়া সরাসরি প্যাকম্যান দিয়েই ইনস্টল করা যাচ্ছে! 🎉
রিপোজিটরি আপডেট
রিপোজিটরির প্যাকেজ আপডেট বা নতুন প্যাকেজ যোগ করা কোন জটিল কাজ না। নতুন প্যাকেজ আর্কাইভগুলো ওই repo-workarea/repo
ফোল্ডারে রেখে পুনরায় ঠিক আগের মতই gpg সাইনিং আর repo-add
কমান্ডগুলো চালাতে হবে। পরে সবগুলো ফাইলশুদ্ধ আবার অনলাইনে আগের জায়গায় আপলোড করে দিলেই হল। আপডেটের সময় ডেটাবেজ ফাইলগুলোর .old
ভার্সনও তৈরি হবে। সেগুলোও আপলোড করতে হবে।
কিন্তু প্যাকেজের নতুন ভার্সন বিল্ড করার কাজটা কিভাবে স্বয়ংক্রিয় করা যায়? সেইটা নিয়ে হয়ত পরে কখনো আলাপ করা যাবে।
পরিশিষ্ট
এখানে কেবল x86_64 আর্কিটেকচারের প্যাকেজ তৈরি করা হয়েছে। তাই আর্কিটেকচার অনুযায়ী প্যাকেজ ভাগ করিনি। pacman.conf
এ $repo
ভ্যারিয়েবলটা বর্তমান সিস্টেমের আর্কিটেকচার নির্দেশ করে। এইটা ব্যবহার করে একটাই সেকশন দিয়ে একাধিক আর্কিটেকচারের সাপোর্ট দেয়া যায়। এই $repo
ভ্যারিয়েবলটা কিভাবে কাজ করে? pacman.conf
এ অন্যান্য রিপোজিটরির সার্ভার ইউআরএলে ঢুঁ মেরে দেখলেই বুঝে যাবার কথা।
জিপিজি সাইনিং প্রয়োজন না হলে, pacman.conf
–এ Server =
লাইনের পরে নতুন একটা লাইনে SigLevel = Optional
লিখে দেয়া যায়। তবে সাইন করতে সমস্যা কী?
আর এটা বলাই বাহুল্য প্রায়, তবে জিপিজি সাইন করার পরে জিপিজি প্রাইভেট কী টা যদি হারিয়ে যায় তাহলে কিন্তু সমস্যা।
এটা রিপোজিটরি তৈরির আবশ্যক ধাপ নয়। পাবলিক কী টা সহজে যাতে ইমপোর্ট করা হয়, সেজন্য রিপোজিটরির সাথেই রাখা হচ্ছে। অন্য কোন ভাবে কী টা প্যাকম্যানে ইমপোর্ট করতে পারলেই চলে। ↩