mirror of
https://github.com/kiviktnm/decman.git
synced 2026-09-19 12:08:28 +00:00
Add an example for using decman
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user