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).
|
||||
@@ -1 +0,0 @@
|
||||
# Imagine something here
|
||||
@@ -1,3 +0,0 @@
|
||||
Why are you looking here?
|
||||
|
||||
What is '%msg%'?
|
||||
@@ -1 +0,0 @@
|
||||
Thats right!
|
||||
@@ -0,0 +1,4 @@
|
||||
MODULES=()
|
||||
BINARIES=()
|
||||
FILES=()
|
||||
HOOKS=(base systemd autodetect microcode modconf kms keyboard keymap sd-vconsole block filesystems fsck)
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
echo "Hello, World!"
|
||||
@@ -0,0 +1,2 @@
|
||||
set number
|
||||
syntax on
|
||||
@@ -1,124 +0,0 @@
|
||||
# from import is ok for importing classes and functions
|
||||
# just remember to not import variables this way
|
||||
|
||||
from decman import Directory, File, Module, UserPackage, prg, sh
|
||||
|
||||
|
||||
class MyModule(Module):
|
||||
def __init__(self):
|
||||
self.pkgs = ["rust"]
|
||||
self.update_rustup = False
|
||||
# Modules have names and versions.
|
||||
# Names must be unique.
|
||||
|
||||
# If you disable a module, all packages, files etc assocated with module are removed.
|
||||
super().__init__(name="Example module", enabled=True, version="1")
|
||||
|
||||
# You can add any methods etc to your modules.
|
||||
def enable_my_custom_feature(self, b: bool):
|
||||
if b:
|
||||
self.pkgs = ["rustup"]
|
||||
self.update_rustup = True
|
||||
|
||||
# This is ran, when the module gets enabled
|
||||
def on_enable(self):
|
||||
# Run arbitary shell code easily with the included sh function.
|
||||
sh("groupadd mygroup")
|
||||
|
||||
# or run a program with arguments.
|
||||
prg(["usermod", "--append", "--groups", "mygroup", "kk"])
|
||||
|
||||
# NOTE! Removing a enabled module from decman.module means that on_disable will not run.
|
||||
# Instead disable the module.
|
||||
def on_disable(self):
|
||||
# You can run commands as any user
|
||||
sh("whoami", user="kk")
|
||||
|
||||
# And override environment variables
|
||||
sh("echo $HI", env_overrides={"HI": "Hello!"})
|
||||
|
||||
# Same options apply to prg as well.
|
||||
|
||||
def after_update(self):
|
||||
# Run code after running decman.
|
||||
if self.update_rustup:
|
||||
prg(["rustup", "update"], user="kk")
|
||||
|
||||
def after_version_change(self):
|
||||
# Modules have version numbers to allow conditionally running code.
|
||||
# You could for example run mkinitcpio only after your config has changed.
|
||||
# Just remember to change the version number.
|
||||
prg(["mkinitcpio", "-P"])
|
||||
|
||||
# Files defined here are the same as outside of modules.
|
||||
# There is however an additional feature:
|
||||
# You may add variables to text files, that will be replaced with the given value.
|
||||
|
||||
def file_variables(self) -> dict[str, str]:
|
||||
return {"%msg%": "Hello, world!"}
|
||||
|
||||
def files(self) -> dict[str, File]:
|
||||
# Variables are substituted in text files automatically.
|
||||
return {
|
||||
"/usr/local/bin/say-hello": File(
|
||||
content="#!/usr/bin/env bash\necho %msg%", permissions=0o755
|
||||
),
|
||||
# Variables are not substituted in binary files.
|
||||
"/usr/local/share/say-hello/image.png": File(
|
||||
source_file="files/i-dont-exist.png", bin_file=True
|
||||
),
|
||||
}
|
||||
|
||||
def directories(self) -> dict[str, Directory]:
|
||||
# Directories are handeled the same way. Variables are substituted in text files.
|
||||
return {
|
||||
"/home/kk/.config/mod-app/": Directory(source_directory="files/app-config", owner="kk")
|
||||
}
|
||||
|
||||
# Packages and systemd units are basically the same with modules as without modules.
|
||||
|
||||
def pacman_packages(self) -> list[str]:
|
||||
# Return pacman packages depending on the usage of this module.
|
||||
return self.pkgs
|
||||
|
||||
def user_packages(self) -> list[UserPackage]:
|
||||
# Note, decman now has a aur package, I recommend using that instead.
|
||||
# Also, this example may be out of date
|
||||
return [
|
||||
UserPackage(
|
||||
pkgname="decman-git",
|
||||
version="0.4.1",
|
||||
provides=["decman"],
|
||||
dependencies=[
|
||||
"python",
|
||||
"python-requests",
|
||||
"devtools",
|
||||
"systemd",
|
||||
"pacman",
|
||||
"git",
|
||||
"less",
|
||||
],
|
||||
make_dependencies=[
|
||||
"python-setuptools",
|
||||
"python-build",
|
||||
"python-installer",
|
||||
"python-wheel",
|
||||
],
|
||||
git_url="https://github.com/kiviktnm/decman-pkgbuild.git",
|
||||
)
|
||||
]
|
||||
|
||||
def aur_packages(self) -> list[str]:
|
||||
return ["protonvpn"]
|
||||
|
||||
def flatpak_packages(self) -> list[str]:
|
||||
return ["org.mozilla.firefox"]
|
||||
|
||||
def flatpak_user_packages(self) -> dict[str, list[str]]:
|
||||
return {"username": ["io.github.kolunmi.Bazaar"]}
|
||||
|
||||
def systemd_units(self) -> list[str]:
|
||||
return ["reflector.timer"]
|
||||
|
||||
def systemd_user_units(self) -> dict[str, list[str]]:
|
||||
return {"kk": ["syncthing.service"]}
|
||||
@@ -8,3 +8,13 @@ class Example(decman.Plugin):
|
||||
|
||||
def available(self) -> bool:
|
||||
return os.path.exists("/tmp/example_plugin_available")
|
||||
|
||||
def process_modules(self, store: decman.Store, modules: set[decman.Module]):
|
||||
# Toy example for setting modules as changed
|
||||
for module in modules:
|
||||
module._changed = True
|
||||
|
||||
def apply(
|
||||
self, store: decman.Store, dry_run: bool = False, params: list[str] | None = None
|
||||
) -> bool:
|
||||
return True
|
||||
|
||||
@@ -1,320 +0,0 @@
|
||||
# This example covers all decman features and many useful ways of configuring a system.
|
||||
# Configuration can be as simple or as complex as is needed.
|
||||
|
||||
import os
|
||||
import socket
|
||||
|
||||
# Note: Do NOT use from imports for global variables
|
||||
# BAD: from decman import packages/modules/etc
|
||||
import decman
|
||||
import decman.config
|
||||
|
||||
# This is fine since the thing being imported is a class and not a global variable.
|
||||
from decman import Directory, File, UserPackage, UserRaisedError
|
||||
|
||||
# Flatpaks are disabled by default. This way no already installed flatpaks will get suddenly deleted.
|
||||
decman.config.enable_flatpak = True
|
||||
|
||||
# Configuring what packages are installed is easy.
|
||||
# Duplicates are OK, so if you have multiple modules that want to ensure a package is installed,
|
||||
# you can add the same package multiple times.
|
||||
decman.packages += ["python", "python", "devtools", "git", "networkmanager"]
|
||||
|
||||
# Decman matches installed packages to those defined in the configuration.
|
||||
# This means that:
|
||||
# - all packages not installed on the system but defined in the source are installed
|
||||
# - all packages installed on the system but not defined in the source are removed
|
||||
# To make decman not care if a package is installed or not, add it to ignored_packages.
|
||||
# Ignored packages can be normal packages or aur packages.
|
||||
decman.ignored_packages += ["rustup", "yay"]
|
||||
|
||||
# Installing AUR packages is easy.
|
||||
decman.aur_packages += ["decman", "protonvpn"]
|
||||
|
||||
# Flatpaks work the same way as all other packages.
|
||||
decman.flatpak_packages += ["dev.qwery.AddWater"]
|
||||
|
||||
# They too can be ignored of course
|
||||
decman.ignored_flatpak_packages += ["org.signal.Signal"]
|
||||
|
||||
# You can also install them to your user installation instead of the system installation
|
||||
# Ensure that previous user installed flatpak declarations aren't overwritten and they are initialized.
|
||||
decman.flatpak_user_packages["kk"] = decman.flatpak_user_packages.get("kk", [])
|
||||
# Now add the package.
|
||||
decman.flatpak_user_packages["kk"].append("dev.zed.Zed")
|
||||
|
||||
# To import GPG keys, set the GNUPGHOME environment variable.
|
||||
# It can easily be done with python as well.
|
||||
os.environ["GNUPGHOME"] = "/home/kk/.gnupg/"
|
||||
# You then must set the user that builds the packages to the owner of the GPG home.
|
||||
decman.config.makepkg_user = "kk"
|
||||
|
||||
# You can also install packages from anywhere, but then you must include some
|
||||
# information about the package. The git_url is the url to the PKGBUILD,
|
||||
#
|
||||
# Note, decman now has a aur package, I recommend using that instead.
|
||||
# Also, this example may be out of date
|
||||
decman.user_packages.append(
|
||||
UserPackage(
|
||||
pkgname="decman-git",
|
||||
version="0.4.1",
|
||||
provides=["decman"],
|
||||
dependencies=[
|
||||
"python",
|
||||
"python-requests",
|
||||
"devtools",
|
||||
"pacman",
|
||||
"systemd",
|
||||
"git",
|
||||
"less",
|
||||
],
|
||||
make_dependencies=[
|
||||
"python-setuptools",
|
||||
"python-build",
|
||||
"python-installer",
|
||||
"python-wheel",
|
||||
],
|
||||
git_url="https://github.com/kiviktnm/decman-pkgbuild.git",
|
||||
)
|
||||
)
|
||||
|
||||
# Managing only packages with decman is not that interesting.
|
||||
# Decman also has really powerful ways of managing config files, scripts etc.
|
||||
|
||||
# IMPORTANT: Decman will remove files that were created by decman, but are no longer in the decman source.
|
||||
# Keep your files in version control to avoid losing important files accidentally.
|
||||
|
||||
# Define file content inline.
|
||||
# Default text file encoding is utf-8 but it can be changed.
|
||||
decman.files["/etc/vconsole.conf"] = File(content="KEYMAP=us", encoding="utf-8")
|
||||
|
||||
# Include file content from another file, set the file owner and permissions.
|
||||
# The source_file is relative to the directory where the main decman source.py is located.
|
||||
# By default, the file group is set to the group of the owner, but it can be overridden with the group argument.
|
||||
decman.files["/home/kk/.bin/user-script.sh"] = File(
|
||||
source_file="files/user-script.sh", owner="kk", permissions=0o744
|
||||
)
|
||||
|
||||
# Non-text files such as images can also be managed.
|
||||
decman.files["/home/kk/.background.png"] = File(
|
||||
source_file="files/i-dont-actually-exist.png", bin_file=True, owner="kk"
|
||||
)
|
||||
|
||||
# If you need to install multiple files at once, use directories.
|
||||
# All files from the source directory will be copied recursively to the target.
|
||||
decman.directories["/home/kk/.config/app/"] = Directory(
|
||||
source_directory="files/app-config", owner="kk"
|
||||
)
|
||||
|
||||
# Decman has built in support for managing systemd units as well.
|
||||
# Decman will enable services declared here, and disable services removed from here.
|
||||
# If you don't want decman to manage a service, don't add it here. It will ignore all units that
|
||||
# weren't enabled here.
|
||||
decman.enabled_systemd_units += ["NetworkManager.service"]
|
||||
|
||||
# You can manage units for users as well.
|
||||
|
||||
# Ensure that previous user unit declarations aren't overwritten and they are initialized.
|
||||
decman.enabled_systemd_user_units["kk"] = decman.enabled_systemd_user_units.get("kk", [])
|
||||
# Add user unit.
|
||||
decman.enabled_systemd_user_units["kk"].append("syncthing.service")
|
||||
|
||||
# Most powerful feature of decman are modules.
|
||||
# In this file you see how to include your module, but to really see what modules are capable of
|
||||
# look at the MyModule class.
|
||||
from my_module import MyModule
|
||||
|
||||
my_own_mod = MyModule()
|
||||
|
||||
# You have full access to python, which makes your configuration very dynamic.
|
||||
# For example: do something if the computers hostname is arch-1
|
||||
if socket.gethostname() == "arch-1":
|
||||
# Modules make dynamic configuration easy.
|
||||
# This executes code defined in MyModule which can affect for example what packages are
|
||||
# installed as a part of this module.
|
||||
my_own_mod.enable_my_custom_feature(True)
|
||||
else:
|
||||
# If you want to abort running decman from your config because something is wrong, raise a UserRaisedError
|
||||
raise UserRaisedError("Unknown hostname!")
|
||||
|
||||
decman.modules += [my_own_mod]
|
||||
|
||||
# Configuring the behavior of decman is also done here.
|
||||
# These are the default values.
|
||||
|
||||
# Note: you probably don't want to change these 2 settings and instead you'll want to to use the --debug CLI option.
|
||||
# Show debug output
|
||||
decman.config.debug_output = False
|
||||
# Suppress output of some commands that you probably don't want to see.
|
||||
decman.config.suppress_command_output = True
|
||||
|
||||
# Make output less verbose. Summaries are still printed.
|
||||
decman.config.quiet_output = False
|
||||
|
||||
# Decman captures pacman command output, and any line (and adjacent lines) that contains any of
|
||||
# the following keywords (case-insensetive) will be printed after the pacman command finishes.
|
||||
#
|
||||
# REMEMBER: You should still generally pay attention to pacman output
|
||||
# since these keywords may not catch all cases.
|
||||
decman.config.pacman_output_keywords = [
|
||||
"pacsave",
|
||||
"pacnew",
|
||||
# Additional keywords can be:
|
||||
# "warning",
|
||||
# "error",
|
||||
# "note",
|
||||
# They might cause too many highlights however.
|
||||
]
|
||||
# If you don't want to print lines that contain keywords, set this to False
|
||||
decman.config.print_pacman_output_highlights = True
|
||||
|
||||
# The user which builds aur and user packages.
|
||||
# decman.config.makepkg_user = "nobody" # This was set in a previous example. Let's not override it.
|
||||
|
||||
# The build directory decman uses for creating a chroot etc.
|
||||
decman.config.build_dir = "/tmp/decman/build"
|
||||
|
||||
# Built packages are stored here.
|
||||
decman.config.pkg_cache_dir = "/var/cache/decman"
|
||||
|
||||
# Timeout in seconds for fetching aur package details.
|
||||
decman.config.aur_rpc_timeout = 30
|
||||
|
||||
# Enable installing and upgrading foreign packages.
|
||||
decman.config.enable_fpm = True
|
||||
|
||||
# Number of package files per package kept in the cache
|
||||
# All built AUR packages and user packages are stored in cache.
|
||||
decman.config.number_of_packages_stored_in_cache = 3
|
||||
|
||||
|
||||
# Changing the default commands decman uses for things is a bit more complex.
|
||||
# Create a child class of the decman.config.Commands class and override methods.
|
||||
# These are the defaults.
|
||||
class MyCommands(decman.config.Commands):
|
||||
def list_pkgs(self) -> list[str]:
|
||||
return ["pacman", "-Qeq", "--color=never"]
|
||||
|
||||
def list_foreign_pkgs_versioned(self) -> list[str]:
|
||||
return ["pacman", "-Qm", "--color=never"]
|
||||
|
||||
# --color=always is used in many commands since --color=auto results in no color.
|
||||
# It seems a sensible default for me, since decman already uses color and it can't be disabled.
|
||||
|
||||
def install_pkgs(self, pkgs: list[str]) -> list[str]:
|
||||
return ["pacman", "-S", "--color=always", "--needed"] + pkgs
|
||||
|
||||
def install_files(self, pkg_files: list[str]) -> list[str]:
|
||||
return ["pacman", "-U", "--color=always", "--asdeps"] + pkg_files
|
||||
|
||||
def set_as_explicitly_installed(self, pkgs: list[str]) -> list[str]:
|
||||
return ["pacman", "-D", "--asexplicit"] + pkgs
|
||||
|
||||
def install_deps(self, deps: list[str]) -> list[str]:
|
||||
return ["pacman", "-S", "--color=always", "--needed", "--asdeps"] + deps
|
||||
|
||||
def is_installable(self, pkg: str) -> list[str]:
|
||||
return ["pacman", "-Sddp", pkg]
|
||||
|
||||
def upgrade(self) -> list[str]:
|
||||
return ["pacman", "-Syu", "--color=always"]
|
||||
|
||||
def remove(self, pkgs: list[str]) -> list[str]:
|
||||
return ["pacman", "-Rs", "--color=always"] + pkgs
|
||||
|
||||
def enable_units(self, units: list[str]) -> list[str]:
|
||||
return ["systemctl", "enable"] + units
|
||||
|
||||
def disable_units(self, units: list[str]) -> list[str]:
|
||||
return ["systemctl", "disable"] + units
|
||||
|
||||
def enable_user_units(self, units: list[str], user: str) -> list[str]:
|
||||
return ["systemctl", "--user", "-M", f"{user}@", "enable"] + units
|
||||
|
||||
def disable_user_units(self, units: list[str], user: str) -> list[str]:
|
||||
return ["systemctl", "--user", "-M", f"{user}@", "disable"] + units
|
||||
|
||||
def compare_versions(self, installed_version: str, new_version: str) -> list[str]:
|
||||
return ["vercmp", installed_version, new_version]
|
||||
|
||||
def git_clone(self, repo: str, dest: str) -> list[str]:
|
||||
return ["git", "clone", repo, dest]
|
||||
|
||||
def git_diff(self, from_commit: str) -> list[str]:
|
||||
return ["git", "diff", from_commit]
|
||||
|
||||
def git_get_commit_id(self) -> list[str]:
|
||||
return ["git", "rev-parse", "HEAD"]
|
||||
|
||||
def git_log_commit_ids(self) -> list[str]:
|
||||
return ["git", "log", "--format=format:%H"]
|
||||
|
||||
def review_file(self, file: str) -> list[str]:
|
||||
return ["less", file]
|
||||
|
||||
def make_chroot(self, chroot_dir: str, with_pkgs: list[str]) -> list[str]:
|
||||
return ["mkarchroot", chroot_dir] + with_pkgs
|
||||
|
||||
def install_chroot_packages(self, chroot_dir: str, packages: list[str]):
|
||||
return [
|
||||
"arch-nspawn",
|
||||
chroot_dir,
|
||||
"pacman",
|
||||
"-S",
|
||||
"--needed",
|
||||
"--noconfirm",
|
||||
] + packages
|
||||
|
||||
def resolve_real_name(self, chroot_dir: str, pkg: str) -> list[str]:
|
||||
return [
|
||||
"arch-nspawn",
|
||||
chroot_dir,
|
||||
"pacman",
|
||||
"-Sddp",
|
||||
"--print-format=%n",
|
||||
pkg,
|
||||
]
|
||||
|
||||
def remove_chroot_packages(self, chroot_dir: str, packages: list[str]):
|
||||
return ["arch-nspawn", chroot_dir, "pacman", "-Rsu", "--noconfirm"] + packages
|
||||
|
||||
def make_chroot_pkg(
|
||||
self, chroot_wd_dir: str, user: str, pkgfiles_to_install: list[str]
|
||||
) -> list[str]:
|
||||
makechrootpkg_cmd = ["makechrootpkg", "-c", "-r", chroot_wd_dir, "-U", user]
|
||||
|
||||
for pkgfile in pkgfiles_to_install:
|
||||
makechrootpkg_cmd += ["-I", pkgfile]
|
||||
|
||||
return makechrootpkg_cmd
|
||||
|
||||
|
||||
# To apply your overrides, set the commands variable.
|
||||
decman.config.commands = MyCommands()
|
||||
|
||||
# Alternative to the built in AUR support:
|
||||
# If you don't want to use the built in AUR helper, you can use some pacman wrapper that can run as root, such as pikaur.
|
||||
# To do this, override commands and disable fpm.
|
||||
|
||||
|
||||
class PikaurWrapperCommands(decman.config.Commands):
|
||||
def list_pkgs(self) -> list[str]:
|
||||
return ["pikaur", "-Qeq"]
|
||||
|
||||
def install_pkgs(self, pkgs: list[str]) -> list[str]:
|
||||
return ["pikaur", "-S"] + pkgs
|
||||
|
||||
def upgrade(self) -> list[str]:
|
||||
return ["pikaur", "-Syu"]
|
||||
|
||||
def remove(self, pkgs: list[str]) -> list[str]:
|
||||
return ["pikaur", "-Rs"] + pkgs
|
||||
|
||||
# it doesn't matter if all pacman commands aren't overridden since they wont be used when fpm is disabled.
|
||||
|
||||
|
||||
# decman.config.enable_fpm = False
|
||||
# decman.config.commands = PikaurWrapperCommands()
|
||||
|
||||
# Then simply add all AUR packages to decman.packages
|
||||
# decman.packages += ["pikaur"]
|
||||
Reference in New Issue
Block a user