{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Package management"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Outline\n",
    "\n",
    "- Discuss software installation workflow.\n",
    "- Debian and Ubuntu packages.\n",
    "- Advanced Package Tool  (APT) for package installation, removal, search, and query.\n",
    "- Debian package tool (dpkg) for package installation, removal, and query.\n",
    "- Redhat packages.\n",
    "- Yellowdog Updater Modified and Dandified (YUM and DNF) for package installation, removal, search, and query.\n",
    "- Redhat Package Manager (RPM) for package installation, removal, and query\n",
    "\n",
    "***\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The purpose of Linux packages\n",
    "\n",
    "All software in Linux distros come in the form of packages available in online mirrors.\n",
    "Packages are used for the following tasks:\n",
    "\n",
    "- Install software.\n",
    "- Remove software.\n",
    "- Update installed software.\n",
    "- Fix broken or partly removed software files.\n",
    "- Reconfigure installed software.\n",
    "- Verify the integrity of the installed files.\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Package format and tools in various Linux distributions\n",
    "\n",
    "- Debian and Ubuntu: *deb*, *apt*\n",
    "- Redhat: *rpm*, *dnf*\n",
    "- Arch and Monjaro: *packman*\n",
    "- Gentoo: *portage (emerge)*\n",
    "\n",
    "Modern tools, including *snap* and *flatpack*:\n",
    "\n",
    "- Universal software packaging (Ubuntu, Fedora, Monjaro).\n",
    "- Sandboxing.\n",
    "- All dependencies are included in the sandboxes.\n",
    "- Limited use: works for specific application installations.\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "### Linux package management\n",
    "\n",
    "\n",
    "```{figure} img/packagemanagers.png\n",
    "---\n",
    "height: 600px\n",
    "name: Debian_Redhat_pkg\n",
    "---\n",
    "Debian and Redhat package installation flow\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ubuntu (Debian) packages\n",
    "\n",
    "Ubuntu OS components and most of the GNU software are available in form of packages.\n",
    "A package file contains:\n",
    "\n",
    "- Software\n",
    "- Info (control) file\n",
    "- Scripts (pre/post install/remove)\n",
    "- md5sum file hashes\n",
    "- Naming convention:\n",
    "\n",
    "```\n",
    "(package-name)_(source version)-(package-version)_(architecture).deb\n",
    "```\n",
    "\n",
    "For example:\n",
    "\n",
    "```\n",
    "make_4.4.1-3_amd64.deb\n",
    "```\n",
    "\n",
    "Package name is make. The source version is ```4.4.1``` of GNU Make 4.4.1 series, package version (revision): ```3``` from Debian, architecture: amd64.\n",
    "\n",
    "The official Ubuntu distribution located in the Ubuntu archive, folder <b>main</b> and <b>Restricted</b>. \n",
    "In folder Restricted, there are packages with restricted vendor licensing, for example, nvidia-driver-595.\n",
    "\n",
    "<b>Universe</b> Is free software available from the network, but not officialy maintained by Ubuntu development team. For example, a2ps (\"Anything to PS\"), xemacs21. No guarantee of security fixes and support.\n",
    "\n",
    "<b>Multiverse</b> Packages in the archive have some onerous license condition restricting use or redistribution of the software. For example, dvd-slideshow.\n",
    "\n",
    "Developers may offer their own package repositories, called package personal archives (<b>PPA</b>).\n",
    "\n",
    "You can run command ```apt-cache show``` on a package on Ubuntu system to see what folder the package belongs to:\n",
    "\n",
    "**Debian system APT folders**\n",
    "\n",
    "- main\n",
    "- contrib\n",
    "- non-free\n",
    "- non-free-firmware\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Deploy kvm3 VM (Exercise)\n",
    "\n",
    "Clone kvm1 into kvm3:\n",
    "```bash\n",
    "virsh shutdown kvm1\n",
    "virt-clone -o kvm1 -n kvm3 -f /home/hostadm/KVM/kvm3.qcow2\n",
    "```\n",
    "\n",
    "Start kvm3 VM and login to its console via virsh:\n",
    "```bash\n",
    "virsh start kvm3\n",
    "virsh console kvm3\n",
    "```\n",
    "\n",
    "Fix the hostname by editing file `/etc/hostname` with `nano` editor:\n",
    "```bash\n",
    "sudo -s\n",
    "nano /etc/hostname\n",
    "```\n",
    "change kvm1 for kvm3.\n",
    "\n",
    "Run script \n",
    "```bash\n",
    "vm_id_reset.sh\n",
    "```\n",
    "Reboot the VM:\n",
    "```bash\n",
    "reboot\n",
    "```\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Installing Ubuntu packages with APT (Exercises)\n",
    "\n",
    "Login to kvm3.\n",
    "\n",
    "Try executing command make, which doesn't exist on the VM yet:\n",
    "```bash\n",
    "make\n",
    "```\n",
    "The system error comes:  <I>The program 'make' is currently not installed. </I></br>\n",
    "\n",
    "You can install it by typing: ```sudo apt install``` make\n",
    "Install recommended package make by running ```apt install```:\n",
    "```bash\n",
    "apt install make\n",
    "```\n",
    "You should be able to run command make now.\n",
    "\n",
    "Simulate package installation by using option -s:\n",
    "```bash\n",
    "apt install -s netpbm\n",
    "```\n",
    "Notice the prerequisite library package that would get installed, libnetpbm10\n",
    "Download the package without installation:\n",
    "```bash\n",
    "apt install -d netpbm\n",
    "```\n",
    "Notice the deb files with the packages in the apt cache directory:\n",
    "```bash\n",
    "ls -l /var/cache/apt/archives\n",
    "```\n",
    "Another way to download a package and get it in the current working directory:\n",
    "```bash\n",
    "apt download netpbm\n",
    "```\n",
    "Install the package:\n",
    "```bash\n",
    "apt install netpbm\n",
    "```\n",
    "Updating all the installed packages\n",
    "```bash\n",
    "apt update\n",
    "apt upgrade\n",
    "```\n",
    "The APT repository and software folders are defined in file\n",
    "```/etc/apt/sources.list``` and optionally in directory ```/etc/apt/sources.list.d```\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Removing Ubuntu packages with APT (Exercises)\n",
    "\n",
    "Remove package make by running ```apt remove```:\n",
    "\n",
    "```bash\n",
    "apt remove make\n",
    "```\n",
    "Simulate package removal by using option -s:\n",
    "```bash\n",
    "apt remove -s netpbm\n",
    "```\n",
    "Notice package libnetpbm10 won't be removed\n",
    "Simulate package removal with the dependencies:\n",
    "```bash\n",
    "apt autoremove -s netpbm\n",
    "```\n",
    "Notice the both packages would be removed.\n",
    "Remove the package with the dependencies:\n",
    "```bash\n",
    "apt autoremove netpbm\n",
    "```\n",
    "Both netpbm and libnetpbm10 should be gone now.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Search and quiry Ubuntu packages with APT (Exercises)\n",
    "\n",
    "First, update the available package list from the Ubuntu repository:\n",
    "```bash\n",
    "apt update\n",
    "```\n",
    "Search for packages containing string make in their name or description:\n",
    "```bash\n",
    "apt-cache search make\n",
    "```\n",
    "Narrow down the search results for the names containing make:\n",
    "```bash\n",
    "apt-cache search --names-only make\n",
    "```\n",
    "Filter the output for word make\n",
    "```bash\n",
    "apt-cache search --names-only make | grep -w ^make\n",
    "```\n",
    "Get the information about package make:\n",
    "```bash\n",
    "apt-cache show make\n",
    "```\n",
    "List the packages that depend on package make. Forcefully removing ```make``` would break these packages.\n",
    "```bash\n",
    "apt-cache showpkg make\n",
    "```\n",
    "Show the packages a given package depends on:\n",
    "```\n",
    "apt-cache depends make\n",
    "```\n",
    "\n",
    "\n",
    "<hr>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Query package repository folder (Exercises).\n",
    "\n",
    "```apt-cache show``` on a package reveals what folder the package belongs to.\n",
    "It can be **main**, **restricted**, **universe**, and **multiverse**.\n",
    "\n",
    "```bash\n",
    "apt-cache show make | grep Filename\n",
    "```\n",
    "```json\n",
    "Filename: pool/main/m/make-dfsg/make_4.4.1-3_amd64.deb\n",
    "```\n",
    "\n",
    "\n",
    "```bash\n",
    "apt-cache show nvidia-driver-595 | grep Filename\n",
    "```\n",
    "\n",
    "```json\n",
    "Filename: pool/restricted/n/nvidia-graphics-drivers-595/nvidia-driver-595_595.71.05-0ubuntu0.26.04.1_amd64.deb\n",
    "Filename: pool/restricted/n/nvidia-graphics-drivers-595/nvidia-driver-595_595.58.03-0ubuntu2_amd64.deb\n",
    "```\n",
    "\n",
    "```bash\n",
    "apt-cache show a2ps | grep Filename\n",
    "```\n",
    "\n",
    "```json\n",
    "Filename: pool/universe/a/a2ps/a2ps_4.15.7-5_amd64.deb\n",
    "```\n",
    "\n",
    "```bash\n",
    "apt-cache show dvd-slideshow | grep Filename\n",
    "```\n",
    "\n",
    "```json\n",
    "Filename: pool/multiverse/d/dvd-slideshow/dvd-slideshow_0.8.6.1-2build1_all.deb\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### APT security (Exercise)\n",
    "\n",
    "- Packages spooled into /var/cache/apt/archives/ directory before installation.\n",
    "- File ```Packages``` (catalog) contains the MD5, SHA1, SHA256, SHA512 hashes, which are presented via ```apt-cache show``` command.\n",
    "- ```apt install``` verifies the hash of the installable package file with the published one.\n",
    "- The cached ```Packages``` file content is stored in /var/lib/apt/ directory.\n",
    "- The ```Packages``` file is signed with the maintainer's Gnu Privacy Guard (GPG) key.\n",
    "- The maintainers public GPG keys are stored in directory /usr/share/keyrings/\n",
    "\n",
    "On Ubuntu 26.04, the maintainers gpg public keys are stored in directory /usr/share/keyrings/.\n",
    "On older Ubuntu distributions, there were only two GPG keys for any distro stored in directory /etc/apt/trusted.gpg.d/.\n",
    "\n",
    "Let's see what happens to APT when the GPG keys are removed.\n",
    " Remove the gpg public keys:\n",
    "```bash\n",
    "rm  /usr/share/keyrings/*\n",
    "```\n",
    "Run command below and see the error messages about unverifiable signature:\n",
    "```bash\n",
    "apt update\n",
    "```\n",
    "Restore the public keys:\n",
    "```bash\n",
    "apt install  ubuntu-keyring --reinstall\n",
    "```\n",
    "\n",
    "Run ```apt update``` again.\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adding APT repository (Exercise)\n",
    "\n",
    "New apt lists should be either added to file /etc/apt/sources.list or added as new files in directory\n",
    " /etc/apt/sources.list.d\n",
    " \n",
    "For example, lets add the repository for BeeGFS file system.\n",
    "\n",
    "Download file ```beegfs-noble.list``` from the vendor's web site into directory /etc/apt/sources.list.d:\n",
    "```bash\n",
    "cd /etc/apt/sources.list.d\n",
    "wget https://www.beegfs.io/release/beegfs_8.3/dists/beegfs-noble.list\n",
    "```\n",
    "\n",
    "Download the vendor public key, dearmor, and store it in directory /etc/apt/keyrings:\n",
    "```bash\n",
    "cd /tmp\n",
    "wget https://www.beegfs.io/release/beegfs_8.3/gpg/GPG-KEY-beegfs\n",
    "cat GPG-KEY-beegfs  | sudo gpg --dearmor -o /etc/apt/keyrings/GPG-KEY-beegfs.gpg\n",
    "```\n",
    "\n",
    "Reference the key in file ```/etc/apt/sources.list.d/beegfs-noble.list```:\n",
    "\n",
    "<font size=\"3\">\n",
    "    \n",
    "```{admonition} content of beegfs-noble.list file\n",
    "deb **[signed-by=/etc/apt/keyrings/GPG-KEY-beegfs.gpg]** https://www.beegfs.io/release/beegfs_8.3 noble non-free\n",
    "```\n",
    "</font>\n",
    "\n",
    "Update apt caches:\n",
    "```bash\n",
    "apt update\n",
    "```\n",
    "Install a package from the newly added repository:\n",
    "```bash\n",
    "apt install beegfs-tools\n",
    "```\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Install a specific version of a package with APT (Exercise)\n",
    "\n",
    "There maybe several versions of the same package available in a repository.\n",
    "\n",
    "You can see them all with command ```apt-cache show``` followed by the package name.\n",
    "\n",
    "For example, for the kernel package ```linux-image-virtual``` we can see several versions:\n",
    "```bash\n",
    "apt-cache show linux-image-virtual\n",
    "```\n",
    "Let's install version ```7.0.0-22.22``` with command below:\n",
    "```bash\n",
    "apt install linux-image-virtual=7.0.0-22.22\n",
    "```\n",
    "***\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### APT logs\n",
    "\n",
    "The history of all ```apt``` commands is stored in file /var/log/apt/history.log\n",
    "\n",
    "To browse through the ```apt``` history:\n",
    "```bash\n",
    "less /var/log/apt/history.log\n",
    "```\n",
    "\n",
    "To see the last 20 lines of the history:\n",
    "```bash\n",
    "tail -20 /var/log/apt/history.log\n",
    "```\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Quiry Ubuntu packages with dpkg (Exercises)\n",
    "\n",
    "What packages are installed on the system?\n",
    "```bash\n",
    "dpkg -l\n",
    "```\n",
    "Quiry package status with dpkg:\n",
    "```bash\n",
    "dpkg -s make\n",
    "dpkg -s tzdata\n",
    "```\n",
    "List the files contained in the package:\n",
    "```bash\n",
    "dpkg -L tzdata\n",
    "```\n",
    "What package contains a file? For example, command /bin/ls\n",
    "```bash\n",
    "dpkg -S /bin/ls\n",
    "```\n",
    "Reconfigure a package with command dpkg-reconfigure after installation:\n",
    "```bash\n",
    "dpkg-reconfigure tzdata\n",
    "```\n",
    "To see the current package configuration, command debconf-show can be used, for example:\n",
    "```bash\n",
    "debconf-show tzdata\n",
    "```\n",
    "If there is no package dependencies, then a package can be installed with command dpkg. Otherwise, use APT.\n",
    "Install package make:\n",
    "```bash\n",
    "apt download make\n",
    "dpkg -i make_4.4.1-3_amd64.deb\n",
    "```\n",
    "To see the list of the files, contained in the deb package file:\n",
    "```bash\n",
    "dpkg --contents make_4.4.1-3_amd64.deb\n",
    "```\n",
    "\n",
    "Verify the consistency of installed files from a package:\n",
    "```bash\n",
    "dpkg -V make\n",
    "```\n",
    "There is nothing in the output.\n",
    "\n",
    "Let's modify a content of one of the files that comes with the package, ```/usr/include/gnumake.h```:\n",
    "```bash\n",
    "echo '/* last line */' >> /usr/include/gnumake.h\n",
    "```\n",
    "Remove file ```/usr/share/man/man1/make.1.gz```:\n",
    "```bash\n",
    "rm /usr/share/man/man1/make.1.gz\n",
    "```\n",
    "Run the package consistency check and see the tampered and removed files in the list:\n",
    "```bash\n",
    "dpkg -V make\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "Remove package make by using command dpkg:\n",
    "```bash\n",
    "dpkg --purge make\n",
    "```\n",
    "\n",
    "Extract the package content into new directory PKGdir:\n",
    "```bash\n",
    "dpkg -X make_4.4.1-3_amd64.deb PKGdir\n",
    "```\n",
    "\n",
    "Install package ```tree```:\n",
    "```bash\n",
    "apt install tree\n",
    "```\n",
    "\n",
    "Browse the directory tree with command `tree`:\n",
    "```bash\n",
    "tree PKGdir\n",
    "```\n",
    "<hr>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### RedHat packages\n",
    "\n",
    "RPM Package naming convention:\n",
    "```\n",
    "(package-name)-(source version)-(package release).(architecture).rpm\n",
    "```\n",
    "For example,\n",
    "```bash\n",
    "nano-8.1-3.el10.x86_64.rpm\n",
    "```\n",
    "Package name is nano. The source version is 8.1. The package release is 3.el10 (Release 3 for RedHat Enterprise Linux 10). Architecture is x86_64.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Deploy rocky10-1 VM (Exercise)\n",
    "\n",
    "Clone your rocky10 VM into rocky10-1, \n",
    "```bash\n",
    "virt-clone -o rocky10 -n rocky10-1 -f /home/hostadm/KVM/rocky10-1.qcow2\n",
    "```\n",
    "\n",
    "\n",
    "Start rocky10-1 and login to its console via command virsh console: \n",
    "```\n",
    "virsh start rocky10-1\n",
    "virsh console rocky10-1\n",
    "```\n",
    "\n",
    "Fix the hostname in file /etc/hostname for the correct one, ```rocky10-1```\n",
    "\n",
    "Run the following commands to reset the machine-id or rocky10-1 and release its DHCP IP address:\n",
    "```bash\n",
    "sudo dnf install dbus-tools\n",
    "sudo rm -f /etc/machine-id\n",
    "sudo dbus-uuidgen --ensure=/etc/machine-id\n",
    "sudo dbus-uuidgen --ensure\n",
    "sudo ip addr flush dev enp1s0\n",
    "```\n",
    "Reboot the VM:\n",
    "```bash\n",
    "sudo reboot\n",
    "```\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Installing and removing RedHat packages with DNF (Exercises)\n",
    "\n",
    "DNF or Dandified YUM is the next-generation version of the Yellowdog Updater, Modified (yum), a package manager for .rpm-based Linux distributions such as RedHat, Fedora, and Rocky. \n",
    "\n",
    "Clean the dnf cache:\n",
    "```bash\n",
    "dnf clean all\n",
    "```\n",
    "\n",
    "Install package netpbm on it:\n",
    "```bash\n",
    "dnf install netpbm\n",
    "```\n",
    "Reinstall package netpbm:\n",
    "```bash\n",
    "dnf reinstall netpbm\n",
    "```\n",
    "You can download packages without installation, for example:\n",
    "```bash\n",
    "dnf download make\n",
    "ls -l make*\n",
    "```\n",
    "Check available updates for installed packages:\n",
    "```bash\n",
    "dnf check-update\n",
    "```\n",
    "Update package tzdata\n",
    "```bash\n",
    "dnf update tzdata\n",
    "```\n",
    "Updating all the installed packages:\n",
    "```bash\n",
    "dnf update\n",
    "```\n",
    "To remove an installed package:\n",
    "```bash\n",
    "dnf remove netpbm\n",
    "```\n",
    "The same can be accomplished with:\n",
    "```bash\n",
    "dnf erase netpbm\n",
    "```\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Search and quiry RPM packages with DNF (Exercises)\n",
    "\n",
    "List the installed package and the package available for installation\n",
    "```bash\n",
    "dnf list gsl\n",
    "dnf list coreutils\n",
    "```\n",
    "The output shows three columns - the package name and architecture, the package version, and the repository. \n",
    "The latter package showes up as installed (@ in front of the repo), and the former as available for installation.\n",
    "\n",
    "To see just installed packages:\n",
    "```bash\n",
    "dnf list --installed\n",
    "dnf repoquery --installed\n",
    "```\n",
    "\n",
    "To see packages available for installation:\n",
    "```bash\n",
    "dnf list --available\n",
    "dnf repoquery\n",
    "```\n",
    "\n",
    "\n",
    "Search for packages containing string make in their name or description:\n",
    "```bash\n",
    "dnf search make\n",
    "```\n",
    "Get the information about package make:\n",
    "```bash\n",
    "dnf info make\n",
    "```\n",
    "List the packages that package make depends upon:\n",
    "```bash\n",
    "dnf deplist make\n",
    "```\n",
    "\n",
    "Identify the package that contains a specific file, for example ```/bin/ls```:\n",
    "```bash\n",
    "dnf provides /usr/bin/ls\n",
    "```\n",
    "\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DNF repositories (Exercises)\n",
    "\n",
    "Like in Ubuntu, the Redhat packages are sorted in repositories.\n",
    "\n",
    "\n",
    "The dnf repositores are defined in directory ```/etc/yum.repos.d/*.repo```\n",
    "\n",
    "\n",
    "To see the available package repositories:\n",
    "```bash\n",
    "dnf repolist\n",
    "```\n",
    "- ```BaseOS```\n",
    "- ```AppStream```\n",
    "- ```Extras```\n",
    "\n",
    "See disabled repositories:\n",
    "```bash\n",
    "dnf repolist --disabled\n",
    "```\n",
    "Packages can be installed only from enabled repositories.\n",
    "\n",
    "To enable, for example repository ```baseos-source```:\n",
    "```bash\n",
    "dnf config-manager --enable  baseos-source\n",
    "```\n",
    "Check the list of available repos:\n",
    "```bash\n",
    "dnf repolist\n",
    "```\n",
    "\n",
    "To see the packages in repo ```baseos-source```:\n",
    "```bash\n",
    "dnf list --repo baseos-source\n",
    "```\n",
    "\n",
    "Add an external vendor repo, for example, BeeGFS with the .repo file in [URL](https://www.beegfs.io/release/beegfs_8.3/dists/beegfs-rhel10.repo):\n",
    "```bash\n",
    "dnf config-manager --add-repo https://www.beegfs.io/release/beegfs_8.3/dists/beegfs-rhel10.repo\n",
    "```\n",
    "\n",
    "Import the vendor key:\n",
    "```bash\n",
    "rpm --import https://www.beegfs.io/release/beegfs_8.3/gpg/GPG-KEY-beegfs\n",
    "```\n",
    "\n",
    "Check the list of available repos:\n",
    "```bash\n",
    "dnf repolist\n",
    "```\n",
    "\n",
    "See repo file ```beegfs-rhel10.repo``` in directory /etc/yum.repos.d:\n",
    "```bash\n",
    "ls /etc/yum.repos.d\n",
    "```\n",
    "\n",
    "Install a package from the new repo:\n",
    "```bash\n",
    "dnf install beegfs-tools\n",
    "```\n",
    "\n",
    "To disable the repo:\n",
    "```bash\n",
    "dnf config-manager --disable beegfs\n",
    "```\n",
    "\n",
    "Check the list of available repos:\n",
    "```bash\n",
    "dnf repolist\n",
    "```\n",
    "\n",
    "To remove the repo completely from the system:\n",
    "```bash\n",
    "rm /etc/yum.repos.d/beegfs-rhel10.repo\n",
    "```\n",
    "\n",
    "\n",
    "***\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Advanced DNF functionalities\n",
    "\n",
    "History of DNF transactions:\n",
    "```bash\n",
    "dnf history\n",
    "```\n",
    "\n",
    "It is possible to revert dnf installation or upgrade in case the old pkgs are still available in thge repos.\n",
    "For example to revert transaction 10:\n",
    "```bash\n",
    "dnf history undo 10\n",
    "```\n",
    "\n",
    "Roll back to transaction 9:\n",
    "```bash\n",
    "dnf history rollback 9\n",
    "```\n",
    "\n",
    "DNF also provides bundles of packages by ```groups```:\n",
    "\n",
    "```bash\n",
    "dnf group list\n",
    "```\n",
    "\n",
    "The detailed info on dnf can be found in the RedHat docs:\n",
    "\n",
    "[Managing software with the DNF tool](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/pdf/managing_software_with_the_dnf_tool/red_hat_enterprise_linux-9-managing_software_with_the_dnf_tool-en-us.pdf)\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Query RPM packages with rpm (Exercises)\n",
    "What packages are installed on the system?\n",
    "```bash\n",
    "rpm -qa\n",
    "```\n",
    "A friendly readable list comes after sorting the output:\n",
    "```bash\n",
    "rpm -qa | sort | less\n",
    "```\n",
    "\n",
    "If there is no package dependencies or the dependencies have already been resolved, then a package can be simply installed with command rpm from its file. Otherwise, use DNF.\n",
    "Install package make from its rpm file:\n",
    "```bash\n",
    "rpm -ivh make-4.4.1-9.el10.x86_64.rpm\n",
    "```\n",
    "\n",
    "Quiry package status with rpm:\n",
    "```bash\n",
    "rpm -q make\n",
    "```\n",
    "Display information about the installed package:\n",
    "```bash\n",
    "rpm -qi make\n",
    "```\n",
    "List the files contained in the package:\n",
    "```bash\n",
    "rpm -ql make\n",
    "```\n",
    "Which package owns a file? For example, command /bin/ls\n",
    "```bash\n",
    "rpm -qf /bin/ls\n",
    "```\n",
    "RPM dependencies:\n",
    "```bash\n",
    "rpm -qR make\n",
    "```\n",
    "\n",
    "Verify the consistency of installed files from a package:\n",
    "```bash\n",
    "rpm -V make\n",
    "```\n",
    "There is nothing in the output.\n",
    "\n",
    "Let's modify a content of one of the files that comes with the package, /usr/include/gnumake.h:\n",
    "```bash\n",
    "echo '/* last line */' >> /usr/include/gnumake.h\n",
    "```\n",
    "Remove file /usr/share/man/man1/make.1.gz:\n",
    "```bash\n",
    "rm /usr/share/man/man1/make.1.gz\n",
    "```\n",
    "Run the package consistency check and see the tampered and removed files in the list:\n",
    "```bash\n",
    "rpm -V make\n",
    "```\n",
    "\n",
    "Try to remove package make by using command rpm:\n",
    "```bash\n",
    "rpm -e make\n",
    "```\n",
    "\n",
    "\n",
    "Quiry the package file:\n",
    "```bash\n",
    "rpm -qp  make-4.4.1-9.el10.x86_64.rpm\n",
    "rpm -qlp make-4.4.1-9.el10.x86_64.rpm\n",
    "rpm -qip make-4.4.1-9.el10.x86_64.rpm\n",
    "```\n",
    "The second command above shows the files contained in the package file, and the third command displays the info about the package.\n",
    "More info about command rpm can be found in the man pages:\n",
    "```bash\n",
    "man rpm\n",
    "```\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### References on APT and YUM\n",
    "\n",
    "\n",
    "[Package Management table for rpm and deb packages](https://help.ubuntu.com/community/SwitchingToUbuntu/FromLinux/RedHatEnterpriseLinuxAndFedora)\n",
    "\n",
    "[Learn Linux, 101: Debian package management](https://developer.ibm.com/tutorials/l-lpic1-102-4/)\n",
    "\n",
    "[Learn Linux, 101: RPM and YUM package management](https://developer.ibm.com/tutorials/l-lpic1-102-5/)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
