mirror of
https://github.com/kiviktnm/decman.git
synced 2026-09-19 12:08:28 +00:00
213 lines
5.8 KiB
Markdown
213 lines
5.8 KiB
Markdown
# Example
|
|
|
|
This directory contains an example of a minimal decman configuration. This also functions as a tutorial for starting out with decman. I recommend looking at the [docs](/docs/README.md) after this.
|
|
|
|
## Tutorial
|
|
|
|
### Installing decman
|
|
|
|
I will first install git and base-devel. Then I'll clone the PKGBUILD and install decman.
|
|
|
|
```sh
|
|
sudo pacman -S git base-devel
|
|
git clone https://aur.archlinux.org/decman.git
|
|
cd decman/
|
|
makepkg -sic
|
|
```
|
|
|
|
### Starting out
|
|
|
|
I will create a source directory for the system's configuration.
|
|
|
|
```sh
|
|
mkdir ~/source
|
|
cd ~/source
|
|
```
|
|
|
|
Decman will remove all explicitly installed packages not found in the source. Let's find all explicitly installed packages.
|
|
|
|
```sh
|
|
$ pacman -Qeq
|
|
base
|
|
base-devel
|
|
btrfs-progs
|
|
decman
|
|
dosfstools
|
|
efibootmgr
|
|
git
|
|
grub
|
|
linux
|
|
openssh
|
|
qemu-guest-agent
|
|
sudo
|
|
vim
|
|
```
|
|
|
|
First thing to note: `decman` is not a native package. I remember this, but if you don't, you can find only native packages with `pacman -Qeqn` and foreign packages with `pacman -Qeqm`. Since decman is not a native package, the pacman plugin cannot handle it. I'll add decman to AUR packages.
|
|
|
|
Instead of adding all of these packages to `decman.pacman.packages`, I will first create a module for base system packages in `~/source/base.py`.
|
|
|
|
```py
|
|
import decman
|
|
from decman.plugins import pacman, aur
|
|
|
|
class BaseModule(decman.Module):
|
|
|
|
def __init__(self):
|
|
# I'll intend this module to be a singleton (only one instance ever),
|
|
# so I'll inline the module name
|
|
super().__init__("base")
|
|
|
|
@pacman.packages
|
|
def pkgs(self) -> set[str]:
|
|
return {
|
|
"base",
|
|
"btrfs-progs",
|
|
"dosfstools",
|
|
"efibootmgr",
|
|
"grub",
|
|
"linux",
|
|
|
|
# I'll also include git and base-devel here, they are essential to this system
|
|
"git",
|
|
"base-devel",
|
|
}
|
|
|
|
@aur.packages
|
|
def aurpkgs(self) -> set[str]:
|
|
return {"decman"}
|
|
```
|
|
|
|
Then I'll create the main source file with the rest of the packages. I'll import `BaseModule` and add it to `decman.modules`. The main file is `~/source/source.py`.
|
|
|
|
```py
|
|
import decman
|
|
from base import BaseModule
|
|
|
|
decman.pacman.packages |= {"openssh", "qemu-guest-agent", "sudo", "vim"}
|
|
decman.modules += [BaseModule()]
|
|
```
|
|
|
|
This config is already enough to run decman for the first time.
|
|
|
|
```sh
|
|
sudo decman --source /home/arch/source/source.py
|
|
```
|
|
|
|
This will run a system upgrade, but otherwise nothing else happens, since my system already matches the desired configuration.
|
|
|
|
### Extending my config with files and commands
|
|
|
|
Now I'll want to gradually add more stuff to my config. As an example, I'll add my custom `mkinitcpio.conf`. I'll create the file `~/source/files/mkinitcpio.conf` with the desired content. Then I'll add the file to my `BaseModule`. Since I want to run the command `mkinitcpio -P` every time I update my config, I'll add a on change hook as well. I'll update the file `~/source/base.py`.
|
|
|
|
```py
|
|
class BaseModule(decman.Module):
|
|
...
|
|
|
|
def files(self) -> dict[str, decman.File]:
|
|
return {"/etc/mkinitcpio.conf": decman.File(source_file="./files/mkinitcpio.conf")}
|
|
|
|
def on_change(self, store):
|
|
decman.prg(["mkinitcpio", "-P"])
|
|
```
|
|
|
|
I'll also add my vim config to decman. I could now create a Vim module, but since my config is simple, I feel that is not needed. I'll update the main source file `~/source/source.py`.
|
|
|
|
```py
|
|
import decman
|
|
|
|
...
|
|
|
|
decman.files["/home/arch/.vimrc"] = decman.File(source_file="./files/vimrc", owner="arch", permissions=0o600)
|
|
```
|
|
|
|
Then I'll apply my changes. Decman will remember my source, so no need to give it as an argument anymore. I don't want to waste time checking for aur updates, so I'll skip them.
|
|
|
|
```sh
|
|
sudo decman --skip aur
|
|
```
|
|
|
|
### Systemd services and flatpaks
|
|
|
|
I want add a desktop environment. I'll create a module for that in the file `~/source/kde.py`. I'll use SDDM as the login manager. SDDM service needs to be enabled, so I'll use the systemd plugin for that.
|
|
|
|
```py
|
|
import decman
|
|
from decman.plugins import pacman, systemd
|
|
|
|
class KDE(decman.Module):
|
|
|
|
def __init__(self):
|
|
super().__init__("kde")
|
|
|
|
@pacman.packages
|
|
def pkgs(self) -> set[str]:
|
|
return {
|
|
"plasma-desktop",
|
|
"konsole",
|
|
"sddm",
|
|
}
|
|
|
|
@systemd.units
|
|
def units(self) -> set[str]:
|
|
return {"sddm.service"}
|
|
```
|
|
|
|
I'll add the module to enabled modules in `~/source/source.py`.
|
|
|
|
```py
|
|
import decman
|
|
from base import BaseModule
|
|
from kde import KDE
|
|
|
|
...
|
|
|
|
decman.modules += [BaseModule(), KDE()]
|
|
```
|
|
|
|
I'll run decman once again. I'll also start SDDM manually, since decman can't autostart it.
|
|
|
|
```sh
|
|
sudo decman
|
|
sudo systemctl start sddm
|
|
```
|
|
|
|
Lastly I want to install some packages with flatpak. I'll first have to install flatpak to make the plugin available. I'll do it manually since it's quicker.
|
|
|
|
```sh
|
|
sudo pacman -S flatpak
|
|
```
|
|
|
|
Then I'll modify `~/source/source.py`. I must add `flatpak` to execution steps to run the plugin.
|
|
|
|
```py
|
|
import decman
|
|
|
|
...
|
|
|
|
decman.execution_order = [
|
|
"files",
|
|
"pacman",
|
|
"aur",
|
|
"flatpak",
|
|
"systemd",
|
|
]
|
|
|
|
decman.pacman.packages.add("flatpak")
|
|
decman.flatpak.packages |= {"org.mozilla.firefox", "org.signal.Signal"}
|
|
```
|
|
|
|
Then run decman.
|
|
|
|
```sh
|
|
sudo decman
|
|
```
|
|
|
|
### Maintaining a system with decman
|
|
|
|
Decman is intended to replace your upgrade procedures. Instead of running `yay -Syu` for example, you would run `sudo decman`. With `after_update` hooks you can chain other update commands such as `rustup update`. This way you'll only have to remember to run decman. All other update steps are defined in your source.
|
|
|
|
## Plugins
|
|
|
|
It is possible to create your own plugins for decman. However, you probably won't need to do that, as modules are already very capable. This example directory also contains a **very** minimal plugin. To learn more about plugins, look at [the docs](/docs/README.md).
|