-
Notifications
You must be signed in to change notification settings - Fork 2
feat: implement skillet configuration tool #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
gbagnoli
wants to merge
45
commits into
master
Choose a base branch
from
skillet
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
8b1d017
feat: implement skillet configuration tool with containerized integra…
gbagnoli 1db75db
refactor: address PR review comments
gbagnoli 005d85b
refactor: replace expect with proper error propagation in cli crates
gbagnoli 9cc457d
ci: add skillet quality checks to GitHub workflow
gbagnoli c90f5f8
fix: resolve clippy type complexity warning in test_utils
gbagnoli 42b7e4b
refactor: simplify integration test container setup
gbagnoli a21ff6d
feat: implement service management and systemctl restart
gbagnoli dbefdc6
refactor(skillet): address code review comments
gbagnoli 75a6155
feat(skillet): implement ssh hardening and enforce pedantic clippy lints
gbagnoli 7dc9b5e
test(skillet): update beezelbot integration test recording
gbagnoli 2afcbbd
refactor(skillet): address second round of review comments
gbagnoli db99175
refactor(skillet): address review comments including systemd DBus int…
gbagnoli c20b696
refactor(skillet): optimize file hashing and verify directory types
gbagnoli 3d4d98a
refactor(skillet): address review comments on file hashing and direct…
gbagnoli 92cfb06
refactor(skillet): improve file/directory type verification and handl…
gbagnoli 1f8dea6
refactor(skillet): optimize systemd unit handling and improve test ru…
gbagnoli a1f0701
refactor(skillet): fix Sha256 usage and use constant for group existe…
gbagnoli ea08f62
refactor(skillet): ensure I/O errors are not ignored during hashing a…
gbagnoli f05638c
refactor(skillet): optimize file metadata calls and hashing, and refi…
gbagnoli 227d59f
refactor(skillet): update architectural docs and consolidate director…
gbagnoli 378b4e8
refactor(skillet): improve robustness of file operations and optimize…
gbagnoli 692ecd1
chore(skillet): commit missing files from previous refactor
gbagnoli 317bdac
Apply suggestions from code review
gbagnoli 358c1b3
feat(clamps): add skillet run for clamps host
gbagnoli 41f8f6c
refactor(skillet): ensure deterministic Quadlet generation and optimi…
gbagnoli 89d190c
feat(podman): implement podman_container resource with UID/GID mappin…
gbagnoli 6212713
refactor(skillet): implement host-specific configuration and pihole c…
gbagnoli 2fca049
refactor(skillet): implement pihole as standalone crate and support h…
gbagnoli c3656f1
feat(skillet): implement host-specific config dispatch and pihole con…
gbagnoli 3e61d67
feat(pihole): pass pihole user configuration from host and run as unp…
gbagnoli a1dccff
feat(pihole): update pihole UID/GID to 40000 on clamps
gbagnoli b2e8da3
docs(skillet): add README.md with basic info
gbagnoli 41de451
fix(test): make entrypoint executable and use absolute path for skill…
gbagnoli 0e00421
fix(test): properly copy and chmod skillet binary in container
gbagnoli e0292dc
feat(pihole): implement unprivileged user execution and fix group nam…
gbagnoli 8517216
feat(pihole): update pihole UID to 40000
gbagnoli 2b2113e
Remove unused code
gbagnoli 874a190
feat(cli): add --inspect flag to test subcommands and fix binary copy…
gbagnoli 488e054
feat(skillet): implement secure secret management and quadlet integra…
gbagnoli 0c01069
refactor(core): implement robust resource management and address PR c…
gbagnoli 9a3df95
refactor(core): improve idempotency and address PR review comments
gbagnoli cd61451
refactor(core): refine symlink and metadata handling in files module
gbagnoli 2e22fd6
feat(cli): restore --inspect flag to test subcommands
gbagnoli 493ccca
refactor: address PR review comments for skillet configuration tool
gbagnoli 2de612b
refactor: implement architectural and security improvements from PR r…
gbagnoli File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| variant: fcos | ||
| version: 1.6.0 | ||
| systemd: | ||
| units: | ||
| - name: skillet-apply.service | ||
| enabled: true | ||
| contents: | | ||
| [Unit] | ||
| Description=Apply Skillet configuration | ||
| After=network-online.target | ||
| Wants=network-online.target | ||
|
|
||
| [Service] | ||
| Type=oneshot | ||
| # Use the generic skillet binary and pass the hostname from /etc/hostname | ||
| ExecStart=/usr/bin/skillet apply --host-file /etc/hostname | ||
| RemainAfterExit=yes | ||
|
|
||
| [Install] | ||
| WantedBy=multi-user.target |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| target/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| # Skillet Project Constraints & Structure | ||
|
|
||
| This document defines the architectural mandates and project structure for `skillet`, a Rust-based idempotent host configuration tool. | ||
|
|
||
| ## Core Mandates | ||
|
|
||
| ### 1. Error Handling & Safety | ||
| - **Libraries MUST use `thiserror`** for custom error types. | ||
| - **Libraries MUST NOT use `anyhow`**. `anyhow` is reserved for the CLI binary only. | ||
| - **NEVER use `unwrap()` or `expect()`** in library code. All errors must be propagated and handled. | ||
| - **Prioritize Crates over Shell-out**: Use Rust crates (e.g., `users`, `nix`) for system interactions whenever possible instead of executing shell commands. | ||
|
|
||
| ### 2. Idempotency | ||
| - All resources (files, users, groups, etc.) must be **idempotent**. | ||
| - Before performing an action, check the current state (e.g., compare SHA256 hashes for files, check existence for users). | ||
| - Actions should only be taken if the system state does not match the desired state. | ||
|
|
||
| ### 3. Testing Strategy | ||
| - **Unit Tests**: Place unit tests in a `tests` submodule within each module's directory (e.g., `src/files/tests.rs`). | ||
| - **Separation**: Never put tests in the same `.rs` file as the implementation code. Reference them using `#[cfg(test)] #[path = "MODULE/tests.rs"] mod tests;`. | ||
| - **Abstractions**: Use Traits (e.g., `FileResource`, `SystemResource`) to allow for mocking in higher-level library tests. | ||
|
|
||
| ### 4. Quality Control & Validation | ||
| - **Formatting & Linting**: Always run `cargo fmt` and `cargo clippy` after making changes to ensure code quality and consistency. **Clippy MUST be run with `pedantic` lints enabled (configured in `Cargo.toml`).** | ||
| - **Verification**: Always run both: | ||
| - **Unit Tests**: `cargo test` across the workspace. | ||
| - **Integration Tests**: `skillet test run <hostname>` for affected hosts to verify end-to-end correctness in a containerized environment. | ||
|
|
||
| ## Testing & Recording Philosophy | ||
|
|
||
| Skillet uses a multi-layered testing approach to ensure reliability and idempotency: | ||
|
|
||
| 1. **Trait-based Abstraction**: Core resources (`FileResource`, `SystemResource`) are defined as traits. This allows for easy mocking using `MockFiles` and `MockSystem` in unit tests. | ||
| 2. **The Recorder Wrapper**: A `Recorder<T>` wrapper can be applied to any resource implementing these traits. It intercepts all operations (e.g., `EnsureFile`, `ServiceRestart`), records them into a sequence of `ResourceOp` enums, and then passes the call to the underlying implementation. | ||
| 3. **Containerized Integration Tests**: | ||
| * **Record Mode**: The tool runs against a fresh container, and the `Recorder` saves the sequence of operations to a YAML file (e.g., `integration_tests/recordings/beezelbot.yaml`). | ||
| * **Run Mode**: The tool runs again, and the *actual* sequence of operations is compared against the *recorded* one. Any mismatch (e.g., a missing service restart or an extra file write) causes the test to fail. | ||
| * **Idempotency**: By running the tool twice in the same container, we can verify that the second run produces an empty (or minimal) set of operations, confirming idempotency. | ||
|
|
||
| ## Project Structure | ||
|
|
||
| The project is organized as a Cargo workspace: | ||
|
|
||
| ```text | ||
| skillet/ | ||
| ├── Cargo.toml # Workspace configuration | ||
| ├── AGENTS.md # This file (Project mandates) | ||
| └── crates/ | ||
| ├── core/ # skillet_core: Low-level idempotent primitives | ||
| │ ├── src/ | ||
| │ │ ├── lib.rs | ||
| │ │ ├── files.rs # File management (Traits + Impl) | ||
| │ │ ├── files/ | ||
| │ │ │ └── tests.rs # Unit tests for files | ||
| │ │ ├── system.rs # User/Group management | ||
| │ │ └── system/ | ||
| │ │ └── tests.rs # Unit tests for system | ||
| │ └── tests/ # Integration tests | ||
| ├── hardening/ # skillet_hardening: Configuration logic (modules) | ||
| │ ├── src/ | ||
| │ │ ├── lib.rs # Hardening logic using core primitives | ||
| │ │ └── tests.rs # Unit tests for hardening logic | ||
| │ └── tests/ | ||
| ├── cli/ # skillet: The main binary executable | ||
| │ └── src/ | ||
| │ └── main.rs # CLI entry point (uses anyhow, clap) | ||
| ├── cli-common/ # skillet_cli_common: Shared CLI logic | ||
| └── hosts/ | ||
| └── beezelbot/ # skillet-beezelbot: Host-specific binary for beezelbot | ||
| ``` | ||
|
|
||
| ## Module Design | ||
| - **Modules as Cookbooks**: Each library crate under `crates/` (besides `core`) represents a "module" or "cookbook" (e.g., `skillet_hardening`). | ||
| - **Binary per Host**: The idea is to have one binary per host type that picks up these modules and reuses core primitives. | ||
| - **Core Primitives**: Found in `skillet_core`, providing the building blocks for all modules. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The project structure diagram seems to be outdated and doesn't reflect the actual structure of the workspace. It's missing the
cli-commonandhosts/beezelbotcrates. It would be beneficial to update the diagram to accurately represent all the crates in the workspace for better clarity and maintainability.For example, the structure could be updated to include: