feat: allow exclusion of dotfiles with pillars

The dotfiles provides hardened configuration as well as usability
settings, but it has downsides:

- Even though some programs allowing including extra files, not all of
  them do;
- Experienced users wants their own configuration that can conflict in
  file path;
- Adds a lot of lines to review that is not strictly necessary for Qusal
  to work.

With this change, users can set pillar values to disable specific
components or all components.

For: https://github.com/ben-grande/dotfiles/pull/1
For: https://github.com/ben-grande/qusal/issues/17
Co-authored-by: Ben Grande <ben.grande.b@gmail.com>
This commit is contained in:
seven-beep 2025-03-03 15:50:27 +01:00 committed by Ben Grande
parent 11bc58a4dd
commit 0bae3d94b2
No known key found for this signature in database
GPG Key ID: 00C64E14F51F9E56
15 changed files with 259 additions and 9 deletions

View File

@ -1,7 +1,8 @@
# dotfiles # dotfiles
<!-- <!--
SPDX-FileCopyrightText: 2023 - 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-License-Identifier: CC-BY-SA-4.0
--> -->
@ -13,6 +14,8 @@ Dotfiles.
* [Description](#description) * [Description](#description)
* [Installation](#installation) * [Installation](#installation)
* [Salt](#salt) * [Salt](#salt)
* [Pillar](#pillar)
* [Pillar example](#pillar-example)
* [Script](#script) * [Script](#script)
* [Usage](#usage) * [Usage](#usage)
* [License](#license) * [License](#license)
@ -59,6 +62,52 @@ Install specific files in Dom0:
sudo qubesctl state.apply dotfiles.copy-dom0,dotfiles.copy-sh,dotfiles.copy-vim,dotfiles.copy-x11 sudo qubesctl state.apply dotfiles.copy-dom0,dotfiles.copy-sh,dotfiles.copy-vim,dotfiles.copy-x11
``` ```
#### Pillar
By default, all states are executed when applied. Each component can be be
deactivated by configuring the corresponding pillar data to a non true value.
You will need a top and a state file in your `pillar_roots`. If you followed
[Qusal's installation instructions](https://github.com/ben-grande/qusal/blob/main/docs/INSTALL.md),
it has already configured the setting for you using the value
`/srv/pillar/qusal`. What you can do, is selectively enable or disable
components.
For a complete example of a pillar state and a list of their corresponding
formulas states, please refer to [pillar.sls.example](pillar.sls.example).
##### Pillar example
On the following example, we will selectively disable only the `dom0`
component, therefore, the state `copy-dom0.sls` is not applied to `dom0`:
Create a pillar top to apply to all targets, write it to
`/srv/pillar/qusal/dotfiles.top`:
```yaml
base:
'*':
- qusal.dotfiles
```
Then, create a pillar state do disable only `dom0` states, write it to
`/srv/pillar/qusal/dotfiles.sls`:
```yaml
qusal:
dotfiles:
dom0: false
```
Add the pillar to the highstate:
```sh
sudo qubesctl top.enable qusal.dotfiles pillar=true
```
From now on, when calling the state `copy-dom0.sls`, it won't execute
anything.
### Script ### Script
You can simply deploy all configurations with: You can simply deploy all configurations with:

View File

@ -1,13 +1,29 @@
{# {#
SPDX-FileCopyrightText: 2023 - 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- if salt["pillar.get"]("qusal:dotfiles:all"), default=True) or
salt["pillar.get"]("qusal:dotfiles:dom0") or
salt["pillar.get"]("qusal:dotfiles:git") or
salt["pillar.get"]("qusal:dotfiles:gtk") or
salt["pillar.get"]("qusal:dotfiles:mutt") or
salt["pillar.get"]("qusal:dotfiles:net") or
salt["pillar.get"]("qusal:dotfiles:pgp") or
salt["pillar.get"]("qusal:dotfiles:sh") or
salt["pillar.get"]("qusal:dotfiles:ssh") or
salt["pillar.get"]("qusal:dotfiles:tmux") or
salt["pillar.get"]("qusal:dotfiles:vim") or
salt["pillar.get"]("qusal:dotfiles:x11")
-%}
include: include:
- .copy-dom0 - .copy-dom0
- .copy-git - .copy-git
- .copy-gtk - .copy-gtk
- .copy-mutt
- .copy-net - .copy-net
- .copy-pgp - .copy-pgp
- .copy-sh - .copy-sh
@ -16,6 +32,13 @@ include:
- .copy-vim - .copy-vim
- .copy-x11 - .copy-x11
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif -%}
{# {#
Unfortunately salt.states.file does not keep permissions when using salt-ssh. Unfortunately salt.states.file does not keep permissions when using salt-ssh.
Best option is 'file.managed mode: keep' or 'file.recurse file_mode: keep'. Best option is 'file.managed mode: keep' or 'file.recurse file_mode: keep'.

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 - 2024 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:dom0", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-dom0-home": "{{ slsdotpath }}-copy-dom0-home":
@ -25,3 +29,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- user: root - user: root
- group: root - group: root
- makedirs: True - makedirs: True
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:git", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-git-home": "{{ slsdotpath }}-copy-git-home":
@ -65,3 +69,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- mode: '0755' - mode: '0755'
- recurse: - recurse:
- mode - mode
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:gtk", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-gtk-home": "{{ slsdotpath }}-copy-gtk-home":
@ -23,3 +27,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- dir_mode: '0700' - dir_mode: '0700'
- user: root - user: root
- group: root - group: root
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:mutt", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-mutt-home": "{{ slsdotpath }}-copy-mutt-home":
@ -39,3 +43,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- mode: '0755' - mode: '0755'
- recurse: - recurse:
- mode - mode
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:net", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-net-home": "{{ slsdotpath }}-copy-net-home":
@ -41,3 +45,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- mode: '0755' - mode: '0755'
- recurse: - recurse:
- mode - mode
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:pgp", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-pgp-home": "{{ slsdotpath }}-copy-pgp-home":
@ -27,3 +31,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- group: root - group: root
{% endif -%} {% endif -%}
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:sh", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-sh-home": "{{ slsdotpath }}-copy-sh-home":
@ -43,3 +47,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- dir_mode: '0755' - dir_mode: '0755'
- recurse: - recurse:
- mode - mode
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:ssh", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-ssh-home": "{{ slsdotpath }}-copy-ssh-home":
@ -24,3 +28,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- dir_mode: '0700' - dir_mode: '0700'
- user: root - user: root
- group: root - group: root
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:tmux", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-tmux-home": "{{ slsdotpath }}-copy-tmux-home":
@ -37,3 +41,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- mode: '0755' - mode: '0755'
- recurse: - recurse:
- mode - mode
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:vim", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-vim-home": "{{ slsdotpath }}-copy-vim-home":
@ -23,3 +27,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- dir_mode: '0700' - dir_mode: '0700'
- user: root - user: root
- group: root - group: root
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

View File

@ -1,9 +1,13 @@
{# {#
SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com> SPDX-FileCopyrightText: 2023 - 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-License-Identifier: AGPL-3.0-or-later SPDX-License-Identifier: AGPL-3.0-or-later
#} #}
{%- set qusal_dot = salt["pillar.get"]("qusal:dotfiles:all", default=True) -%}
{%- if salt["pillar.get"]("qusal:dotfiles:x11", default=qusal_dot) -%}
{%- import "dom0/gui-user.jinja" as gui_user -%} {%- import "dom0/gui-user.jinja" as gui_user -%}
"{{ slsdotpath }}-copy-x11-home": "{{ slsdotpath }}-copy-x11-home":
@ -27,3 +31,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later
- group: root - group: root
- keep_symlinks: True - keep_symlinks: True
- force_symlinks: True - force_symlinks: True
{%- else -%}
"{{ sls }}-was-disabled-by-pillar":
test.nop
{%- endif %}

37
pillar.sls.example Normal file
View File

@ -0,0 +1,37 @@
{#
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-FileCopyrightText: 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: CC-BY-SA-4.0
Example of a pillar state structure for https://github.com/ben-grande/dotfiles
For this file to be active:
1. Copy the file to the pillar_roots directory without the '.example' suffix;
2. Reference this state by a pillar highstate.
See the README for detailed instructions.
Each pillar component is optional. Disable a single component by setting them
to 'false'. To selectively enable few components, disable 'all' and enable
each desired component by setting them to 'true'.
Entries example: 'dom0' corresponds to 'copy-dom0.sls'.
#}
qusal:
dotfiles:
all: true
dom0: true
git: true
gtk: true
mutt: true
net: true
pgp: true
sh: true
ssh: true
tmux: true
vim: true
x11: true

20
pillar.top.example Normal file
View File

@ -0,0 +1,20 @@
{#
SPDX-FileCopyrightText: 2024 seven-beep <ebn@entreparentheses.xyz>
SPDX-FileCopyrightText: 2025 Benjamin Grande M. S. <ben.grande.b@gmail.com>
SPDX-License-Identifier: CC-BY-SA-4.0
Example of a pillar top structure for https://github.com/ben-grande/dotfiles
For this file to be active:
1. Copy the file to the pillar_roots directory without the '.example' suffix;
2. Enable the pillar highstate.
See the README for detailed instructions.
#}
base:
'*':
- qusal.dotfiles