From 5bd72446f6ac4fe89ff4b5132ce178dc22d63e0c Mon Sep 17 00:00:00 2001 From: Dieter Plaetinck Date: Sun, 21 Nov 2021 15:26:47 -0500 Subject: [PATCH] WIP: describe concepts first. The readme has a great, concise introduction, but the Usage section jumps pretty hard into "first run" specifics without explaining some needed background information. I feel like there should be some conceptual descriptions before getting into the specifics of the commands to run. Defining some concepts and terms early on means the rest of the docs can be less verbose. This is an initial attempt at doing so, and while doing it, it made sense to move the modus operandi into it. I'm filing this PR as a starting point for a conversation around it, it should not be merged as is. this builds up understanding more logically (but people can still jump ahead if they choose to using the TOC). Looking forward, we should probably split up some stuff into separate pages. E.g: * keep the README lean / headline stuff. * separate page: tutorial / first run * separate page for concepts deep dive * separate howto's (e.g. ignoring files, scripting) * separate page for comparison to other systems --- README.md | 64 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 3c8c3c77..b0eb755a 100644 --- a/README.md +++ b/README.md @@ -45,36 +45,29 @@ Since the system configuration is described as shell scripts, it is trivially ex Simply clone (or [download](https://github.com/CyberShadow/aconfmgr/archive/master.zip)+unzip) the GitHub repository. `aconfmgr` will install dependencies as needed during execution. [An AUR package is also available](https://aur.archlinux.org/packages/aconfmgr-git/). -### First run - -Run `aconfmgr save` to transcribe the system's configuration to the configuration directory. This will create the file `99-unsorted.sh` in the configuration directory, as well as other files describing the system configuration. (The configuration directory will usually be `~/.config/aconfmgr`, or `./config` if running directly from git, or it can be overridden with `-c`.) - -On the first run, `aconfmgr` will likely include some files which you may not want to include in your system configuration. These can be temporary or auto-generated files which are not directly owned by a package. To prevent `aconfmgr` from including these files in the configuration, create e.g. `10-ignores.sh` in the configuration directory, with the lines e.g. `IgnorePath '/path/to/file.ext'` or `IgnorePath '/path/to/dir/*'`. (See [ignoring files](#ignoring-files) for details.) Delete everything from the configuration directory except that file and re-run `aconfmgr save` to regenerate a configuration minding these ignore rules. - -Once `aconfmgr save` finishes, you should review the contents of `99-unsorted.sh`, and sort it into one or more new files (e.g.: `10-base.sh`, `20-drivers.sh`, `30-gui.sh`, `50-misc.sh` ...). The files should have a `.sh` extension, and use `bash` syntax. I suggest adding a comment for each package describing why installing the package was needed, so it is clear when the package is no longer needed and can be removed. - -During this process, you may identify packages or system changes which are no longer needed. Do not sort them into your configuration files - instead, delete the file `99-unsorted.sh`, and run `aconfmgr apply`. This will synchronize the system state against your configuration, thus removing the omitted packages. (You will be given a chance to confirm all changes before they are applied.) - -Note: you don't need to run `aconfmgr` via `sudo`. It will elevate as necessary by invoking `sudo` itself. +### High level overview -### Maintenance +aconfmgr manages 2 states: -The configuration directory should be versioned using a version control system (e.g. Git). Ideally, the file `99-unsorted.sh` should not be versioned - it will only be created when the current configuration does not reflect the current system state, therefore indicating that there are system changes that have not been accounted for. +* The state of the Arch Linux system in which aconfmgr runs (referred to as "the system"). +* The description of the system state (referred to as "the configuration"). -Periodic maintenance consists of running `aconfmgr save`; if this results in uncommitted changes to the configuration directory, then there are unaccounted system changes. The changes should be reviewed, sorted, documented, committed and pushed. +`aconfmgr save` builds/updates the configuration to match the system and `aconfmgr apply` updates the system to match the configuration. +There is also a 3rd state, which is a intermediate state: the "output" directory (see further below). -### Restoring +The configuration is an abstracted version of the system. It aims to be a high level, compact representation: -To restore a system to its earlier state, or to set up a new system, simply make sure the correct configuration is in the configuration directory and run `aconfmgr apply`. You will be able to preview and confirm any actual system changes. +* Any system files/directories part of packages are covered by instructions to install the package (`AddPackage`). +* Any files and directories part of an installed package, but not on the system result in an instruction to remove them (`SetFileProperty deleted y`). +* Any files modified from the packages or files/directories added (not part of a package) are covered with an instruction (`CopyFile`) to add them from the "files" directory, which is part of the configuration. -## Modus operandi +Furthermore, certain paths of the system are ignored and not included in the configuration. These paths can we provided by the user, but aconfmgr also includes defaults, such as '/home' (users typically have a better way to manage home directories), '/mnt' (data typically not critical enough or better managed differently), '/proc' (not real data), 'var/cache' (unimportant cache data) and more. See . (TODO confirm and specify whether this applies to both save and apply). -The `aconfmgr` script has two subcommands: +Note: +* No version information is stored for packages. When an `apply` needs to install a package it may be a newer version than the package that resulted in the `AddPackage` directive. +* The configuration is imperative and cumulative, not declarative. Each "save" run resulting in new configuration, will add a new section to the "99-unsorted.sh" configuration file. For example, a system that at point had package "foo" installed, and then later had it removed, would result in a configuration that contains an `AddPackage foo` directive, followed by `RemovePackage` foo from the next run. In fact, the configuration consists of shell scripts that will be evaluated in order. They may contain simple directories, but also more advanced logic. Users are expected to coalesce calls concerning the same paths, and organize all directives and logic into sensible, minimal configuration into scripts that have filenames starting with numbers lower than 99. That way, `aconfmgr save` can always append the latest configuration differences into "99-unsorted.sh". +* `aconfmgr apply` will actually evaluate all configuration scripts and *compile* a system configuration description in the `output` directory. The difference between that directory's contents, and the system, dictates the actions ultimately taken by `aconfmgr apply`. -- `aconfmgr save` calculates the difference between the current system's configuration and the configuration described by the configuration directory, and writes it back to the configuration directory. -- `aconfmgr apply` applies the difference between the configuration described by the configuration directory and the current system's configuration, installing/removing packages and creating/editing configuration files. - -The configuration directory contains shell scripts, initially generated by the `save` subcommand, and then usually edited by the user. Evaluating these scripts will *compile* a system configuration description in the `output` directory. The difference between that directory's contents, and the actual current system configuration, dictates the actions ultimately taken by `aconfmgr`. `aconfmgr save` will write the difference to the file `99-unsorted.sh` (under the configuration directory) as a series of shell commands which attempt to bring the configuration up to date with the current system. When starting with an empty configuration, this difference will consist of the entire system description. Since the script only appends to that file, it may end up undoing configuration changes done earlier in the scripts (e.g. removing packages from the package list). It is up to the user to refactor the configuration to remove redundancies, document changes, and improve maintainability. @@ -82,18 +75,41 @@ The configuration directory contains shell scripts, initially generated by the ` The contracts of both commands are that they are mutually idempotent: after a successful invocation of either, invoking either command immediately after will be a no-op. -### Packages +### Package handling Background: On Arch Linux, every installed package is installed either explicitly, or as a dependency for another package. Packages can also have mandatory (hard) or optional dependencies. You can view this information using `pacman -Qi ` ("Install Reason", "Depends On", "Optional Deps"). `aconfmgr` only tracks explicitly-installed packages, ignoring their hard dependencies. Therefore: - `aconfmgr save` will only save installed packages that are marked as explicitly installed. -- Installed packages that are neither explicitly installed, nor are hard dependencies of other installed packages, are considered prunable orphans and will be removed. +- Installed packages that are neither explicitly installed, nor are hard dependencies of other installed packages, are considered prunable orphans and will be removed. // TODO so not mutually idempotent then? apply may remove packages after save noticed such packages -> actually no, looks like apply may remove these - see below - Packages that are only optional dependencies of other packages must be listed explicitly, otherwise they will be pruned. - `aconfmgr apply` removes unlisted packages by unpinning them (setting their install reason as "installed as a dependency"), after which it prunes all orphan packages. If the package is still required by another package, it will remain on the system (until it is no longer required); otherwise, it is removed. - Packages that are installed and explicitly listed in the configuration will have their install reason set to "explicitly installed". + +### First run + +Run `aconfmgr save` to populate the first configuration. This will create the file `99-unsorted.sh` in the configuration directory, as well as other files describing the system configuration. (The configuration directory will usually be `~/.config/aconfmgr`, or `./config` if running directly from git, or it can be overridden with `-c`.) + +On the first run, `aconfmgr` will likely include some files which you may not want to include in your system configuration. These can be temporary or auto-generated files which are not directly owned by a package. To prevent `aconfmgr` from including these files in the configuration, create e.g. `10-ignores.sh` in the configuration directory, with the lines e.g. `IgnorePath '/path/to/file.ext'` or `IgnorePath '/path/to/dir/*'`. (See [ignoring files](#ignoring-files) for details.) Delete everything from the configuration directory except that file and re-run `aconfmgr save` to regenerate a configuration minding these ignore rules. + +Once `aconfmgr save` finishes, you should review the contents of `99-unsorted.sh`, and sort it into one or more new files (e.g.: `10-base.sh`, `20-drivers.sh`, `30-gui.sh`, `50-misc.sh` ...). The files should have a `.sh` extension, and use `bash` syntax. I suggest adding a comment for each package describing why installing the package was needed, so it is clear when the package is no longer needed and can be removed. + +During this process, you may identify packages or system changes which are no longer needed. Do not sort them into your configuration files - instead, delete the file `99-unsorted.sh`, and run `aconfmgr apply`. This will synchronize the system state against your configuration, thus removing the omitted packages. (You will be given a chance to confirm all changes before they are applied.) + +Note: you don't need to run `aconfmgr` via `sudo`. It will elevate as necessary by invoking `sudo` itself. + +### Maintenance + +The configuration directory should be versioned using a version control system (e.g. Git). Ideally, the file `99-unsorted.sh` should not be versioned - it will only be created when the current configuration does not reflect the current system state, therefore indicating that there are system changes that have not been accounted for. + +Periodic maintenance consists of running `aconfmgr save`; if this results in uncommitted changes to the configuration directory, then there are unaccounted system changes. The changes should be reviewed, sorted, documented, committed and pushed. Or removed and applied + +### Restoring + +To restore a system to its earlier state, or to set up a new system, simply make sure the correct configuration is in the configuration directory and run `aconfmgr apply`. You will be able to preview and confirm any actual system changes. + ## Advanced Usage ### Configuration syntax