enable deno formatter
Some checks failed
buildbot/nix-build .#checks.aarch64-darwin.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-minimal-inventory-machine Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-no-breakpoints Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-flash-installer Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-inventory-schema Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-default Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-inventory-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-ts-api Build done.
buildbot/nix-build .#checks.x86_64-linux.package-default Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-minimal-inventory-machine Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test-backup Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.check-for-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-archlinux Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-apk Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-deb Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-rpm Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-age Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-bash Build done.
buildbot/nix-build .#checks.x86_64-linux.renderClanOptions Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-pytest Build done.
buildbot/nix-build .#checks.x86_64-linux.treefmt Build done.
buildbot/nix-build .#checks.x86_64-linux.package-deploy-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-e2fsprogs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-git Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-nix Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-openssh Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-docs Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.12-mypy" Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.12-qemu" Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-rsync Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sops Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sshpass Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-tor Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-zbar Build done.
buildbot/nix-build .#checks.x86_64-linux.container Build done.
buildbot/nix-build .#checks.x86_64-linux.deltachat Build done.
buildbot/nix-build .#checks.x86_64-linux.borgbackup Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-example-valid Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-minimal-inventory-machine Build done.
buildbot/nix-build .#checks.x86_64-linux.module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-editor Build done.
buildbot/nix-build .#checks.x86_64-linux.package-impure-checks Build done.
buildbot/nix-build .#checks.x86_64-linux.package-merge-after-ci Build done.
buildbot/nix-build .#checks.x86_64-linux.package-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.package-moonlight-sunshine-accept Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.package-tea-create-pr Build done.
buildbot/nix-build .#checks.x86_64-linux.matrix-synapse Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotier-members Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-nix-unit-tests Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.package-pending-reviews Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotierone Build done.
buildbot/nix-build .#checks.x86_64-linux.postgresql Build done.
buildbot/nix-build .#checks.x86_64-linux.package-function-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.secrets Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.template-minimal Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-without-core Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-inventory-eval Build done.
buildbot/nix-build .#checks.x86_64-linux.zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.wayland-proxy-virtwl Build done.
buildbot/nix-build .#checks.aarch64-darwin.package-function-schema Build done.
buildbot/nix-build .#checks.aarch64-linux.package-function-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.syncthing Build done.
buildbot/nix-build .#checks.x86_64-linux.module-clan-vars-eval Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-install-test-ubuntu-22-04 Build done.
buildbot/nix-build .#checks.x86_64-linux.test-backups Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-with-core Build done.
buildbot/nix-build .#checks.x86_64-linux.flash Build done.
buildbot/nix-build .#checks.x86_64-linux.test-installation Build done.
buildbot/nix-eval Build done.
checks / checks-impure (pull_request) Successful in 4m43s

This commit is contained in:
Jörg Thalheim 2024-07-08 16:33:11 +02:00
parent e1b7805aef
commit e0f4276f33
54 changed files with 1124 additions and 749 deletions

View File

@ -1,40 +1,64 @@
# Clan core repository
Welcome to the Clan core repository, the heart of the [clan.lol](https://clan.lol/) project! This monorepo is the foundation of Clan, a revolutionary open-source project aimed at restoring fun, freedom, and functionality to computing. Here, you'll find all the essential packages, NixOS modules, CLI tools, and tests needed to contribute to and work with the Clan project. Clan leverages the Nix system to ensure reliability, security, and seamless management of digital environments, putting the power back into the hands of users.
Welcome to the Clan core repository, the heart of the
[clan.lol](https://clan.lol/) project! This monorepo is the foundation of Clan,
a revolutionary open-source project aimed at restoring fun, freedom, and
functionality to computing. Here, you'll find all the essential packages, NixOS
modules, CLI tools, and tests needed to contribute to and work with the Clan
project. Clan leverages the Nix system to ensure reliability, security, and
seamless management of digital environments, putting the power back into the
hands of users.
## Why Clan?
Our mission is simple: to democratize computing by providing tools that empower users, foster innovation, and challenge outdated paradigms. Clan represents our contribution to a future where technology serves humanity, not the other way around. By participating in Clan, you're joining a movement dedicated to creating a secure, user-empowered digital future.
Our mission is simple: to democratize computing by providing tools that empower
users, foster innovation, and challenge outdated paradigms. Clan represents our
contribution to a future where technology serves humanity, not the other way
around. By participating in Clan, you're joining a movement dedicated to
creating a secure, user-empowered digital future.
## Features of Clan
- **Full-Stack System Deployment:** Utilize Clans toolkit alongside Nix's reliability to build and manage systems effortlessly.
- **Full-Stack System Deployment:** Utilize Clans toolkit alongside Nix's
reliability to build and manage systems effortlessly.
- **Overlay Networks:** Secure, private communication channels between devices.
- **Virtual Machine Integration:** Seamless operation of VM applications within the main operating system.
- **Virtual Machine Integration:** Seamless operation of VM applications within
the main operating system.
- **Robust Backup Management:** Long-term, self-hosted data preservation.
- **Intuitive Secret Management:** Simplified encryption and password management processes.
- **Intuitive Secret Management:** Simplified encryption and password management
processes.
## Getting started with Clan
If you're new to Clan and eager to dive in, start with our quickstart guide and explore the core functionalities that Clan offers:
If you're new to Clan and eager to dive in, start with our quickstart guide and
explore the core functionalities that Clan offers:
- **Quickstart Guide**: Check out [getting started](https://docs.clan.lol/#starting-with-a-new-clan-project)<!-- [docs/site/index.md](docs/site/index.md) --> to get up and running with Clan in no time.
- **Quickstart Guide**: Check out
[getting started](https://docs.clan.lol/#starting-with-a-new-clan-project)<!-- [docs/site/index.md](docs/site/index.md) -->
to get up and running with Clan in no time.
### Managing secrets
In the Clan ecosystem, security is paramount. Learn how to handle secrets effectively:
In the Clan ecosystem, security is paramount. Learn how to handle secrets
effectively:
- **Secrets Management**: Securely manage secrets by consulting [secrets](https://docs.clan.lol/getting-started/secrets/)<!-- [secrets.md](docs/site/getting-started/secrets.md) -->.
- **Secrets Management**: Securely manage secrets by consulting
[secrets](https://docs.clan.lol/getting-started/secrets/)<!-- [secrets.md](docs/site/getting-started/secrets.md) -->.
### Contributing to Clan
The Clan project thrives on community contributions. We welcome everyone to contribute and collaborate:
The Clan project thrives on community contributions. We welcome everyone to
contribute and collaborate:
- **Contribution Guidelines**: Make a meaningful impact by following the steps in [contributing](https://docs.clan.lol/contributing/contributing/)<!-- [contributing.md](docs/CONTRIBUTING.md) -->.
- **Contribution Guidelines**: Make a meaningful impact by following the steps
in
[contributing](https://docs.clan.lol/contributing/contributing/)<!-- [contributing.md](docs/CONTRIBUTING.md) -->.
## Join the revolution
Clan is more than a tool; it's a movement towards a better digital future. By contributing to the Clan project, you're part of changing technology for the better, together.
Clan is more than a tool; it's a movement towards a better digital future. By
contributing to the Clan project, you're part of changing technology for the
better, together.
### Community and support
@ -42,4 +66,3 @@ Connect with us and the Clan community for support and discussion:
- [Matrix channel](https://matrix.to/#/#clan:clan.lol) for live discussions.
- IRC bridges (coming soon) for real-time chat support.

View File

@ -1,11 +1,13 @@
---
description = "Statically configure borgbackup with sane defaults."
---
This module implements the `borgbackup` backend and implements sane defaults
for backup management through `borgbackup` for members of the clan.
This module implements the `borgbackup` backend and implements sane defaults for
backup management through `borgbackup` for members of the clan.
Configure target machines where the backups should be sent to through `targets`.
Configure machines that should be backuped either through `includeMachines`
which will exclusively add the included machines to be backuped, or through
`excludeMachines`, which will add every machine except the excluded machine to the backup.
`excludeMachines`, which will add every machine except the excluded machine to
the backup.

View File

@ -2,6 +2,7 @@
description = "Efficient, deduplicating backup program with optional compression and secure encryption."
categories = ["backup"]
---
BorgBackup (short: Borg) gives you:
- Space efficient storage of backups.
@ -10,4 +11,4 @@ BorgBackup (short: Borg) gives you:
- Mountable backups with FUSE.
- Easy installation on multiple platforms: Linux, macOS, BSD, ...
- Free software (BSD license).
- Backed by a large and active open source community.
- Backed by a large and active open source community.

View File

@ -4,14 +4,17 @@ description = "Email-based instant messaging for Desktop."
!!! warning "Under construction"
!!! info
This module will automatically configure an email server on the machine for handling the e-mail messaging seamlessly.
!!! info This module will automatically configure an email server on the machine
for handling the e-mail messaging seamlessly.
## Features
- [x] **Email-based**: Uses any email account as its backend.
- [x] **End-to-End Encryption**: Supports Autocrypt to automatically encrypt messages.
- [x] **No Phone Number Required**: Uses your email address instead of a phone number.
- [x] **End-to-End Encryption**: Supports Autocrypt to automatically encrypt
messages.
- [x] **No Phone Number Required**: Uses your email address instead of a phone
number.
- [x] **Cross-Platform**: Available on desktop and mobile platforms.
- [x] **Automatic Server Setup**: Includes your own DeltaChat server for enhanced control and privacy.
- [x] **Automatic Server Setup**: Includes your own DeltaChat server for
enhanced control and privacy.
- [ ] **Bake a cake**: This module cannot cake a bake.

View File

@ -2,11 +2,11 @@
description = "Automatically generates and configures a password for the root user."
---
After the system was installed/deployed the following command can be used to display the root-password:
After the system was installed/deployed the following command can be used to
display the root-password:
```bash
clan secrets get {machine_name}-password
```
See also: [Facts / Secrets](../../getting-started/secrets.md)

View File

@ -2,13 +2,16 @@
description = "Configures partitioning of the main disk"
categories = ["disk-layout"]
---
# Primary Disk Layout
A module for the "disk-layout" category MUST be choosen.
There is exactly one slot for this type of module in the UI, if you don't fill the slot, your machine cannot boot
There is exactly one slot for this type of module in the UI, if you don't fill
the slot, your machine cannot boot
This module is a good choice for most machines. In the future clan will offer a broader choice of disk-layouts
This module is a good choice for most machines. In the future clan will offer a
broader choice of disk-layouts
The UI will ask for the options of this module:
@ -17,6 +20,7 @@ The UI will ask for the options of this module:
# Usage example
`inventory.json`
```json
"services": {
"single-disk": {
@ -39,4 +43,4 @@ The UI will ask for the options of this module:
}
}
}
```
```

View File

@ -1,33 +1,45 @@
---
description = "A secure, file synchronization app for devices over networks, offering a private alternative to cloud services."
---
## Usage
We recommend configuring this module as an sync-service through the provided options. Although it provides a Web GUI through which more usage scenarios are supported.
We recommend configuring this module as an sync-service through the provided
options. Although it provides a Web GUI through which more usage scenarios are
supported.
## Features
- **Private and Secure**: Syncthing uses TLS encryption to secure data transfer between devices, ensuring that only the intended devices can read your data.
- **Decentralized**: No central server is involved in the data transfer. Each device communicates directly with others.
- **Open Source**: The source code is openly available for audit and contribution, fostering trust and continuous improvement.
- **Cross-Platform**: Syncthing supports multiple platforms including Windows, macOS, Linux, BSD, and Android.
- **Real-time Synchronization**: Changes made to files are synchronized in real-time across all connected devices.
- **Web GUI**: It includes a user-friendly web interface for managing devices and configurations. (`127.0.0.1:8384`)
- **Private and Secure**: Syncthing uses TLS encryption to secure data transfer
between devices, ensuring that only the intended devices can read your data.
- **Decentralized**: No central server is involved in the data transfer. Each
device communicates directly with others.
- **Open Source**: The source code is openly available for audit and
contribution, fostering trust and continuous improvement.
- **Cross-Platform**: Syncthing supports multiple platforms including Windows,
macOS, Linux, BSD, and Android.
- **Real-time Synchronization**: Changes made to files are synchronized in
real-time across all connected devices.
- **Web GUI**: It includes a user-friendly web interface for managing devices
and configurations. (`127.0.0.1:8384`)
## Configuration
- **Share Folders**: Select folders to share with connected devices and configure permissions and synchronization parameters.
- **Share Folders**: Select folders to share with connected devices and
configure permissions and synchronization parameters.
!!! info
Clan automatically discovers other devices. Automatic discovery requires one machine to be an [introducer](#clan.syncthing.introducer)
!!! info Clan automatically discovers other devices. Automatic discovery
requires one machine to be an [introducer](#clan.syncthing.introducer)
If that is not the case you can add the other device by its Device ID manually.
You can find and share Device IDs under the "Add Device" button in the Web GUI. (`127.0.0.1:8384`)
## Troubleshooting
- **Sync Conflicts**: Resolve synchronization conflicts manually by reviewing file versions and modification times in the Web GUI (`127.0.0.1:8384`).
- **Sync Conflicts**: Resolve synchronization conflicts manually by reviewing
file versions and modification times in the Web GUI (`127.0.0.1:8384`).
## Support
- **Documentation**: Extensive documentation is available on the [Syncthing website](https://docs.syncthing.net/).
- **Documentation**: Extensive documentation is available on the
[Syncthing website](https://docs.syncthing.net/).

View File

@ -1,3 +1,3 @@
---
description = "This module sets the `clan.lol` and `nix-community` cache up as a trusted cache."
----
## description = "This module sets the `clan.lol` and `nix-community` cache up as a trusted cache."

View File

@ -2,13 +2,14 @@
description = "Automatically generates and configures a password for the specified user account."
---
If setting the option prompt to true, the user will be prompted to type in their desired password.
If setting the option prompt to true, the user will be prompted to type in their
desired password.
!!! Note
This module will set `mutableUsers` to `false`, meaning you can not manage user passwords through `passwd` anymore.
!!! Note This module will set `mutableUsers` to `false`, meaning you can not
manage user passwords through `passwd` anymore.
After the system was installed/deployed the following command can be used to display the user-password:
After the system was installed/deployed the following command can be used to
display the user-password:
```bash
clan secrets get {machine_name}-user-password
@ -16,4 +17,5 @@ clan secrets get {machine_name}-user-password
See also: [Facts / Secrets](../../getting-started/secrets.md)
To regenerate the password, delete the password files in the clan directory and redeploy the machine.
To regenerate the password, delete the password files in the clan directory and
redeploy the machine.

View File

@ -1,6 +1,7 @@
---
description = "Statically configure the `zerotier` peers of a clan network."
---
Statically configure the `zerotier` peers of a clan network.
Requires a machine, that is the zerotier controller configured in the network.

View File

@ -1,8 +1,12 @@
# Contributing
**Continuous Integration (CI)**: Each pull request gets automatically tested by gitea. If any errors are detected, it will block pull requests until they're resolved.
**Continuous Integration (CI)**: Each pull request gets automatically tested by
gitea. If any errors are detected, it will block pull requests until they're
resolved.
**Dependency Management**: We use the [Nix package manager](https://nixos.org/) to manage dependencies and ensure reproducibility, making your development process more robust.
**Dependency Management**: We use the [Nix package manager](https://nixos.org/)
to manage dependencies and ensure reproducibility, making your development
process more robust.
## Supported Operating Systems
@ -15,81 +19,84 @@ Let's get your development environment up and running:
1. **Install Nix Package Manager**:
- You can install the Nix package manager by either [downloading the Nix installer](https://github.com/DeterminateSystems/nix-installer/releases) or running this command:
```bash
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
```
- You can install the Nix package manager by either
[downloading the Nix installer](https://github.com/DeterminateSystems/nix-installer/releases)
or running this command:
```bash
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
```
2. **Install direnv**:
- To automatically setup a devshell on entering the directory
```bash
nix profile install nixpkgs#nix-direnv-flakes
```
- To automatically setup a devshell on entering the directory
```bash
nix profile install nixpkgs#nix-direnv-flakes
```
3. **Add direnv to your shell**:
- Direnv needs to [hook into your shell](https://direnv.net/docs/hook.html) to work.
You can do this by executing following command. The example below will setup direnv for `zsh` and `bash`
- Direnv needs to [hook into your shell](https://direnv.net/docs/hook.html)
to work. You can do this by executing following command. The example below
will setup direnv for `zsh` and `bash`
```bash
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc && echo 'eval "$(direnv hook bash)"' >> ~/.bashrc && eval "$SHELL"
```
```bash
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc && echo 'eval "$(direnv hook bash)"' >> ~/.bashrc && eval "$SHELL"
```
4. **Create a Gitea Account**:
- Register an account on https://git.clan.lol
- Fork the [clan-core](https://git.clan.lol/clan/clan-core) repository
- Clone the repository and navigate to it
- Add a new remote called upstream:
```bash
git remote add upstream gitea@git.clan.lol:clan/clan-core.git
```
- Register an account on https://git.clan.lol
- Fork the [clan-core](https://git.clan.lol/clan/clan-core) repository
- Clone the repository and navigate to it
- Add a new remote called upstream:
```bash
git remote add upstream gitea@git.clan.lol:clan/clan-core.git
```
5. **Create an access token**:
- Log in to Gitea.
- Go to your account settings.
- Navigate to the Applications section.
- Click Generate New Token.
- Name your token and select all available scopes.
- Generate the token and copy it for later use.
- Your access token is now ready to use with all permissions.
- Log in to Gitea.
- Go to your account settings.
- Navigate to the Applications section.
- Click Generate New Token.
- Name your token and select all available scopes.
- Generate the token and copy it for later use.
- Your access token is now ready to use with all permissions.
5. **Register Your Gitea Account Locally**:
6. **Register Your Gitea Account Locally**:
- Execute the following command to add your Gitea account locally:
```bash
tea login add
```
- Fill out the prompt as follows:
- URL of Gitea instance: `https://git.clan.lol`
- Name of new Login [git.clan.lol]:
- Do you have an access token? Yes
- Token: <yourtoken>
- Set Optional settings: No
- Execute the following command to add your Gitea account locally:
```bash
tea login add
```
- Fill out the prompt as follows:
- URL of Gitea instance: `https://git.clan.lol`
- Name of new Login [git.clan.lol]:
- Do you have an access token? Yes
- Token: <yourtoken>
- Set Optional settings: No
7. **Allow .envrc**:
6. **Allow .envrc**:
- When you enter the directory, you'll receive an error message like this:
```bash
direnv: error .envrc is blocked. Run `direnv allow` to approve its content
```
- Execute `direnv allow` to automatically execute the shell script `.envrc`
when entering the directory.
- When you enter the directory, you'll receive an error message like this:
```bash
direnv: error .envrc is blocked. Run `direnv allow` to approve its content
```
- Execute `direnv allow` to automatically execute the shell script `.envrc` when entering the directory.
8. **(Optional) Install Git Hooks**:
- To syntax check your code you can run:
```bash
nix fmt
```
- To make this automatic install the git hooks
```bash
./scripts/pre-commit
```
7. **(Optional) Install Git Hooks**:
- To syntax check your code you can run:
```bash
nix fmt
```
- To make this automatic install the git hooks
```bash
./scripts/pre-commit
```
8. **Open a Pull Request**:
- To automatically open up a pull request you can use our tool called:
```
merge-after-ci --reviewers Mic92 Lassulus Qubasa
```
9. **Open a Pull Request**:
- To automatically open up a pull request you can use our tool called:
```
merge-after-ci --reviewers Mic92 Lassulus Qubasa
```
# Debugging
@ -103,7 +110,8 @@ To quickly show all possible packages and tests execute:
nix flake show --system no-eval
```
Under `checks` you will find all tests that are executed in our CI. Under `packages` you find all our projects.
Under `checks` you will find all tests that are executed in our CI. Under
`packages` you find all our projects.
```
git+file:///home/lhebendanz/Projects/clan-core
@ -138,26 +146,33 @@ git+file:///home/lhebendanz/Projects/clan-core
└───new-clan: template: Initialize a new clan flake
```
You can execute every test separately by following the tree path `nix build .#checks.x86_64-linux.clan-pytest` for example.
You can execute every test separately by following the tree path
`nix build .#checks.x86_64-linux.clan-pytest` for example.
## Test Locally in Devshell with Breakpoints
To test the cli locally in a development environment and set breakpoints for debugging, follow these steps:
To test the cli locally in a development environment and set breakpoints for
debugging, follow these steps:
1. Run the following command to execute your tests and allow for debugging with breakpoints:
1. Run the following command to execute your tests and allow for debugging with
breakpoints:
```bash
cd ./pkgs/clan-cli
pytest -n0 -s --maxfail=1 ./tests/test_nameofthetest.py
```
You can place `breakpoint()` in your Python code where you want to trigger a breakpoint for debugging.
You can place `breakpoint()` in your Python code where you want to trigger a
breakpoint for debugging.
## Test Locally in a Nix Sandbox
To run tests in a Nix sandbox, you have two options depending on whether your test functions have been marked as impure or not:
To run tests in a Nix sandbox, you have two options depending on whether your
test functions have been marked as impure or not:
### Running Tests Marked as Impure
If your test functions need to execute `nix build` and have been marked as impure because you can't execute `nix build` inside a Nix sandbox, use the following command:
If your test functions need to execute `nix build` and have been marked as
impure because you can't execute `nix build` inside a Nix sandbox, use the
following command:
```bash
nix run .#impure-checks
@ -167,7 +182,8 @@ This command will run the impure test functions.
### Running Pure Tests
For test functions that have not been marked as impure and don't require executing `nix build`, you can use the following command:
For test functions that have not been marked as impure and don't require
executing `nix build`, you can use the following command:
```bash
nix build .#checks.x86_64-linux.clan-pytest --rebuild
@ -179,22 +195,24 @@ This command will run all pure test functions.
If you need to inspect the Nix sandbox while running tests, follow these steps:
1. Insert an endless sleep into your test code where you want to pause the execution. For example:
1. Insert an endless sleep into your test code where you want to pause the
execution. For example:
```python
import time
time.sleep(3600) # Sleep for one hour
```
2. Use `cntr` and `psgrep` to attach to the Nix sandbox. This allows you to interactively debug your code while it's paused. For example:
2. Use `cntr` and `psgrep` to attach to the Nix sandbox. This allows you to
interactively debug your code while it's paused. For example:
```bash
psgrep -a -x your_python_process_name
cntr attach <container id, container name or process id>
```
Or you can also use the [nix breakpoint hook](https://nixos.org/manual/nixpkgs/stable/#breakpointhook)
Or you can also use the
[nix breakpoint hook](https://nixos.org/manual/nixpkgs/stable/#breakpointhook)
# Standards

View File

@ -2,17 +2,27 @@
## General Description
Self-hosting refers to the practice of hosting and maintaining servers, networks, storage, services, and other types of infrastructure by oneself rather than relying on a third-party vendor. This could involve running a server from a home or business location, or leasing a dedicated server at a data center.
Self-hosting refers to the practice of hosting and maintaining servers,
networks, storage, services, and other types of infrastructure by oneself rather
than relying on a third-party vendor. This could involve running a server from a
home or business location, or leasing a dedicated server at a data center.
There are several reasons for choosing to self-host. These can include:
1. Cost savings: Over time, self-hosting can be more cost-effective, especially for businesses with large scale needs.
1. Cost savings: Over time, self-hosting can be more cost-effective, especially
for businesses with large scale needs.
1. Control: Self-hosting provides a greater level of control over the infrastructure and services. It allows the owner to customize the system to their specific needs.
1. Control: Self-hosting provides a greater level of control over the
infrastructure and services. It allows the owner to customize the system to
their specific needs.
1. Privacy and security: Self-hosting can offer improved privacy and security because data remains under the control of the host rather than being stored on third-party servers.
1. Privacy and security: Self-hosting can offer improved privacy and security
because data remains under the control of the host rather than being stored
on third-party servers.
1. Independent: Being independent of third-party services can ensure that one's websites, applications, or services remain up even if the third-party service goes down.
1. Independent: Being independent of third-party services can ensure that one's
websites, applications, or services remain up even if the third-party service
goes down.
## Stories
@ -20,23 +30,32 @@ There are several reasons for choosing to self-host. These can include:
Alice wants to self-host a mumble server for her family.
- She visits to the Clan website, and follows the instructions on how to install Clan-OS on her server.
- Alice logs into a terminal on her server via SSH (alternatively uses Clan GUI app)
- Using the Clan CLI or GUI tool, alice creates a new private network for her family (VPN)
- Alice now browses a list of curated Clan modules and finds a module for mumble.
- She visits to the Clan website, and follows the instructions on how to install
Clan-OS on her server.
- Alice logs into a terminal on her server via SSH (alternatively uses Clan GUI
app)
- Using the Clan CLI or GUI tool, alice creates a new private network for her
family (VPN)
- Alice now browses a list of curated Clan modules and finds a module for
mumble.
- She adds this module to her network using the Clan tool.
- After that, she uses the clan tool to invite her family members to her network
- Other family members join the private network via the invitation.
- By accepting the invitation, other members automatically install all required software to interact with the network on their machine.
- By accepting the invitation, other members automatically install all required
software to interact with the network on their machine.
### Story 2: Adding a service to an existing network
Alice wants to add a photos app to her private network
- She uses the clan CLI or GUI tool to manage her existing private Clan family network
- She discovers a module for photoprism, and adds it to her server using the tool
- Other members who are already part of her network, will receive a notification that an update is required to their environment
- After accepting, all new software and services to interact with the new photoprism service will be installed automatically.
- She uses the clan CLI or GUI tool to manage her existing private Clan family
network
- She discovers a module for photoprism, and adds it to her server using the
tool
- Other members who are already part of her network, will receive a notification
that an update is required to their environment
- After accepting, all new software and services to interact with the new
photoprism service will be installed automatically.
## Challenges

View File

@ -2,35 +2,53 @@
## General Description
Joining a self-hosted infrastructure involves connecting to a network, server, or system that is privately owned and managed, instead of being hosted by a third-party service provider. This could be a business's internal server, a private cloud setup, or any other private IT infrastructure that is not publicly accessible or controlled by outside entities.
Joining a self-hosted infrastructure involves connecting to a network, server,
or system that is privately owned and managed, instead of being hosted by a
third-party service provider. This could be a business's internal server, a
private cloud setup, or any other private IT infrastructure that is not publicly
accessible or controlled by outside entities.
## Stories
### Story 1: Joining a private network
Alice' son Bob has never heard of Clan, but receives an invitation URL from Alice who already set up private Clan network for her family.
Alice' son Bob has never heard of Clan, but receives an invitation URL from
Alice who already set up private Clan network for her family.
Bob opens the invitation link and lands on the Clan website. He quickly learns about what Clan is and can see that the invitation is for a private network of his family that hosts a number of services, like a private voice chat and a photo sharing platform.
Bob opens the invitation link and lands on the Clan website. He quickly learns
about what Clan is and can see that the invitation is for a private network of
his family that hosts a number of services, like a private voice chat and a
photo sharing platform.
Bob decides to join the network and follows the instructions to install the Clan tool on his computer.
Bob decides to join the network and follows the instructions to install the Clan
tool on his computer.
Feeding the invitation link to the Clan tool, bob registers his machine with the network.
Feeding the invitation link to the Clan tool, bob registers his machine with the
network.
All programs required to interact with the network will be installed and configured automatically and securely.
All programs required to interact with the network will be installed and
configured automatically and securely.
Optionally, bob can customize the configuration of these programs through a simplified configuration interface.
Optionally, bob can customize the configuration of these programs through a
simplified configuration interface.
### Story 2: Receiving breaking changes
The Clan family network which Bob is part of received an update.
The existing photo sharing service has been removed and replaced with another alternative service. The new photo sharing service requires a different client app to view and upload photos.
The existing photo sharing service has been removed and replaced with another
alternative service. The new photo sharing service requires a different client
app to view and upload photos.
Bob accepts the update. Now his environment will be updated. The old client software will be removed and the new one installed.
Bob accepts the update. Now his environment will be updated. The old client
software will be removed and the new one installed.
Because Bob has customized the previous photo viewing app, he is notified that this customization is no longer valid, as the software has been removed (deprecation message).l
Because Bob has customized the previous photo viewing app, he is notified that
this customization is no longer valid, as the software has been removed
(deprecation message).l
Optionally, Bob can now customize the new photo viewing software through his Clan configuration app or via a config file.
Optionally, Bob can now customize the new photo viewing software through his
Clan configuration app or via a config file.
## Challenges

View File

@ -2,23 +2,30 @@
## General Description
Clan modules are pieces of software that can be used by admins to build a private or public infrastructure.
Clan modules are pieces of software that can be used by admins to build a
private or public infrastructure.
Clan modules should have the following properties:
1. Documented: It should be clear what the module does and how to use it.
1. Self contained: A module should be usable as is. If it requires any other software or settings, those should be delivered with the module itself.
1. Simple to deploy and use: Modules should have opinionated defaults that just work. Any customization should be optional
1. Self contained: A module should be usable as is. If it requires any other
software or settings, those should be delivered with the module itself.
1. Simple to deploy and use: Modules should have opinionated defaults that just
work. Any customization should be optional
## Stories
### Story 1: Maintaining a shared folder module
Alice maintains a module for a shared folder service that she uses in her own infra, but also publishes for the community.
Alice maintains a module for a shared folder service that she uses in her own
infra, but also publishes for the community.
By following clan module standards (Backups, Interfaces, Output schema, etc), other community members have an easy time re-using the module within their own infra.
By following clan module standards (Backups, Interfaces, Output schema, etc),
other community members have an easy time re-using the module within their own
infra.
She benefits from publishing the module, because other community members start using it and help to maintain it.
She benefits from publishing the module, because other community members start
using it and help to maintain it.
## Challenges

View File

@ -1,2 +1 @@
# Blog

View File

@ -7,27 +7,34 @@ date: 2024-06-24
slug: backups
---
Our goal with [Clan](https://clan.lol/) is to give users control over their data.
However, with great power comes great responsibility, and owning your data means you also need to take care of backups yourself.
Our goal with [Clan](https://clan.lol/) is to give users control over their
data. However, with great power comes great responsibility, and owning your data
means you also need to take care of backups yourself.
In our experience, setting up automatic backups is often a tedious process as it requires custom integration of the backup software and
the services that produce the state. More important than the backup is the restore.
Restores are often not well tested or documented, and if not working correctly, they can render the backup useless.
In our experience, setting up automatic backups is often a tedious process as it
requires custom integration of the backup software and the services that produce
the state. More important than the backup is the restore. Restores are often not
well tested or documented, and if not working correctly, they can render the
backup useless.
In Clan, we want to make backup and restore a first-class citizen.
Every service should describe what state it produces and how it can be backed up and restored.
In this article, we will discuss how our backup interface in Clan works.
The interface allows different backup software to be used interchangeably and
allows module authors to define custom backup and restore logic for their services.
In Clan, we want to make backup and restore a first-class citizen. Every service
should describe what state it produces and how it can be backed up and restored.
In this article, we will discuss how our backup interface in Clan works. The
interface allows different backup software to be used interchangeably and allows
module authors to define custom backup and restore logic for their services.
## First Comes the State
Our services are built from Clan modules. Clan modules are essentially [NixOS modules](https://wiki.nixos.org/wiki/NixOS_modules), the basic configuration components of NixOS.
However, we have enhanced them with additional features provided by Clan and restricted certain option types to enable configuration through a [graphical interface](https://docs.clan.lol/blog/2024/05/25/jsonschema-converter/).
Our services are built from Clan modules. Clan modules are essentially
[NixOS modules](https://wiki.nixos.org/wiki/NixOS_modules), the basic
configuration components of NixOS. However, we have enhanced them with
additional features provided by Clan and restricted certain option types to
enable configuration through a
[graphical interface](https://docs.clan.lol/blog/2024/05/25/jsonschema-converter/).
In a simple case, this can be just a bunch of directories, such as what we define for our [ZeroTier](https://www.zerotier.com/) VPN service.
In a simple case, this can be just a bunch of directories, such as what we
define for our [ZeroTier](https://www.zerotier.com/) VPN service.
```nix
{
@ -35,10 +42,12 @@ In a simple case, this can be just a bunch of directories, such as what we defin
}
```
For other systems, we need more complex backup and restore logic.
For each state, we can provide custom command hooks for backing up and restoring.
For other systems, we need more complex backup and restore logic. For each
state, we can provide custom command hooks for backing up and restoring.
In our PostgreSQL module, for example, we define `preBackupCommand` and `postRestoreCommand` to use `pg_dump` and `pg_restore` to backup and restore individual databases:
In our PostgreSQL module, for example, we define `preBackupCommand` and
`postRestoreCommand` to use `pg_dump` and `pg_restore` to backup and restore
individual databases:
```nix
preBackupCommand = ''
@ -56,46 +65,54 @@ postRestoreCommand = ''
## Then the Backup
Our CLI unifies the different backup providers in one [interface](https://docs.clan.lol/reference/cli/backups/).
Our CLI unifies the different backup providers in one
[interface](https://docs.clan.lol/reference/cli/backups/).
As of now, we support backups using [BorgBackup](https://www.borgbackup.org/) and
a backup module called "localbackup" based on [rsnapshot](https://rsnapshot.org/), optimized for backup on locally attached storage media.
As of now, we support backups using [BorgBackup](https://www.borgbackup.org/)
and a backup module called "localbackup" based on
[rsnapshot](https://rsnapshot.org/), optimized for backup on locally attached
storage media.
To use different backup software, a module needs to set the options provided by our backup interface.
The following Nix code is a toy example that uses the `tar` program to perform backup and restore to illustrate how the backup interface works:
To use different backup software, a module needs to set the options provided by
our backup interface. The following Nix code is a toy example that uses the
`tar` program to perform backup and restore to illustrate how the backup
interface works:
```nix
clan.core.backups.providers.tar = {
list = ''
echo /var/lib/system-back.tar
'';
create = let
uniqueFolders = lib.unique (
lib.flatten (lib.mapAttrsToList (_name: state: state.folders) config.clan.core.state)
);
in ''
# FIXME: a proper implementation should also run `state.preBackupCommand` of each state
if [ -f /var/lib/system-back.tar ]; then
tar -uvpf /var/lib/system-back.tar ${builtins.toString uniqueFolders}
else
tar -cvpf /var/lib/system-back.tar ${builtins.toString uniqueFolders}
fi
'';
restore = ''
IFS=':' read -ra FOLDER <<< "''$FOLDERS"
echo "${FOLDER[@]}" > /run/folders-to-restore.txt
tar -xvpf /var/lib/system-back.tar -C / -T /run/folders-to-restore.txt
'';
};
clan.core.backups.providers.tar = {
list = ''
echo /var/lib/system-back.tar
'';
create = let
uniqueFolders = lib.unique (
lib.flatten (lib.mapAttrsToList (_name: state: state.folders) config.clan.core.state)
);
in ''
# FIXME: a proper implementation should also run `state.preBackupCommand` of each state
if [ -f /var/lib/system-back.tar ]; then
tar -uvpf /var/lib/system-back.tar ${builtins.toString uniqueFolders}
else
tar -cvpf /var/lib/system-back.tar ${builtins.toString uniqueFolders}
fi
'';
restore = ''
IFS=':' read -ra FOLDER <<< "''$FOLDERS"
echo "${FOLDER[@]}" > /run/folders-to-restore.txt
tar -xvpf /var/lib/system-back.tar -C / -T /run/folders-to-restore.txt
'';
};
```
For better real-world implementations, check out the implementations for [BorgBackup](https://git.clan.lol/clan/clan-core/src/branch/main/clanModules/borgbackup/default.nix)
and [localbackup](https://git.clan.lol/clan/clan-core/src/branch/main/clanModules/localbackup/default.nix).
For better real-world implementations, check out the implementations for
[BorgBackup](https://git.clan.lol/clan/clan-core/src/branch/main/clanModules/borgbackup/default.nix)
and
[localbackup](https://git.clan.lol/clan/clan-core/src/branch/main/clanModules/localbackup/default.nix).
## What It Looks Like to the End User
After following the guide for configuring a [backup](https://docs.clan.lol/getting-started/backups/),
users can use the CLI to create backups, list them, and restore them.
After following the guide for configuring a
[backup](https://docs.clan.lol/getting-started/backups/), users can use the CLI
to create backups, list them, and restore them.
Backups can be created through the CLI like this:
@ -113,20 +130,26 @@ clan backups list web01
web01::u366395@u366395.your-storagebox.de:/./borgbackup::web01-web01-2024-06-18T01:00:00
web03::u366395@u366395.your-storagebox.de:/./borgbackup::web01-web01-2024-06-19T01:00:00
```
One cool feature of our backup system is that it is aware of individual services/applications.
Let's say we want to restore the state of our [Matrix](https://matrix.org/) chat server; we can just specify it like this:
One cool feature of our backup system is that it is aware of individual
services/applications. Let's say we want to restore the state of our
[Matrix](https://matrix.org/) chat server; we can just specify it like this:
```
clan backups restore --service matrix-synapse web01 borgbackup web03::u366395@u366395.your-storagebox.de:/./borgbackup::web01-web01-2024-06-19T01:00:00
```
In this case, it will first stop the matrix-synapse systemd service, then delete the [PostgreSQL](https://www.postgresql.org/) database, restore the database from the backup, and then start the matrix-synapse service again.
In this case, it will first stop the matrix-synapse systemd service, then delete
the [PostgreSQL](https://www.postgresql.org/) database, restore the database
from the backup, and then start the matrix-synapse service again.
## Future work
As of now we implemented our backup and restore for a handful of services and we expect to refine the interface as we test the interface for more applications.
As of now we implemented our backup and restore for a handful of services and we
expect to refine the interface as we test the interface for more applications.
Currently, our backup implementation backs up filesystem state from running services.
This can lead to inconsistencies if applications change the state while the backup is running.
In the future, we hope to make backups more atomic by backing up a filesystem snapshot instead of normal directories.
This, however, requires the use of modern filesystems that support these features.
Currently, our backup implementation backs up filesystem state from running
services. This can lead to inconsistencies if applications change the state
while the backup is running. In the future, we hope to make backups more atomic
by backing up a filesystem snapshot instead of normal directories. This,
however, requires the use of modern filesystems that support these features.

View File

@ -7,66 +7,113 @@ authors:
date: 2024-03-19
---
In a digital age where users are guided increasingly toward submission and
dependence, Clan reclaims computing and networking from the ground up.
In a digital age where users are guided increasingly toward submission and dependence, Clan reclaims computing and networking from the ground up.
Clan enables users to build any system from a git repository, automate secret handling, and join devices in a secure darknet. This control extends beyond applications to communication protocols and the operating system itself, putting you fully in charge of your own digital environment.
Clan enables users to build any system from a git repository, automate secret
handling, and join devices in a secure darknet. This control extends beyond
applications to communication protocols and the operating system itself, putting
you fully in charge of your own digital environment.
## Why We're Building Clan
Our mission is simple: to restore fun, freedom, and functionality to computing as an open source project. We believe in building tools that empower users, foster innovation, and challenge the limitations imposed by outdated paradigms. Clan, in its essence, is an open source endeavor; it's our contribution to a future where technology serves humanity, not the other way around.
Our mission is simple: to restore fun, freedom, and functionality to computing
as an open source project. We believe in building tools that empower users,
foster innovation, and challenge the limitations imposed by outdated paradigms.
Clan, in its essence, is an open source endeavor; it's our contribution to a
future where technology serves humanity, not the other way around.
## How Clan Changes the Game
Clan embodies a new philosophy in system, application, and network design. It enables seamless, secure communication across devices, simplifies software distribution and updates, and offers both public and private network configurations. Here are some of the ways it accomplishes this:
- **Nix as a Foundation:** Imagine a safety net for your computer's operating system, one that lets you make changes or updates without the fear of causing a crash or losing data. Nix simplifies the complexities of system design, ensuring that updates are safe and systems are more reliable.
Clan embodies a new philosophy in system, application, and network design. It
enables seamless, secure communication across devices, simplifies software
distribution and updates, and offers both public and private network
configurations. Here are some of the ways it accomplishes this:
- **Simplified System Deployment:** Building and managing a computer system, from the operating system to the software you use, often feels like putting together a complex puzzle. With Clan, the puzzle pieces are replaced by a set of building blocks. Leveraging the power of Nix and Clan's innovative toolkit, anyone from tech-savvy administrators to everyday users can create and maintain what we call "full-stack systems" (everything your computer needs to run smoothly).
- **Nix as a Foundation:** Imagine a safety net for your computer's operating
system, one that lets you make changes or updates without the fear of causing
a crash or losing data. Nix simplifies the complexities of system design,
ensuring that updates are safe and systems are more reliable.
- **A Leap in Connectivity:** Imagine if you could create private, secure pathways between your devices, bypassing the noisy and often insecure internet. Clan makes this possible through something called "overlay networks." These networks are like private tunnels, allowing your devices to talk to each other securely and directly. With Clan's built-in overlay networks and automatically configured services, connecting your devices becomes seamless, secure, and hassle-free.
- **Simplified System Deployment:** Building and managing a computer system,
from the operating system to the software you use, often feels like putting
together a complex puzzle. With Clan, the puzzle pieces are replaced by a set
of building blocks. Leveraging the power of Nix and Clan's innovative toolkit,
anyone from tech-savvy administrators to everyday users can create and
maintain what we call "full-stack systems" (everything your computer needs to
run smoothly).
- **Security Through Separation:** Clan employs sandboxing and virtual machines, a technology that runs code in isolated environments - so even if you explore new Clans, your system remains protected from potential threats.
- **A Leap in Connectivity:** Imagine if you could create private, secure
pathways between your devices, bypassing the noisy and often insecure
internet. Clan makes this possible through something called "overlay
networks." These networks are like private tunnels, allowing your devices to
talk to each other securely and directly. With Clan's built-in overlay
networks and automatically configured services, connecting your devices
becomes seamless, secure, and hassle-free.
- **Reliable:** With Clan, your data and services are preserved for the long haul. We focus on self-hosted backups and integration with the [Fediverse](https://de.wikipedia.org/wiki/Fediverse), a network of interconnected, independent online communities, so your digital life remains uninterrupted and under your control.
- **Security Through Separation:** Clan employs sandboxing and virtual machines,
a technology that runs code in isolated environments - so even if you explore
new Clans, your system remains protected from potential threats.
- **Reliable:** With Clan, your data and services are preserved for the long
haul. We focus on self-hosted backups and integration with the
[Fediverse](https://de.wikipedia.org/wiki/Fediverse), a network of
interconnected, independent online communities, so your digital life remains
uninterrupted and under your control.
## A Glimpse at Clan's Features
- **Social Scaling:** Choose between creating a private sanctuary for your closest contacts, a dynamic space for a self-contained community, or embracing the open web with public Clans anyone can join.
- **Social Scaling:** Choose between creating a private sanctuary for your
closest contacts, a dynamic space for a self-contained community, or embracing
the open web with public Clans anyone can join.
{{ video(name="show_join.webm")}}
- **Seamless VM Integration:** Applications running in virtual machines can appear and behave as if they're part of your main operating system — a blend of power and simplicity.
- **Seamless VM Integration:** Applications running in virtual machines can
appear and behave as if they're part of your main operating system — a blend
of power and simplicity.
{{ video(name="show_run.webm")}}
- **Robust Backup Management:** Keep your data safe _forever_ - never worry about cloud services disappearing in 10 years.
- **Robust Backup Management:** Keep your data safe _forever_ - never worry
about cloud services disappearing in 10 years.
{{ asciinema(name="backups.cast") }}
- **Intuitive Secret Management:** Clan simplifies digital security by automating the creation and management of encryption keys and passwords for your services.
- **Intuitive Secret Management:** Clan simplifies digital security by
automating the creation and management of encryption keys and passwords for
your services.
{{ asciinema(name="secrets.cast") }}
- **Remote Install:** Set up and manage Clan systems anywhere in the world with just a QR scan or SSH access, making remote installations as easy as snapping a photo or sharing a link.
- **Remote Install:** Set up and manage Clan systems anywhere in the world with
just a QR scan or SSH access, making remote installations as easy as snapping
a photo or sharing a link.
{{ asciinema(name="nixos-install.cast") }}
## Who Stands to Benefit?
Clan is for anyone and everyone who believes in the power of open source technology to connect, empower, and protect. From system administrators to less tech-savvy individuals, small business owners to privacy-conscious users, Clan offers something for everyone — a way to reclaim control and redefine how we interact with technology.
Clan is for anyone and everyone who believes in the power of open source
technology to connect, empower, and protect. From system administrators to less
tech-savvy individuals, small business owners to privacy-conscious users, Clan
offers something for everyone — a way to reclaim control and redefine how we
interact with technology.
## Join the Revolution
Ready to control your digital world? Clan is more than a tool—it's a movement. Secure your data, manage your systems easily, or connect with others how you like. Start with Clan for a better digital future.
Ready to control your digital world? Clan is more than a tool—it's a movement.
Secure your data, manage your systems easily, or connect with others how you
like. Start with Clan for a better digital future.
Connect with us on our [Matrix channel at clan.lol](https://matrix.to/#/#clan:clan.lol) or through our IRC bridges (coming soon).
Connect with us on our
[Matrix channel at clan.lol](https://matrix.to/#/#clan:clan.lol) or through our
IRC bridges (coming soon).
Want to see the code? Check it out [on our Gitea](https://git.clan.lol/clan/clan-core) or [on GitHub](https://github.com/clan-lol/clan-core).
Want to see the code? Check it out
[on our Gitea](https://git.clan.lol/clan/clan-core) or
[on GitHub](https://github.com/clan-lol/clan-core).
Or follow our [RSS feed](https://docs.clan.lol/feed_rss_created.xml)!
Join us and be part of changing technology for the better, together.

View File

@ -9,11 +9,18 @@ slug: jsonschema-converter
## Overview
Weve developed a new library designed to extract interfaces from NixOS modules and convert them into JSON schemas, paving the way for effortless GUI generation. This blog post outlines the motivations behind this development, demonstrates the capabilities of the library, and guides you through leveraging it to create GUIs seamlessly.
Weve developed a new library designed to extract interfaces from NixOS modules
and convert them into JSON schemas, paving the way for effortless GUI
generation. This blog post outlines the motivations behind this development,
demonstrates the capabilities of the library, and guides you through leveraging
it to create GUIs seamlessly.
## Motivation
In recent months, our team has been exploring various graphical user interfaces (GUIs) to streamline NixOS machine configuration. While our opinionated Clan modules simplify NixOS configurations, there's a need to configure these modules from diverse frontends, such as:
In recent months, our team has been exploring various graphical user interfaces
(GUIs) to streamline NixOS machine configuration. While our opinionated Clan
modules simplify NixOS configurations, there's a need to configure these modules
from diverse frontends, such as:
- Command-line interfaces (CLIs)
- Web-based UIs
@ -21,14 +28,18 @@ In recent months, our team has been exploring various graphical user interfaces
- Mobile applications
- Large Language Models (LLMs)
Given this need, a universal format like JSON is a natural choice. It is already possible as of now, to import json based NixOS configurations, as illustrated below:
Given this need, a universal format like JSON is a natural choice. It is already
possible as of now, to import json based NixOS configurations, as illustrated
below:
`configuration.json`:
```json
{ "networking": { "hostName": "my-machine" } }
```
This configuration can be then imported inside a classic NixOS config:
```nix
{config, lib, pkgs, ...}: {
imports = [
@ -37,14 +48,17 @@ This configuration can be then imported inside a classic NixOS config:
}
```
This straightforward approach allows us to build a frontend that generates JSON, enabling the configuration of NixOS machines. But, two critical questions arise:
This straightforward approach allows us to build a frontend that generates JSON,
enabling the configuration of NixOS machines. But, two critical questions arise:
1. How does the frontend learn about existing configuration options?
2. How can it verify user input without running Nix?
Introducing [JSON schema](https://json-schema.org/), a widely supported standard that defines interfaces in JSON and validates input against them.
Introducing [JSON schema](https://json-schema.org/), a widely supported standard
that defines interfaces in JSON and validates input against them.
Example schema for `networking.hostName`:
```json
{
"type": "object",
@ -64,7 +78,9 @@ Example schema for `networking.hostName`:
## Client-Side Input Validation
Validating input against JSON schemas is both efficient and well-supported across numerous programming languages. Using JSON schema validators, you can accurately check configurations like our `configuration.json`.
Validating input against JSON schemas is both efficient and well-supported
across numerous programming languages. Using JSON schema validators, you can
accurately check configurations like our `configuration.json`.
Validation example:
@ -93,20 +109,28 @@ On instance['networking']['hostName']:
## Automatic GUI Generation
Certain libraries facilitate straightforward GUI generation from JSON schemas. For instance, the [react-jsonschema-form playground](https://rjsf-team.github.io/react-jsonschema-form/) auto-generates a form for any given schema.
Certain libraries facilitate straightforward GUI generation from JSON schemas.
For instance, the
[react-jsonschema-form playground](https://rjsf-team.github.io/react-jsonschema-form/)
auto-generates a form for any given schema.
## NixOS Module to JSON Schema Converter
To enable the development of responsive frontends, our library allows the extraction of interfaces from NixOS modules to JSON schemas. Open-sourced for community collaboration, this library supports building sophisticated user interfaces for NixOS.
To enable the development of responsive frontends, our library allows the
extraction of interfaces from NixOS modules to JSON schemas. Open-sourced for
community collaboration, this library supports building sophisticated user
interfaces for NixOS.
Heres a preview of our library's functions exposed through the [clan-core](https://git.clan.lol/clan/clan-core) flake:
Heres a preview of our library's functions exposed through the
[clan-core](https://git.clan.lol/clan/clan-core) flake:
- `lib.jsonschema.parseModule` - Generates a schema for a NixOS module.
- `lib.jsonschema.parseOption` - Generates a schema for a single NixOS option.
- `lib.jsonschema.parseOptions` - Generates a schema from an attrset of NixOS options.
- `lib.jsonschema.parseOptions` - Generates a schema from an attrset of NixOS
options.
Example: `module.nix`:
Example:
`module.nix`:
```nix
{lib, config, pkgs, ...}: {
# a simple service with two options
@ -121,6 +145,7 @@ Example:
```
Converted, using the `parseModule` function:
```shell
$ cd clan-core
$ nix eval --json --impure --expr \
@ -142,7 +167,9 @@ This utility can also generate interfaces for existing NixOS modules or options.
## GUI for NGINX in Under a Minute
Creating a prototype GUI for the NGINX module using our library and [react-jsonschema-form playground](https://rjsf-team.github.io/react-jsonschema-form/) can be done quickly:
Creating a prototype GUI for the NGINX module using our library and
[react-jsonschema-form playground](https://rjsf-team.github.io/react-jsonschema-form/)
can be done quickly:
1. Export all NGINX options into a JSON schema using a Nix expression:
@ -157,11 +184,14 @@ in
```
2. Write the schema into a file:
```shell
$ nix eval --json -f ./export.nix | jq > nginx.json
```
3. Open the [react-jsonschema-form playground](https://rjsf-team.github.io/react-jsonschema-form/), select `Blank` and paste the `nginx.json` contents.
3. Open the
[react-jsonschema-form playground](https://rjsf-team.github.io/react-jsonschema-form/),
select `Blank` and paste the `nginx.json` contents.
This provides a quick look at a potential GUI (screenshot is cropped).
@ -171,19 +201,30 @@ This provides a quick look at a potential GUI (screenshot is cropped).
### Laziness
JSON schema mandates the declaration of all required fields upfront, which might be configured implicitly or remain unused. For instance, `services.nginx.virtualHosts.<name>.sslCertificate` must be specified even if SSL isnt enabled.
JSON schema mandates the declaration of all required fields upfront, which might
be configured implicitly or remain unused. For instance,
`services.nginx.virtualHosts.<name>.sslCertificate` must be specified even if
SSL isnt enabled.
### Limited Types
Certain NixOS module types, like `types.functionTo` and `types.package`, do not map straightforwardly to JSON. For full compatibility, adjustments to NixOS modules might be necessary, such as substituting `listOf package` with `listOf str`.
Certain NixOS module types, like `types.functionTo` and `types.package`, do not
map straightforwardly to JSON. For full compatibility, adjustments to NixOS
modules might be necessary, such as substituting `listOf package` with
`listOf str`.
### Parsing NixOS Modules
Currently, our converter relies on the `options` attribute of evaluated NixOS modules, extracting information from the `type.name` attribute, which is suboptimal. Enhanced introspection capabilities within the NixOS module system would be beneficial.
Currently, our converter relies on the `options` attribute of evaluated NixOS
modules, extracting information from the `type.name` attribute, which is
suboptimal. Enhanced introspection capabilities within the NixOS module system
would be beneficial.
## Future Prospects
We hope these experiments inspire the community, encourage contributions and further development in this space. Share your ideas and contributions through our issue tracker or matrix channel!
We hope these experiments inspire the community, encourage contributions and
further development in this space. Share your ideas and contributions through
our issue tracker or matrix channel!
## Links

View File

@ -6,8 +6,9 @@ authors:
date: 2024-04-16
---
Last week, we added a new documentation hub for clan at [docs.clan.lol](https://docs.clan.lol).
We are still working on improving the installation procedures, so stay tuned.
We now have weekly office hours where people are invited to hangout and ask questions.
They are every Wednesday 15:30 UTC (17:30 CEST) in our [jitsi](https://jitsi.lassul.us/clan.lol).
Otherwise drop by in our [matrix channel](https://matrix.to/#/#clan:clan.lol).
Last week, we added a new documentation hub for clan at
[docs.clan.lol](https://docs.clan.lol). We are still working on improving the
installation procedures, so stay tuned. We now have weekly office hours where
people are invited to hangout and ask questions. They are every Wednesday 15:30
UTC (17:30 CEST) in our [jitsi](https://jitsi.lassul.us/clan.lol). Otherwise
drop by in our [matrix channel](https://matrix.to/#/#clan:clan.lol).

View File

@ -3,7 +3,9 @@
## Introduction
When managing machine configuration this can be done through many possible ways.
Ranging from writing `nix` expression in a `flake.nix` file; placing `autoincluded` files into your machine directory; or configuring everything in a simple UI (upcomming).
Ranging from writing `nix` expression in a `flake.nix` file; placing
`autoincluded` files into your machine directory; or configuring everything in a
simple UI (upcomming).
clan currently offers the following methods to configure machines:
@ -20,44 +22,43 @@ clan currently offers the following methods to configure machines:
- inventory.json
- machines/`machine_name`/hardware-configuration.nix (`autoincluded` if it exists)
!!! Warning "Deprecated"
machines/`machine_name`/settings.json
## BuildClan
The core function that produces a clan. It returns a set of consistent configurations for all machines with ready-to-use secrets, backups and other services.
The core function that produces a clan. It returns a set of consistent
configurations for all machines with ready-to-use secrets, backups and other
services.
### Inputs
`directory`
: The directory containing the machines subdirectory
`directory` : The directory containing the machines subdirectory
`machines`
: Allows to include machine-specific modules i.e. machines.${name} = { ... }
`machines` : Allows to include machine-specific modules i.e. machines.${name} =
{ ... }
`meta`
: An optional set
`meta` : An optional set
: `{ name :: string, icon :: string, description :: string }`
`inventory`
: Service set for easily configuring distributed services, such as backups
`inventory` : Service set for easily configuring distributed services, such as
backups
: For more details see [Inventory](#inventory)
`specialArgs`
: Extra arguments to pass to nixosSystem i.e. useful to make self available
`specialArgs` : Extra arguments to pass to nixosSystem i.e. useful to make self
available
`pkgsForSystem`
: A function that maps from architecture to pkgs, if specified this nixpkgs will be only imported once for each system.
This improves performance, but all nipxkgs.* options will be ignored.
`(string -> pkgs )`
`pkgsForSystem` : A function that maps from architecture to pkgs, if specified
this nixpkgs will be only imported once for each system. This improves
performance, but all nipxkgs.* options will be ignored. `(string -> pkgs )`
## Inventory
`Inventory` is an abstract service layer for consistently configuring distributed services across machine boundaries.
`Inventory` is an abstract service layer for consistently configuring
distributed services across machine boundaries.
The following is the specification of the inventory in `cuelang`

View File

@ -5,59 +5,110 @@ authors:
- Qubasa
date: 2024-05-25
---
## Revolutionizing Server Management
In the world of server management, countless tools claim to offer seamless deployment of multiple machines. Yet, many fall short, leaving server admins and self-hosting enthusiasts grappling with complexity. Enter the Clan-Core Framework—a groundbreaking all in one solution designed to transform decentralized self-hosting into an effortless and scalable endeavor.
In the world of server management, countless tools claim to offer seamless
deployment of multiple machines. Yet, many fall short, leaving server admins and
self-hosting enthusiasts grappling with complexity. Enter the Clan-Core
Framework—a groundbreaking all in one solution designed to transform
decentralized self-hosting into an effortless and scalable endeavor.
### The Power of Clan-Core
Imagine having the power to manage your servers with unparalleled ease, scaling your IT infrastructure like never before. Clan-Core empowers you to do just that. At its core, Clan-Core leverages a single Git repository to define everything about your machines. This central repository utilizes Nix or JSON files to specify configurations, including disk formatting, ensuring a streamlined and unified approach.
Imagine having the power to manage your servers with unparalleled ease, scaling
your IT infrastructure like never before. Clan-Core empowers you to do just
that. At its core, Clan-Core leverages a single Git repository to define
everything about your machines. This central repository utilizes Nix or JSON
files to specify configurations, including disk formatting, ensuring a
streamlined and unified approach.
### Simplified Deployment Process
With Clan-Core, the cumbersome task of bootstrapping a specific ISO is a thing of the past. All you need is SSH access to your Linux server. Clan-Core allows you to overwrite any existing Linux distribution live over SSH, eliminating time-consuming setup processes. This capability means you can deploy updates or new configurations swiftly and efficiently, maximizing uptime and minimizing hassle.
With Clan-Core, the cumbersome task of bootstrapping a specific ISO is a thing
of the past. All you need is SSH access to your Linux server. Clan-Core allows
you to overwrite any existing Linux distribution live over SSH, eliminating
time-consuming setup processes. This capability means you can deploy updates or
new configurations swiftly and efficiently, maximizing uptime and minimizing
hassle.
### Secure and Efficient Secret Management
Security is paramount in server management, and Clan-Core takes it seriously. Passwords and other sensitive information are encrypted within the Git repository, automatically decrypted during deployment. This not only ensures the safety of your secrets but also simplifies their management. Clan-Core supports sharing secrets with other admins, fostering collaboration and maintaining reproducibillity and security without sacrificing convenience.
Security is paramount in server management, and Clan-Core takes it seriously.
Passwords and other sensitive information are encrypted within the Git
repository, automatically decrypted during deployment. This not only ensures the
safety of your secrets but also simplifies their management. Clan-Core supports
sharing secrets with other admins, fostering collaboration and maintaining
reproducibillity and security without sacrificing convenience.
### Services as Apps
Setting up a service can be quite difficult. Many server adjustments need to be made, from setting up a database to adjusting webserver configurations and generating the correct private keys. However, Clan-Core aims to make setting up a service as easy as installing an application. Through Clan-Core's Module system, everything down to secrets can be automatically set up. This transforms the often daunting task of service setup into a smooth, automated process, making it accessible to all.
Setting up a service can be quite difficult. Many server adjustments need to be
made, from setting up a database to adjusting webserver configurations and
generating the correct private keys. However, Clan-Core aims to make setting up
a service as easy as installing an application. Through Clan-Core's Module
system, everything down to secrets can be automatically set up. This transforms
the often daunting task of service setup into a smooth, automated process,
making it accessible to all.
### Decentralized Mesh VPN
Building on these features is a self-configuring decentralized mesh VPN that interconnects all your machines into a private darknet. This ensures that sensitive services, which might have too much attack surface to be hosted on the public internet, can still be made available privately without the need to worry about potential system compromise. By creating a secure, private network, Clan-Core offers an additional layer of protection for your most critical services.
Building on these features is a self-configuring decentralized mesh VPN that
interconnects all your machines into a private darknet. This ensures that
sensitive services, which might have too much attack surface to be hosted on the
public internet, can still be made available privately without the need to worry
about potential system compromise. By creating a secure, private network,
Clan-Core offers an additional layer of protection for your most critical
services.
### Decentralized Domain Name System
Current DNS implementations are distributed but not truly decentralized. For Clan-Core, we implemented our own truly decentralized DNS module. This module uses simple flooding and caching algorithms to discover available domains inside the darknet. This approach ensures that your internal domain name system is robust, reliable, and independent of external control, enhancing the resilience and security of your infrastructure.
Current DNS implementations are distributed but not truly decentralized. For
Clan-Core, we implemented our own truly decentralized DNS module. This module
uses simple flooding and caching algorithms to discover available domains inside
the darknet. This approach ensures that your internal domain name system is
robust, reliable, and independent of external control, enhancing the resilience
and security of your infrastructure.
### A New Era of Decentralized Self-Hosting
Clan-Core is more than just a tool; it's a paradigm shift in server management. By consolidating machine definitions, secrets and network configuration, into a single, secure repository, it transforms how you manage and scale your infrastructure. Whether you're a seasoned server admin or a self-hosting enthusiast, Clan-Core offers a powerful, user-friendly solution to take your capabilities to the next level.
Clan-Core is more than just a tool; it's a paradigm shift in server management.
By consolidating machine definitions, secrets and network configuration, into a
single, secure repository, it transforms how you manage and scale your
infrastructure. Whether you're a seasoned server admin or a self-hosting
enthusiast, Clan-Core offers a powerful, user-friendly solution to take your
capabilities to the next level.
### Key Features of Clan-Core:
- **Unified Git Repository**: All machine configurations and secrets stored in a single repository.
- **Live Overwrites**: Deploy configurations over existing Linux distributions via SSH.
- **Automated Service Setup**: Easily set up services with Clan-Core's Module system.
- **Decentralized Mesh VPN**: Securely interconnect all machines into a private darknet.
- **Decentralized DNS**: Robust, independent DNS using flooding and caching algorithms.
- **Automated Secret Management**: Encrypted secrets that are automatically decrypted during deployment.
- **Unified Git Repository**: All machine configurations and secrets stored in a
single repository.
- **Live Overwrites**: Deploy configurations over existing Linux distributions
via SSH.
- **Automated Service Setup**: Easily set up services with Clan-Core's Module
system.
- **Decentralized Mesh VPN**: Securely interconnect all machines into a private
darknet.
- **Decentralized DNS**: Robust, independent DNS using flooding and caching
algorithms.
- **Automated Secret Management**: Encrypted secrets that are automatically
decrypted during deployment.
- **Collaboration Support**: Share secrets securely with other admins.
## Clan-Cores Future
Our vision for Clan-Core extends far beyond being just another deployment tool. Clan-Core is a framework we've developed to achieve something much greater. We want to put the "personal" back into "personal computing." Our goal is for everyday users to fully customize their phones or laptops and create truly private spaces for friends and family.
Our first major step is to develop a Graphical User Interface (GUI) that makes configuring all this possible. Initial tests have shown that AI can be leveraged as an alternative to traditional GUIs. This paves the way for a future where people can simply talk to their computers, and they will configure themselves according to the users' wishes.
By adopting Clan, you're not just embracing a tool—you're joining a movement towards a more efficient, secure, and scalable approach to server management. Join us and revolutionize your IT infrastructure today.
Our vision for Clan-Core extends far beyond being just another deployment tool.
Clan-Core is a framework we've developed to achieve something much greater. We
want to put the "personal" back into "personal computing." Our goal is for
everyday users to fully customize their phones or laptops and create truly
private spaces for friends and family.
Our first major step is to develop a Graphical User Interface (GUI) that makes
configuring all this possible. Initial tests have shown that AI can be leveraged
as an alternative to traditional GUIs. This paves the way for a future where
people can simply talk to their computers, and they will configure themselves
according to the users' wishes.
By adopting Clan, you're not just embracing a tool—you're joining a movement
towards a more efficient, secure, and scalable approach to server management.
Join us and revolutionize your IT infrastructure today.

View File

@ -1,6 +1,7 @@
# Hardware Installation
For installations on physical hardware, create a NixOS installer image and transfer it to a bootable USB drive as described below.
For installations on physical hardware, create a NixOS installer image and
transfer it to a bootable USB drive as described below.
## Creating a Bootable USB Drive on Linux
@ -26,40 +27,42 @@ curl -L https://github.com/nix-community/nixos-images/releases/download/nixos-un
2. Identify your flash drive with `lsblk`.
```shellSession
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sdb 8:0 1 117,2G 0 disk
└─sdb1 8:1 1 117,2G 0 part /run/media/qubasa/INTENSO
nvme0n1 259:0 0 1,8T 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot
└─nvme0n1p2 259:2 0 1,8T 0 part
└─luks-f7600028-9d83-4967-84bc-dd2f498bc486 254:0 0 1,8T 0 crypt /nix/store
```
```shellSession
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sdb 8:0 1 117,2G 0 disk
└─sdb1 8:1 1 117,2G 0 part /run/media/qubasa/INTENSO
nvme0n1 259:0 0 1,8T 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot
└─nvme0n1p2 259:2 0 1,8T 0 part
└─luks-f7600028-9d83-4967-84bc-dd2f498bc486 254:0 0 1,8T 0 crypt /nix/store
```
In this case it's `sdb`
In this case it's `sdb`
3. Ensure all partitions on the drive are unmounted. Replace `sdX` in the command below with your device identifier (like `sdb`, etc.):
3. Ensure all partitions on the drive are unmounted. Replace `sdX` in the
command below with your device identifier (like `sdb`, etc.):
```shellSession
sudo umount /dev/sdb1
```
```shellSession
sudo umount /dev/sdb1
```
### Write the Image to the USB Drive
Use the `dd` utility to write the NixOS installer image to your USB drive:
```shellSession
sudo dd bs=4M conv=fsync oflag=direct status=progress if=./nixos-installer-x86_64-linux.iso of=/dev/sd<X>
```
```shellSession
sudo dd bs=4M conv=fsync oflag=direct status=progress if=./nixos-installer-x86_64-linux.iso of=/dev/sd<X>
```
In this case, the USB device is `sdb` use `of=/dev/sdb`
In this case, the USB device is `sdb` use `of=/dev/sdb`
### Boot and Connect
After writing the installer to the USB drive, use it to boot the target machine.
1. For this secure boot needs to be disabled. Go into your UEFI / Bios settings by pressing one of the keys outlined below while booting:
1. For this secure boot needs to be disabled. Go into your UEFI / Bios settings
by pressing one of the keys outlined below while booting:
- **Dell**: F2/Del (BIOS Setup)
- **HP**: Esc (Startup Menu)
@ -71,9 +74,11 @@ After writing the installer to the USB drive, use it to boot the target machine.
- **Samsung**: F2 (BIOS Setup)
- **MSI**: Del (BIOS Setup)
- **Apple**: Option (Alt) Key (Boot Menu for Mac)
- If your hardware was not listed read the manufacturers instructions how to enter the boot Menu/BIOS Setup.
- If your hardware was not listed read the manufacturers instructions how to
enter the boot Menu/BIOS Setup.
2. Inside the UEFI/Bios Menu go to `Security->Secure Boot` and disable secure boot
2. Inside the UEFI/Bios Menu go to `Security->Secure Boot` and disable secure
boot
3. Save your settings. Put in the USB stick and reboot.
@ -91,43 +96,46 @@ After writing the installer to the USB drive, use it to boot the target machine.
- **Apple**: Option (Alt) Key (Boot Menu for Mac)
- If your hardware was not listed read the manufacturers instructions how to enter the boot Menu/BIOS Setup.
5. Select `NixOS` to boot into the clan installer
6. The installer will display an IP address and a root password, which you can use to connect via SSH.
Alternatively you can also use the displayed QR code.
6. The installer will display an IP address and a root password, which you can
use to connect via SSH.\
Alternatively you can also use the displayed QR code.
7. Set your keyboard language (i.e. `de` for German keyboards, default is English). Important for writing passwords correctly.
7. Set your keyboard language (i.e. `de` for German keyboards, default is
English). Important for writing passwords correctly.
```shellSession
loadkeys de
```
```shellSession
loadkeys de
```
8. If you only have Wifi available, execute:
1. Bring up the `iwd` shell
1. Bring up the `iwd` shell
```shellSession
iwctl
```
```shellSession
iwctl
```
2. List available networks. Double press tab after station for autocompleting your wlan device. In this case `wlan0`
2. List available networks. Double press tab after station for autocompleting
your wlan device. In this case `wlan0`
```shellSession
[iwd] station wlan0 get-networks
```
```shellSession
[iwd] station wlan0 get-networks
```
3. Connect to a Wifi network. Replace `SSID` with the wlan network name.
3. Connect to a Wifi network. Replace `SSID` with the wlan network name.
```shellSession
[iwd] station wlan0 connect SSID
```
```shellSession
[iwd] station wlan0 connect SSID
```
9. Now that you have internet re-execute the init script by pressing `Ctrl+D` or by executing:
9. Now that you have internet re-execute the init script by pressing `Ctrl+D` or
by executing:
```shellSession
bash
```
```shellSession
bash
```
10. Connect to the machine over ssh

View File

@ -4,11 +4,11 @@
```bash
clan secrets set mysecret
> Paste your secret:
> Paste your secret:
```
!!! note
As you type your secret won't be displayed. Press Enter to save the secret.
!!! note As you type your secret won't be displayed. Press Enter to save the
secret.
#### List all Secrets (list)
@ -18,7 +18,8 @@ clan secrets list
#### Assigning Access (set)
By default, secrets are encrypted for your key. To specify which users and machines can access a secret:
By default, secrets are encrypted for your key. To specify which users and
machines can access a secret:
```bash
clan secrets set --machine <machine1> --machine <machine2> --user <user1> --user <user2> <secret_name>
@ -54,13 +55,12 @@ Lists all added users
clan secrets user list
```
``` {.console, title="Example output", .no-copy}
```{.console, title="Example output", .no-copy}
jon
sara
```
!!! Question "Who can execute this command?"
Everyone - completely public.
!!! Question "Who can execute this command?" Everyone - completely public.
#### add user
@ -70,8 +70,7 @@ add a user
clan secrets users add {username} {public-key}
```
!!! Note
Changes can be trusted by maintainer review in version control.
!!! Note Changes can be trusted by maintainer review in version control.
#### get user
@ -81,7 +80,7 @@ get a user public key
clan secrets users get {username}
```
``` {.console, title="Example output", .no-copy}
```{.console, title="Example output", .no-copy}
age1zk8uzrte55wkg9lkqxu5x6twsj2ja4lehegks0cw4mkg6jv37d9qsjpt44
```
@ -93,8 +92,7 @@ remove a user
clan secrets users remove {username}
```
!!! Note
Changes can be trusted by maintainer review in version control.
!!! Note Changes can be trusted by maintainer review in version control.
#### add-secret user
@ -104,15 +102,15 @@ Grants the user (`username`) access to the secret (`secret_name`)
clan secrets users add-secret {username} {secret_name}
```
!!! Note
Requires the executor of the command to have access to the secret (`secret_name`).
!!! Note Requires the executor of the command to have access to the secret
(`secret_name`).
#### remove-secret user
remove the user (`username`) from accessing the secret (`secret_name`)
!!! Danger "Make sure at least one person has access."
It might still be possible for the machine to access the secret. (See [machines](#machines))
!!! Danger "Make sure at least one person has access." It might still be
possible for the machine to access the secret. (See [machines](#machines))
We highly recommend to use version control such as `git` which allows you to rollback secrets in case anything gets messed up.
@ -120,8 +118,8 @@ remove the user (`username`) from accessing the secret (`secret_name`)
clan secrets users remove-secret {username} {secret_name}
```
!!! Question "Who can execute this command?"
Requires the executor of the command to have access to the secret (`secret_name`).
!!! Question "Who can execute this command?" Requires the executor of the
command to have access to the secret (`secret_name`).
### Machines (Reference)
@ -134,7 +132,8 @@ clan secrets users remove-secret {username} {secret_name}
#### List machine
New machines in Clan come with age keys stored in `./sops/machines/<machine_name>`. To list these machines:
New machines in Clan come with age keys stored in
`./sops/machines/<machine_name>`. To list these machines:
```bash
clan secrets machines list
@ -142,13 +141,15 @@ clan secrets machines list
#### Add machine
For clan machines the machine key is generated automatically on demand if none exists.
For clan machines the machine key is generated automatically on demand if none
exists.
```bash
clan secrets machines add <machine_name> <age_key>
```
If you already have a device key and want to add it manually, see: [How to obtain a remote key](#obtain-remote-keys-manually)
If you already have a device key and want to add it manually, see:
[How to obtain a remote key](#obtain-remote-keys-manually)
#### get machine
@ -192,8 +193,7 @@ Assign users to a new group, e.g., `admins`:
clan secrets groups add-user admins <username>
```
!!! info
The group is created if no such group existed before.
!!! info The group is created if no such group existed before.
The user must exist in beforehand (See: [users](#users-reference))
@ -234,7 +234,8 @@ TODO
- [generate]() generate age key
- [show]() show age public key
- [update]() re-encrypt all secrets with current keys (useful when changing keys)
- [update]() re-encrypt all secrets with current keys (useful when changing
keys)
#### generate
@ -261,7 +262,8 @@ sops/
│ └── <your_username>/
```
The content of the secret is stored encrypted inside the `secret` file under `mysecret`.
The content of the secret is stored encrypted inside the `secret` file under
`mysecret`.
By default, secrets are encrypted with your key to ensure readability.
@ -273,8 +275,8 @@ To fetch a **SSH host key** from a preinstalled system:
ssh-keyscan <domain_name> | nix shell nixpkgs#ssh-to-age -c ssh-to-age
```
!!! Success
This command converts the SSH key into an age key on the fly. Since this is the format used by the clan secrets backend.
!!! Success This command converts the SSH key into an age key on the fly. Since
this is the format used by the clan secrets backend.
Once added the **SSH host key** enables seamless integration of existing machines with clan.
@ -290,8 +292,10 @@ See also: [Machine reference](#machines-reference)
A NixOS machine will automatically import all secrets that are encrypted for the
current machine. At runtime it will use the host key to decrypt all secrets into
an in-memory, non-persistent filesystem using [sops-nix](https://github.com/Mic92/sops-nix).
In your nixos configuration you can get a path to secrets like this `config.sops.secrets.<name>.path`. For example:
an in-memory, non-persistent filesystem using
[sops-nix](https://github.com/Mic92/sops-nix). In your nixos configuration you
can get a path to secrets like this `config.sops.secrets.<name>.path`. For
example:
```nix
{ config, ...}: {
@ -309,16 +313,23 @@ examples.
### Migration: Importing existing sops-based keys / sops-nix
`clan secrets` stores each secret in a single file, whereas [sops](https://github.com/Mic92/sops-nix) commonly allows to put all secrets in a yaml or json document.
`clan secrets` stores each secret in a single file, whereas
[sops](https://github.com/Mic92/sops-nix) commonly allows to put all secrets in
a yaml or json document.
If you already happened to use sops-nix, you can migrate by using the `clan secrets import-sops` command by importing these files:
If you already happened to use sops-nix, you can migrate by using the
`clan secrets import-sops` command by importing these files:
```bash
% clan secrets import-sops --prefix matchbox- --group admins --machine matchbox nixos/matchbox/secrets/secrets.yaml
```
This will create secrets for each secret found in `nixos/matchbox/secrets/secrets.yaml` in a `./sops` folder of your repository.
Each member of the group `admins` in this case will be able to decrypt the secrets with their respective key.
This will create secrets for each secret found in
`nixos/matchbox/secrets/secrets.yaml` in a `./sops` folder of your repository.
Each member of the group `admins` in this case will be able to decrypt the
secrets with their respective key.
Since our clan secret module will auto-import secrets that are encrypted for a particular nixos machine,
you can now remove `sops.secrets.<secrets> = { };` unless you need to specify more options for the secret like owner/group of the secret file.
Since our clan secret module will auto-import secrets that are encrypted for a
particular nixos machine, you can now remove `sops.secrets.<secrets> = { };`
unless you need to specify more options for the secret like owner/group of the
secret file.

View File

@ -2,23 +2,27 @@
## Introduction to Backups
When you're managing your own services, creating regular backups is crucial to ensure your data's safety.
This guide introduces you to Clan's built-in backup functionalities.
Clan supports backing up your data to both local storage devices (like USB drives) and remote servers, using well-known tools like borgbackup and rsnapshot.
We might add more options in the future, but for now, let's dive into how you can secure your data.
When you're managing your own services, creating regular backups is crucial to
ensure your data's safety. This guide introduces you to Clan's built-in backup
functionalities. Clan supports backing up your data to both local storage
devices (like USB drives) and remote servers, using well-known tools like
borgbackup and rsnapshot. We might add more options in the future, but for now,
let's dive into how you can secure your data.
## Backing Up Locally with Localbackup
### What is Localbackup?
Localbackup lets you backup your data onto physical storage devices connected to your computer,
such as USB hard drives or network-attached storage. It uses a tool called rsnapshot for this purpose.
Localbackup lets you backup your data onto physical storage devices connected to
your computer, such as USB hard drives or network-attached storage. It uses a
tool called rsnapshot for this purpose.
### Setting Up Localbackup
1. **Identify Your Backup Device:**
First, figure out which device you'll use for backups. You can see all connected devices by running this command in your terminal:
First, figure out which device you'll use for backups. You can see all connected
devices by running this command in your terminal:
```bash
lsblk --output NAME,PTUUID,FSTYPE,SIZE,MOUNTPOINT
@ -29,7 +33,8 @@ Look for the device you intend to use for backups and note its details.
2. **Configure Your Backup Device:**
Once you've identified your device, you'll need to add it to your configuration.
Here's an example NixOS configuration for a device located at `/dev/sda2` with an `ext4` filesystem:
Here's an example NixOS configuration for a device located at `/dev/sda2` with
an `ext4` filesystem:
```nix
{
@ -41,9 +46,11 @@ Here's an example NixOS configuration for a device located at `/dev/sda2` with a
}
```
Replace `/dev/sda2` with your device and `/mnt/hdd` with your preferred mount point.
Replace `/dev/sda2` with your device and `/mnt/hdd` with your preferred mount
point.
3. **Set Backup Targets:** Next, define where on your device you'd like the backups to be stored:
3. **Set Backup Targets:** Next, define where on your device you'd like the
backups to be stored:
```nix
{
@ -66,22 +73,23 @@ Replace `/dev/sda2` with your device and `/mnt/hdd` with your preferred mount po
5. **Listing Backups:** To see available backups, run:
```bash
clan backups list mymachine
```
```bash
clan backups list mymachine
```
## Remote Backups with Borgbackup
### Overview of Borgbackup
Borgbackup splits the backup process into two parts: a backup client that sends data to a backup server.
The server stores the backups.
Borgbackup splits the backup process into two parts: a backup client that sends
data to a backup server. The server stores the backups.
### Setting Up the Borgbackup Client
1. **Specify Backup Server:**
Start by indicating where your backup data should be sent. Replace `hostname` with your server's address:
Start by indicating where your backup data should be sent. Replace `hostname`
with your server's address:
```nix
{
@ -95,7 +103,8 @@ Start by indicating where your backup data should be sent. Replace `hostname` wi
2. **Select Folders to Backup:**
Decide which folders you want to back up. For example, to backup your home and root directories:
Decide which folders you want to back up. For example, to backup your home and
root directories:
```nix
{ clan.core.state.userdata.folders = [ "/home" "/root" ]; }
@ -103,13 +112,15 @@ Decide which folders you want to back up. For example, to backup your home and r
3. **Generate Backup Credentials:**
Run `clan facts generate <yourmachine>` to prepare your machine for backup, creating necessary SSH keys and credentials.
Run `clan facts generate <yourmachine>` to prepare your machine for backup,
creating necessary SSH keys and credentials.
### Setting Up the Borgbackup Server
1. **Configure Backup Repository:**
On the server where backups will be stored, enable the SSH daemon and set up a repository for each client:
On the server where backups will be stored, enable the SSH daemon and set up a
repository for each client:
```nix
{
@ -124,13 +135,15 @@ On the server where backups will be stored, enable the SSH daemon and set up a r
Ensure the path to the public key is correct.
2. **Update Your Systems:** Apply your changes by running `clan machines update` to both the server and your client
2. **Update Your Systems:** Apply your changes by running `clan machines update`
to both the server and your client
### Managing Backups
- **Scheduled Backups:**
Backups are automatically performed nightly. To check the next scheduled backup, use:
Backups are automatically performed nightly. To check the next scheduled
backup, use:
```bash
systemctl list-timers | grep -E 'NEXT|borg'

View File

@ -50,30 +50,31 @@ Adding or configuring a new machine requires two simple steps:
1. Find the remote disk id by executing:
```bash title="setup computer"
ssh root@flash-installer.local lsblk --output NAME,ID-LINK,FSTYPE,SIZE,MOUNTPOINT
```
```bash title="setup computer"
ssh root@flash-installer.local lsblk --output NAME,ID-LINK,FSTYPE,SIZE,MOUNTPOINT
```
!!! Note
Replace `flash-installer.local` with the IP address of the machine if you don't have the avahi service running which resolves mDNS local domains.
!!! Note Replace `flash-installer.local` with the IP address of the machine
if you don't have the avahi service running which resolves mDNS local
domains.
Which should show something like:
Which should show something like:
```{.shellSession hl_lines="6" .no-copy}
NAME ID-LINK FSTYPE SIZE MOUNTPOINT
sda usb-ST_16GB_AA6271026J1000000509-0:0 14.9G
├─sda1 usb-ST_16GB_AA6271026J1000000509-0:0-part1 1M
├─sda2 usb-ST_16GB_AA6271026J1000000509-0:0-part2 vfat 100M /boot
└─sda3 usb-ST_16GB_AA6271026J1000000509-0:0-part3 ext4 2.9G /
nvme0n1 nvme-eui.e8238fa6bf530001001b448b4aec2929 476.9G
├─nvme0n1p1 nvme-eui.e8238fa6bf530001001b448b4aec2929-part1 vfat 512M
├─nvme0n1p2 nvme-eui.e8238fa6bf530001001b448b4aec2929-part2 ext4 459.6G
└─nvme0n1p3 nvme-eui.e8238fa6bf530001001b448b4aec2929-part3 swap 16.8G
```
```{.shellSession hl_lines="6" .no-copy}
NAME ID-LINK FSTYPE SIZE MOUNTPOINT
sda usb-ST_16GB_AA6271026J1000000509-0:0 14.9G
├─sda1 usb-ST_16GB_AA6271026J1000000509-0:0-part1 1M
├─sda2 usb-ST_16GB_AA6271026J1000000509-0:0-part2 vfat 100M /boot
└─sda3 usb-ST_16GB_AA6271026J1000000509-0:0-part3 ext4 2.9G /
nvme0n1 nvme-eui.e8238fa6bf530001001b448b4aec2929 476.9G
├─nvme0n1p1 nvme-eui.e8238fa6bf530001001b448b4aec2929-part1 vfat 512M
├─nvme0n1p2 nvme-eui.e8238fa6bf530001001b448b4aec2929-part2 ext4 459.6G
└─nvme0n1p3 nvme-eui.e8238fa6bf530001001b448b4aec2929-part3 swap 16.8G
```
1. Edit the following fields inside the `flake.nix`
=== "**buildClan**"
=== "**buildClan**"
```nix title="clan-core.lib.buildClan" hl_lines="18 23"
buildClan {
@ -106,7 +107,7 @@ Adding or configuring a new machine requires two simple steps:
}
```
=== "**flakeParts**"
=== "**flakeParts**"
```nix title="clan-core.flakeModules.default" hl_lines="18 23"
clan = {
@ -139,36 +140,40 @@ Adding or configuring a new machine requires two simple steps:
};
```
!!! Info "Replace `__CHANGE_ME__` with the appropriate identifier, such as `nvme-eui.e8238fa6bf530001001b448b4aec2929`"
!!! Info "Replace `__YOUR_SSH_KEY__` with your personal key, like `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILoMI0NC5eT9pHlQExrvR5ASV3iW9+BXwhfchq0smXUJ jon@jon-desktop`"
!!! Info "Replace `__CHANGE_ME__` with the appropriate identifier, such as
`nvme-eui.e8238fa6bf530001001b448b4aec2929`" !!! Info "Replace
`__YOUR_SSH_KEY__` with your personal key, like
`ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILoMI0NC5eT9pHlQExrvR5ASV3iW9+BXwhfchq0smXUJ jon@jon-desktop`"
These steps will allow you to update your machine later.
### Step 2: Detect Drivers
Generate the `hardware-configuration.nix` file for your machine by executing the following command:
Generate the `hardware-configuration.nix` file for your machine by executing the
following command:
```bash
clan machines hw-generate [MACHINE_NAME] [HOSTNAME]
```
replace `[MACHINE_NAME]` with the name of the machine i.e. `jon` and `[HOSTNAME]` with the `ip_adress` or `hostname` of the machine within the network. i.e. `flash-installer.local`
replace `[MACHINE_NAME]` with the name of the machine i.e. `jon` and
`[HOSTNAME]` with the `ip_adress` or `hostname` of the machine within the
network. i.e. `flash-installer.local`
!!! Example
```bash
clan machines hw-generate jon flash-installer.local
```
!!! Example `bash clan machines hw-generate jon flash-installer.local`
This command connects to `flash-installer.local` as `root`, runs `nixos-generate-config` to detect hardware configurations (excluding filesystems), and writes them to `machines/jon/hardware-configuration.nix`.
### Step 3: Custom Disk Formatting
In `./modules/disko.nix`, a simple `ext4` disk partitioning scheme is defined for the Disko module. For more complex disk partitioning setups, refer to the [Disko examples](https://github.com/nix-community/disko/tree/master/example).
In `./modules/disko.nix`, a simple `ext4` disk partitioning scheme is defined
for the Disko module. For more complex disk partitioning setups, refer to the
[Disko examples](https://github.com/nix-community/disko/tree/master/example).
### Step 4: Custom Configuration
Modify `./machines/jon/configuration.nix` to personalize the system settings according to your requirements.
Modify `./machines/jon/configuration.nix` to personalize the system settings
according to your requirements.
### Step 5: Check Configuration
@ -178,13 +183,13 @@ Validate your configuration by running:
nix flake check
```
This command helps ensure that your system configuration is correct and free from errors.
This command helps ensure that your system configuration is correct and free
from errors.
!!! Note
Integrate this step into your [Continuous Integration](https://en.wikipedia.org/wiki/Continuous_integration) workflow to ensure that only valid Nix configurations are merged into your codebase. This practice helps maintain system stability and reduces integration issues.
---
## Whats next?

View File

@ -1,14 +1,19 @@
# Deploy Machine
Integrating a new machine into your Clan environment is an easy yet flexible process, allowing for a straight forward management of multiple NixOS configurations.
Integrating a new machine into your Clan environment is an easy yet flexible
process, allowing for a straight forward management of multiple NixOS
configurations.
We'll walk you through adding a new computer to your Clan.
## Installing a New Machine
Clan CLI, in conjunction with [nixos-anywhere](https://github.com/nix-community/nixos-anywhere), provides a seamless method for installing NixOS on various machines.
Clan CLI, in conjunction with
[nixos-anywhere](https://github.com/nix-community/nixos-anywhere), provides a
seamless method for installing NixOS on various machines.
This process involves preparing a suitable hardware and disk partitioning configuration and ensuring the target machine is accessible via SSH.
This process involves preparing a suitable hardware and disk partitioning
configuration and ensuring the target machine is accessible via SSH.
### Step 0. Prerequisites
@ -35,11 +40,10 @@ This process involves preparing a suitable hardware and disk partitioning config
- Any cloud machine if it is reachable via SSH and supports `kexec`.
### Step 1. Deploy the machine
**Finally deployment time!** Use the following command to build and deploy the image via SSH onto your machine.
**Finally deployment time!** Use the following command to build and deploy the
image via SSH onto your machine.
=== "**Image Installer**"
@ -136,21 +140,20 @@ This process involves preparing a suitable hardware and disk partitioning config
clan machines install [MACHINE] <target_host>
```
If you are using our template `[MACHINE]` would be `jon`
!!! success
Your machine is all set up. 🎉 🚀
!!! success Your machine is all set up. 🎉 🚀
## Update Your Machines
Clan CLI enables you to remotely update your machines over SSH. This requires setting up a target address for each target machine.
Clan CLI enables you to remotely update your machines over SSH. This requires
setting up a target address for each target machine.
### Setting the Target Host
Replace `root@jon` with the actual hostname or IP address of your target machine:
Replace `root@jon` with the actual hostname or IP address of your target
machine:
```{.nix hl_lines="9" .no-copy}
buildClan {
# ...
@ -166,10 +169,8 @@ buildClan {
};
```
!!! warning
The use of `root@` in the target address implies SSH access as the `root` user.
Ensure that the root login is secured and only used when necessary.
!!! warning The use of `root@` in the target address implies SSH access as the
`root` user. Ensure that the root login is secured and only used when necessary.
### Updating Machine Configurations
@ -179,7 +180,8 @@ Execute the following command to update the specified machine:
clan machines update jon
```
You can also update all configured machines simultaneously by omitting the machine name:
You can also update all configured machines simultaneously by omitting the
machine name:
```bash
clan machines update
@ -187,10 +189,9 @@ clan machines update
### Setting a Build Host
If the machine does not have enough resources to run the NixOS evaluation or build itself,
it is also possible to specify a build host instead.
During an update, the cli will ssh into the build host and run `nixos-rebuild` from there.
If the machine does not have enough resources to run the NixOS evaluation or
build itself, it is also possible to specify a build host instead. During an
update, the cli will ssh into the build host and run `nixos-rebuild` from there.
```{.nix hl_lines="5" .no-copy}
buildClan {
@ -205,8 +206,9 @@ buildClan {
### Excluding a machine from `clan machine update`
To exclude machines from being updated when running `clan machines update` without any machines specified,
one can set the `clan.deployment.requireExplicitUpdate` option to true:
To exclude machines from being updated when running `clan machines update`
without any machines specified, one can set the
`clan.deployment.requireExplicitUpdate` option to true:
```{.nix hl_lines="5" .no-copy}
buildClan {
@ -219,7 +221,8 @@ buildClan {
};
```
This is useful for machines that are not always online or are not part of the regular update cycle.
This is useful for machines that are not always online or are not part of the
regular update cycle.
---
@ -228,4 +231,3 @@ This is useful for machines that are not always online or are not part of the re
- [**Mesh VPN**](./mesh-vpn.md): Configuring a secure mesh network.
---

View File

@ -1,12 +1,15 @@
# Clan with `flake-parts`
Clan supports integration with [flake.parts](https://flake.parts/) a tool which allows composing nixos modules in a modular way.
Clan supports integration with [flake.parts](https://flake.parts/) a tool which
allows composing nixos modules in a modular way.
Here's how to set up Clan using `nix flakes` and `flake-parts`.
## 1. Update Your Flake Inputs
To begin, you'll need to add `flake-parts` as a new dependency in your flake's inputs. This is alongside the already existing dependencies, such as `clan-core` and `nixpkgs`. Here's how you can update your `flake.nix` file:
To begin, you'll need to add `flake-parts` as a new dependency in your flake's
inputs. This is alongside the already existing dependencies, such as `clan-core`
and `nixpkgs`. Here's how you can update your `flake.nix` file:
```nix
# flake.nix
@ -28,19 +31,22 @@ inputs = {
## 2. Import Clan-Core Flake Module
After updating your flake inputs, the next step is to import the `clan-core` flake module. This will make the [clan options](https://git.clan.lol/clan/clan-core/src/branch/main/flakeModules/clan.nix) available within `mkFlake`.
After updating your flake inputs, the next step is to import the `clan-core`
flake module. This will make the
[clan options](https://git.clan.lol/clan/clan-core/src/branch/main/flakeModules/clan.nix)
available within `mkFlake`.
```nix
outputs =
inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } (
{
#
imports = [
inputs.clan-core.flakeModules.default
];
}
);
outputs =
inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } (
{
#
imports = [
inputs.clan-core.flakeModules.default
];
}
);
```
### 3. Configure Clan Settings and Define Machines
@ -91,7 +97,8 @@ Below is a guide on how to structure this in your flake.nix:
});
```
For detailed information about configuring `flake-parts` and the available options within Clan,
refer to the Clan module documentation located [here](https://git.clan.lol/clan/clan-core/src/branch/main/flakeModules/clan.nix).
For detailed information about configuring `flake-parts` and the available
options within Clan, refer to the Clan module documentation located
[here](https://git.clan.lol/clan/clan-core/src/branch/main/flakeModules/clan.nix).
---

View File

@ -2,10 +2,12 @@
Our installer image simplifies the process of performing remote installations.
Follow our step-by-step guide to create and transfer this image onto a bootable USB drive.
Follow our step-by-step guide to create and transfer this image onto a bootable
USB drive.
!!! info
If you already have a NixOS machine you can ssh into (in the cloud for example) you can skip this chapter and go directly to [Configure Machines](configure.md).
!!! info If you already have a NixOS machine you can ssh into (in the cloud for
example) you can skip this chapter and go directly to
[Configure Machines](configure.md).
### Step 0. Prerequisites
@ -18,29 +20,30 @@ Follow our step-by-step guide to create and transfer this image onto a bootable
2. Identify your flash drive with `lsblk`:
```shellSession
lsblk
```
```shellSession
lsblk
```
```{.shellSession hl_lines="2" .no-copy}
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sdb 8:0 1 117,2G 0 disk
└─sdb1 8:1 1 117,2G 0 part /run/media/qubasa/INTENSO
nvme0n1 259:0 0 1,8T 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot
└─nvme0n1p2 259:2 0 1,8T 0 part
└─luks-f7600028-9d83-4967-84bc-dd2f498bc486 254:0 0 1,8T 0 crypt /nix/store
```
```{.shellSession hl_lines="2" .no-copy}
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sdb 8:0 1 117,2G 0 disk
└─sdb1 8:1 1 117,2G 0 part /run/media/qubasa/INTENSO
nvme0n1 259:0 0 1,8T 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot
└─nvme0n1p2 259:2 0 1,8T 0 part
└─luks-f7600028-9d83-4967-84bc-dd2f498bc486 254:0 0 1,8T 0 crypt /nix/store
```
!!! Info "In this case the USB device is `sdb`"
!!! Info "In this case the USB device is `sdb`"
3. Ensure all partitions on the drive are unmounted. Replace `sdb1` in the command below with your device identifier (like `sdc1`, etc.):
3. Ensure all partitions on the drive are unmounted. Replace `sdb1` in the
command below with your device identifier (like `sdc1`, etc.):
```shellSession
sudo umount /dev/sdb1
```
=== "**Linux OS**"
### Step 2. Flash Custom Installer
=== "**Linux OS**" ### Step 2. Flash Custom Installer
Using clan flash enables the inclusion of ssh public keys.
It also allows to set language and keymap currently in the installer image.
@ -62,10 +65,7 @@ sudo umount /dev/sdb1
The `clan flash` utility will erase the disk. Make sure to specify the correct device
=== "**Other OS**"
### Step 2. Download Generic Installer
=== "**Other OS**" ### Step 2. Download Generic Installer
```shellSession
wget https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-installer-x86_64-linux.iso
@ -91,21 +91,19 @@ sudo umount /dev/sdb1
After writing the installer to the USB drive, use it to boot the target machine.
!!! info
Plug it into the target machine and select the USB drive as a temporary boot device.
!!! info Plug it into the target machine and select the USB drive as a temporary
boot device.
??? tip "Here you can find the key combinations for selection used by most vendors."
- **Dell**: F12 (Boot Menu), F2/Del (BIOS Setup)
- **HP**: F9 (Boot Menu), Esc (Startup Menu)
- **Lenovo**: F12 (ThinkPad Boot Menu), F2/Fn+F2/Novo Button (IdeaPad Boot Menu/BIOS Setup)
- **Acer**: F12 (Boot Menu), F2/Del (BIOS Setup)
- **Asus**: F8/Esc (Boot Menu), F2/Del (BIOS Setup)
- **Toshiba**: F12/F2 (Boot Menu), Esc then F12 (Alternate Method)
- **Sony**: F11/Assist Button (Boot Menu/Recovery Options)
- **Samsung**: F2/F12/Esc (Boot Menu), F2 (BIOS Setup)
- **MSI**: F11 (Boot Menu), Del (BIOS Setup)
- **Apple**: Option (Alt) Key (Boot Menu for Mac)
- If your hardware was not listed read the manufacturers instructions how to enter the boot Menu/BIOS Setup.
??? tip "Here you can find the key combinations for selection used by most
vendors." - **Dell**: F12 (Boot Menu), F2/Del (BIOS Setup) - **HP**: F9 (Boot
Menu), Esc (Startup Menu) - **Lenovo**: F12 (ThinkPad Boot Menu), F2/Fn+F2/Novo
Button (IdeaPad Boot Menu/BIOS Setup) - **Acer**: F12 (Boot Menu), F2/Del (BIOS
Setup) - **Asus**: F8/Esc (Boot Menu), F2/Del (BIOS Setup) - **Toshiba**: F12/F2
(Boot Menu), Esc then F12 (Alternate Method) - **Sony**: F11/Assist Button (Boot
Menu/Recovery Options) - **Samsung**: F2/F12/Esc (Boot Menu), F2 (BIOS Setup) -
**MSI**: F11 (Boot Menu), Del (BIOS Setup) - **Apple**: Option (Alt) Key (Boot
Menu for Mac) - If your hardware was not listed read the manufacturers
instructions how to enter the boot Menu/BIOS Setup.
**During Boot**
@ -113,12 +111,13 @@ Select `NixOS` to boot into the clan installer.
**After Booting**
For deploying your configuration the machine needs to be connected via LAN (recommended).
For deploying your configuration the machine needs to be connected via LAN
(recommended).
## (Optional) Connect to Wifi
If you don't have access via LAN the Installer offers support for connecting via Wifi.
If you don't have access via LAN the Installer offers support for connecting via
Wifi.
```shellSession
iwctl
@ -159,8 +158,8 @@ IPv4 address 192.168.188.50 (Your new local ip)
Press ++ctrl+d++ to exit `IWD`.
!!! Important
Press ++ctrl+d++ **again** to update the displayed QR code and connection information.
!!! Important Press ++ctrl+d++ **again** to update the displayed QR code and
connection information.
You're all set up

View File

@ -1,13 +1,14 @@
# Mesh VPN
This guide provides detailed instructions for configuring
[ZeroTier VPN](https://zerotier.com) within Clan. Follow the
outlined steps to set up a machine as a VPN controller (`<CONTROLLER>`) and to
include a new machine into the VPN.
[ZeroTier VPN](https://zerotier.com) within Clan. Follow the outlined steps to
set up a machine as a VPN controller (`<CONTROLLER>`) and to include a new
machine into the VPN.
## Concept
By default all machines within one clan are connected via a chosen network technology.
By default all machines within one clan are connected via a chosen network
technology.
```{.no-copy}
Clan
@ -16,13 +17,15 @@ Clan
Node B
```
If you select multiple network technologies at the same time. e.g. (zerotier + yggdrassil)
You must choose one of them as primary network and the machines are always connected via the primary network.
If you select multiple network technologies at the same time. e.g. (zerotier +
yggdrassil) You must choose one of them as primary network and the machines are
always connected via the primary network.
## 1. Set-Up the VPN Controller
The VPN controller is initially essential for providing configuration to new
peers. Once addresses are allocated, the controller's continuous operation is not essential.
peers. Once addresses are allocated, the controller's continuous operation is
not essential.
1. **Designate a Machine**: Label a machine as the VPN controller in the clan,
referred to as `<CONTROLLER>` henceforth in this guide.
@ -44,8 +47,9 @@ peers. Once addresses are allocated, the controller's continuous operation is no
To introduce a new machine to the VPN, adhere to the following steps:
1. **Update Configuration**: On the new machine, incorporate the following to its
configuration, substituting `<CONTROLLER>` with the controller machine name:
1. **Update Configuration**: On the new machine, incorporate the following to
its configuration, substituting `<CONTROLLER>` with the controller machine
name:
```nix
{ config, ... }: {
clan.networking.zerotier.networkId = builtins.readFile (config.clan.core.clanDir + "/machines/<CONTROLLER>/facts/zerotier-network-id");
@ -57,24 +61,15 @@ To introduce a new machine to the VPN, adhere to the following steps:
```
Replace `<NEW_MACHINE>` with the designated new machine name.
!!! Note "For Private Networks"
1. **Retrieve the ZeroTier ID**: On the `new_machine`, execute:
```bash
$ sudo zerotier-cli info
```
Example Output:
```{.console, .no-copy}
200 info d2c71971db 1.12.1 OFFLINE
```
, where `d2c71971db` is the ZeroTier ID.
2. **Authorize the New Machine on the Controller**: On the controller machine,
execute:
```bash
$ sudo zerotier-members allow <ID>
```
Substitute `<ID>` with the ZeroTier ID obtained previously.
!!! Note "For Private Networks" 1. **Retrieve the ZeroTier ID**: On the
`new_machine`, execute: `bash $ sudo zerotier-cli info` Example Output:
`{.console, .no-copy} 200 info d2c71971db 1.12.1 OFFLINE` , where
`d2c71971db` is the ZeroTier ID. 2. **Authorize the New Machine on the
Controller**: On the controller machine, execute:
`bash $ sudo zerotier-members allow <ID>` Substitute `<ID>` with the ZeroTier
ID obtained previously.
2. **Verify Connection**: On the `new_machine`, re-execute:
1. **Verify Connection**: On the `new_machine`, re-execute:
```bash
$ sudo zerotier-cli info
```
@ -83,15 +78,17 @@ To introduce a new machine to the VPN, adhere to the following steps:
200 info d2c71971db 1.12.1 ONLINE
```
!!! success "Congratulations!"
The new machine is now part of the VPN, and the ZeroTier
configuration on NixOS within the Clan project is complete.
!!! success "Congratulations!" The new machine is now part of the VPN, and the
ZeroTier configuration on NixOS within the Clan project is complete.
## Further
Currently you can only use **Zerotier** as networking technology because this is the first network stack we aim to support.
In the future we plan to add additional network technologies like tinc, head/tailscale, yggdrassil and mycelium.
Currently you can only use **Zerotier** as networking technology because this is
the first network stack we aim to support. In the future we plan to add
additional network technologies like tinc, head/tailscale, yggdrassil and
mycelium.
We chose zerotier because in our tests it was a straight forwards solution to bootstrap.
It allows you to selfhost a controller and the controller doesn't need to be globally reachable.
Which made it a good fit for starting the project.
We chose zerotier because in our tests it was a straight forwards solution to
bootstrap. It allows you to selfhost a controller and the controller doesn't
need to be globally reachable. Which made it a good fit for starting the
project.

View File

@ -1,21 +1,26 @@
# Secrets / Facts
Clan enables encryption of secrets (such as passwords & keys) ensuring security and ease-of-use among users.
Clan enables encryption of secrets (such as passwords & keys) ensuring security
and ease-of-use among users.
Clan utilizes the [sops](https://github.com/getsops/sops) format and integrates with [sops-nix](https://github.com/Mic92/sops-nix) on NixOS machines.
Clan utilizes the [sops](https://github.com/getsops/sops) format and integrates
with [sops-nix](https://github.com/Mic92/sops-nix) on NixOS machines.
This guide will walk you through:
- **Creating a Keypair for Your User**: Learn how to generate a keypair for $USER to securely control all secrets.
- **Creating Your First Secret**: Step-by-step instructions on creating your initial secret.
- **Assigning Machine Access to the Secret**: Understand how to grant a machine access to the newly created secret.
- **Creating a Keypair for Your User**: Learn how to generate a keypair for
$USER to securely control all secrets.
- **Creating Your First Secret**: Step-by-step instructions on creating your
initial secret.
- **Assigning Machine Access to the Secret**: Understand how to grant a machine
access to the newly created secret.
## Create Your Admin Keypair
To get started, you'll need to create **Your admin keypair**.
!!! info
Don't worry — if you've already made one before, this step won't change or overwrite it.
!!! info Don't worry — if you've already made one before, this step won't change
or overwrite it.
```bash
clan secrets key generate
@ -30,12 +35,12 @@ Generated age private key at '/home/joerg/.config/sops/age/keys.txt' for your us
Also add your age public key to the repository with 'clan secrets users add YOUR_USER age1wkth7uhpkl555g40t8hjsysr20drq286netu8zptw50lmqz7j95sw2t3l7' (replace YOUR_USER with your actual username)
```
!!! warning
Make sure to keep a safe backup of the private key you've just created.
If it's lost, you won't be able to get to your secrets anymore because they all need the admin key to be unlocked.
!!! warning Make sure to keep a safe backup of the private key you've just
created. If it's lost, you won't be able to get to your secrets anymore because
they all need the admin key to be unlocked.
!!! note
It's safe to add any secrets created by the clan CLI and placed in your repository to version control systems like `git`.
!!! note It's safe to add any secrets created by the clan CLI and placed in your
repository to version control systems like `git`.
### Add Your Public Key
@ -43,7 +48,8 @@ Also add your age public key to the repository with 'clan secrets users add YOUR
clan secrets users add $USER <your_public_key>
```
It's best to choose the same username as on your Setup/Admin Machine that you use to control the deployment with.
It's best to choose the same username as on your Setup/Admin Machine that you
use to control the deployment with.
Once run this will create the following files:
@ -53,7 +59,9 @@ sops/
└── <your_username>/
└── key.json
```
If you followed the quickstart tutorial all necessary secrets are initialized at this point.
If you followed the quickstart tutorial all necessary secrets are initialized at
this point.
---
@ -65,7 +73,8 @@ If you followed the quickstart tutorial all necessary secrets are initialized at
## More on Secrets
If you want to know more about how to save and share passwords in your clan read further!
If you want to know more about how to save and share passwords in your clan read
further!
### Adding a Secret
@ -90,8 +99,10 @@ clan secrets list
A NixOS machine will automatically import all secrets that are encrypted for the
current machine. At runtime it will use the host key to decrypt all secrets into
an in-memory, non-persistent filesystem using [sops-nix](https://github.com/Mic92/sops-nix).
In your nixos configuration you can get a path to secrets like this `config.sops.secrets.<name>.path`. For example:
an in-memory, non-persistent filesystem using
[sops-nix](https://github.com/Mic92/sops-nix). In your nixos configuration you
can get a path to secrets like this `config.sops.secrets.<name>.path`. For
example:
```nix
{ config, ...}: {
@ -106,12 +117,13 @@ In your nixos configuration you can get a path to secrets like this `config.sops
### Assigning Access
When using `clan secrets set <secret>` without arguments, secrets are encrypted for the key of the user named like your current $USER.
When using `clan secrets set <secret>` without arguments, secrets are encrypted
for the key of the user named like your current $USER.
To add machines/users to an existing secret use:
```bash
clan secrets machines add-secret <machine_name> <secret_name>
clan secrets machines add-secret <machine_name> <secret_name>
```
Alternatively specify users and machines while creating a secret:
@ -156,44 +168,50 @@ Here's how to get started:
### Adding Machine Keys
New machines in Clan come with age keys stored in `./sops/machines/<machine_name>`. To list these machines:
New machines in Clan come with age keys stored in
`./sops/machines/<machine_name>`. To list these machines:
```bash
clan secrets machines list
clan secrets machines list
```
For existing machines, add their keys:
```bash
clan secrets machines add <machine_name> <age_key>
clan secrets machines add <machine_name> <age_key>
```
To fetch an age key from an SSH host key:
```bash
ssh-keyscan <domain_name> | nix shell nixpkgs#ssh-to-age -c ssh-to-age
ssh-keyscan <domain_name> | nix shell nixpkgs#ssh-to-age -c ssh-to-age
```
### Migration: Importing existing sops-based keys / sops-nix
`clan secrets` stores each secret in a single file, whereas [sops](https://github.com/Mic92/sops-nix) commonly allows to put all secrets in a yaml or json document.
`clan secrets` stores each secret in a single file, whereas
[sops](https://github.com/Mic92/sops-nix) commonly allows to put all secrets in
a yaml or json document.
If you already happened to use sops-nix, you can migrate by using the `clan secrets import-sops` command by importing these files:
If you already happened to use sops-nix, you can migrate by using the
`clan secrets import-sops` command by importing these files:
```bash
% clan secrets import-sops --prefix matchbox- --group admins --machine matchbox nixos/matchbox/secrets/secrets.yaml
```
This will create secrets for each secret found in `nixos/matchbox/secrets/secrets.yaml` in a `./sops` folder of your repository.
Each member of the group `admins` in this case will be able to decrypt the secrets with their respective key.
Since our clan secret module will auto-import secrets that are encrypted for a particular nixos machine,
you can now remove `sops.secrets.<secrets> = { };` unless you need to specify more options for the secret like owner/group of the secret file.
This will create secrets for each secret found in
`nixos/matchbox/secrets/secrets.yaml` in a `./sops` folder of your repository.
Each member of the group `admins` in this case will be able to decrypt the
secrets with their respective key.
Since our clan secret module will auto-import secrets that are encrypted for a
particular nixos machine, you can now remove `sops.secrets.<secrets> = { };`
unless you need to specify more options for the secret like owner/group of the
secret file.
## Indepth Explanation
The secrets system conceptually knows two different entities:
- **Machine**: consumes secrets
@ -201,37 +219,48 @@ The secrets system conceptually knows two different entities:
**A Users** Can add or revoke machines' access to secrets.
**A machine** Can decrypt secrets that where encrypted specifically for that machine.
**A machine** Can decrypt secrets that where encrypted specifically for that
machine.
!!! Danger
**Always make sure at least one _User_ has access to a secret**. Otherwise you could lock yourself out from accessing the secret.
!!! Danger **Always make sure at least one _User_ has access to a secret**.
Otherwise you could lock yourself out from accessing the secret.
### Inherited implications
By default clan uses [sops](https://github.com/getsops/sops) through [sops-nix](https://github.com/Mic92/sops-nix) for managing its secrets which inherits some implications that are important to understand:
By default clan uses [sops](https://github.com/getsops/sops) through
[sops-nix](https://github.com/Mic92/sops-nix) for managing its secrets which
inherits some implications that are important to understand:
- **Public/Private keys**: Entities are identified via their public keys. Each Entity can use their respective private key to decrypt a secret.
- **Public/Private keys**: Entities are identified via their public keys. Each
Entity can use their respective private key to decrypt a secret.
- **Public keys are stored**: All Public keys are stored inside the repository
- **Secrets are stored Encrypted**: secrets are stored inside the repository encrypted with the respective public keys
- **Secrets are deployed encrypted**: Fully encrypted secrets are deployed to machines at deployment time.
- **Secrets are decrypted by sops on-demand**: Each machine decrypts its secrets at runtime and stores them at an ephemeral location.
- **Machine key-pairs are auto-generated**: When a machine is created **no user-interaction is required** to setup public/private key-pairs.
- **secrets are re-encrypted**: In case machines, users or groups are modified secrets get re-encrypted on demand.
- **Secrets are stored Encrypted**: secrets are stored inside the repository
encrypted with the respective public keys
- **Secrets are deployed encrypted**: Fully encrypted secrets are deployed to
machines at deployment time.
- **Secrets are decrypted by sops on-demand**: Each machine decrypts its secrets
at runtime and stores them at an ephemeral location.
- **Machine key-pairs are auto-generated**: When a machine is created **no
user-interaction is required** to setup public/private key-pairs.
- **secrets are re-encrypted**: In case machines, users or groups are modified
secrets get re-encrypted on demand.
!!! Important
After revoking access to a secret you should also change the underlying secret. i.e. change the API key, or the password.
!!! Important After revoking access to a secret you should also change the
underlying secret. i.e. change the API key, or the password.
---
### Machine and user keys
The following diagrams illustrates how a user can provide a secret (i.e. a Password).
The following diagrams illustrates how a user can provide a secret (i.e. a
Password).
- By using the **Clan CLI** a user encrypts the password with both the **User public-key** and the **machine's public-key**
- By using the **Clan CLI** a user encrypts the password with both the **User
public-key** and the **machine's public-key**
- The *Machine* can decrypt the password with its private-key on demand.
- The _Machine_ can decrypt the password with its private-key on demand.
- The *User* is able to decrypt the password to make changes to it.
- The _User_ is able to decrypt the password to make changes to it.
```plantuml
@startuml
@ -248,14 +277,14 @@ Rel_R(secret, machine, "Decrypt", "", "machine privkey" )
@enduml
```
#### User groups
Here we illustrate how machine groups work.
Common use cases:
- **Shared Management**: Access among multiple users. I.e. a subset of secrets/machines that have two admins
- **Shared Management**: Access among multiple users. I.e. a subset of
secrets/machines that have two admins
```plantuml
@startuml
@ -309,12 +338,9 @@ Rel(secret, c1, "Decrypt", "", "Both machine A or B can decrypt using their priv
<!-- TODO: See also [Groups Reference](#groups-reference) -->
See the [readme](https://github.com/Mic92/sops-nix) of sops-nix for more
examples.
---
## Whats next?

View File

@ -1,6 +1,7 @@
# Setup
Create your own clan with these initial steps and manage a fleet of machines with one single testable git repository!
Create your own clan with these initial steps and manage a fleet of machines
with one single testable git repository!
### Prerequisites
@ -35,9 +36,11 @@ Add the Clan CLI into your development workflow:
nix shell git+https://git.clan.lol/clan/clan-core#clan-cli
```
You can find reference documentation for the `clan` cli program [here](./reference/cli/index.md).
You can find reference documentation for the `clan` cli program
[here](./reference/cli/index.md).
Alternatively you can check out the help pages directly:
```terminalSession
clan --help
```
@ -51,7 +54,8 @@ clan flakes create my-clan
```
This command creates the `flake.nix` and `.clan-flake` files for your project.
It will also generate files from a default template, to help show general clan usage patterns.
It will also generate files from a default template, to help show general clan
usage patterns.
### Step 3: Verify the Project Structure
@ -64,7 +68,7 @@ tree
This should yield the following:
``` { .console .no-copy }
```{ .console .no-copy }
.
├── flake.nix
├── machines
@ -84,7 +88,7 @@ This should yield the following:
clan machines list
```
``` { .console .no-copy }
```{ .console .no-copy }
jon
sara
```
@ -97,6 +101,7 @@ sara
### What's Next?
- [**Installer**](getting-started/installer.md): Setting up new computers remotely is easy with an USB stick.
- [**Installer**](getting-started/installer.md): Setting up new computers
remotely is easy with an USB stick.
---

View File

@ -11,6 +11,7 @@
treefmt.programs.nixfmt.enable = true;
treefmt.programs.nixfmt.package = pkgs.nixfmt-rfc-style;
treefmt.programs.deadnix.enable = true;
treefmt.programs.deno.enable = true;
treefmt.programs.mypy.directories = {
"pkgs/clan-cli".extraPythonPackages = self'.packages.clan-cli.testDependencies;
@ -20,6 +21,7 @@
};
treefmt.programs.ruff.check = true;
treefmt.programs.ruff.format = true;
treefmt.settings.global.excludes = [ "*/sops/*" ];
# FIXME: currently broken in CI
#treefmt.settings.formatter.vale =

View File

@ -1,11 +1,15 @@
# Inventory
The inventory is our concept for distributed services. Users can configure multiple machines with minimal effort.
The inventory is our concept for distributed services. Users can configure
multiple machines with minimal effort.
- The inventory acts as a declarative source of truth for all machine configurations.
- The inventory acts as a declarative source of truth for all machine
configurations.
- Users can easily add or remove machines to/from services.
- Ensures that all machines and services are configured consistently, across multiple nixosConfigs.
- Defaults and predefined roles in our modules minimizes the need for manual configuration.
- Ensures that all machines and services are configured consistently, across
multiple nixosConfigs.
- Defaults and predefined roles in our modules minimizes the need for manual
configuration.
Open questions:
@ -13,13 +17,13 @@ Open questions:
- It must be accessible from Python.
- It must set the value in the module system.
- [ ] Inventory might use assertions. Should each machine inherit the inventory assertions ?
- [ ] Inventory might use assertions. Should each machine inherit the inventory
assertions ?
- [ ] Is the service config interface the same as the module config interface ?
- [ ] As a user do I want to see borgbackup as the high level category?
Architecture
```
@ -61,7 +65,8 @@ Comments are rendered as descriptions in the json schema.
name: string
```
Cue open sets. In the following `foo = {...}` means that the key `foo` can contain any arbitrary json object.
Cue open sets. In the following `foo = {...}` means that the key `foo` can
contain any arbitrary json object.
```cue
foo: { ... }
@ -79,12 +84,12 @@ This is the schema of
```json
{
"a": {
"attr": "foo"
},
"b": {
"attr": "bar"
}
// ... Indefinitely more dynamic keys of type "string"
"a": {
"attr": "foo"
},
"b": {
"attr": "bar"
}
// ... Indefinitely more dynamic keys of type "string"
}
```

View File

@ -1,6 +1,7 @@
# clan app
Provides users with the simple functionality to manage their locally registered clans.
Provides users with the simple functionality to manage their locally registered
clans.
![app-preview](screenshots/image.png)
@ -52,8 +53,9 @@ PERF=1 ./bin/clan-app
> Note:
>
> we recognized bugs when starting some cli-commands through the integrated vs-code terminal.
> If encountering issues make sure to run commands in a regular os-shell.
> we recognized bugs when starting some cli-commands through the integrated
> vs-code terminal. If encountering issues make sure to run commands in a
> regular os-shell.
lib-Adw has a demo application showing all widgets. You can run it by executing
@ -77,18 +79,34 @@ gtk4-icon-browser
Here are some important documentation links related to the Clan App:
- [Adw PyGobject Reference](http://lazka.github.io/pgi-docs/index.html#Adw-1): This link provides the PyGObject reference documentation for the Adw library, which is used in the Clan App. It contains detailed information about the Adw widgets and their usage.
- [Adw PyGobject Reference](http://lazka.github.io/pgi-docs/index.html#Adw-1):
This link provides the PyGObject reference documentation for the Adw library,
which is used in the Clan App. It contains detailed information about the Adw
widgets and their usage.
- [GTK4 PyGobject Reference](http://lazka.github.io/pgi-docs/index.html#Gtk-4.0): This link provides the PyGObject reference documentation for GTK4, the toolkit used for building the user interface of the clan app. It includes information about GTK4 widgets, signals, and other features.
- [GTK4 PyGobject Reference](http://lazka.github.io/pgi-docs/index.html#Gtk-4.0):
This link provides the PyGObject reference documentation for GTK4, the toolkit
used for building the user interface of the clan app. It includes information
about GTK4 widgets, signals, and other features.
- [Adw Widget Gallery](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/widget-gallery.html): This link showcases a widget gallery for Adw, allowing you to see the available widgets and their visual appearance. It can be helpful for designing the user interface of the clan app.
- [Adw Widget Gallery](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/widget-gallery.html):
This link showcases a widget gallery for Adw, allowing you to see the
available widgets and their visual appearance. It can be helpful for designing
the user interface of the clan app.
- [Python + GTK3 Tutorial](https://python-gtk-3-tutorial.readthedocs.io/en/latest/textview.html): Although the clan app uses GTK4, this tutorial for GTK3 can still be useful as it covers the basics of building GTK-based applications with Python. It includes examples and explanations for various GTK widgets, including text views.
- [Python + GTK3 Tutorial](https://python-gtk-3-tutorial.readthedocs.io/en/latest/textview.html):
Although the clan app uses GTK4, this tutorial for GTK3 can still be useful as
it covers the basics of building GTK-based applications with Python. It
includes examples and explanations for various GTK widgets, including text
views.
- [GNOME Human Interface Guidelines](https://developer.gnome.org/hig/): This link provides the GNOME Human Interface Guidelines, which offer design and usability recommendations for creating GNOME applications. It covers topics such as layout, navigation, and interaction patterns.
- [GNOME Human Interface Guidelines](https://developer.gnome.org/hig/): This
link provides the GNOME Human Interface Guidelines, which offer design and
usability recommendations for creating GNOME applications. It covers topics
such as layout, navigation, and interaction patterns.
## Error handling
> Error dialogs should be avoided where possible, since they are disruptive.
>
> For simple non-critical errors, toasts can be a good alternative.
> For simple non-critical errors, toasts can be a good alternative.

View File

@ -1,7 +1,10 @@
# Webkit GTK doesn't interop flawless with Solid.js build result
1. Webkit expects script tag to be in `body` only solid.js puts the in the head.
2. script and css files are loaded with type="module" and crossorigin tags beeing set. WebKit silently fails to load then.
3. Paths to resiources are not allowed to start with "/" because webkit interprets them relative to the system and not the base url.
4. webkit doesn't support native features such as directly handling external urls (i.e opening them in the default browser)
6. Other problems to be found?
2. script and css files are loaded with type="module" and crossorigin tags
beeing set. WebKit silently fails to load then.
3. Paths to resiources are not allowed to start with "/" because webkit
interprets them relative to the system and not the base url.
4. webkit doesn't support native features such as directly handling external
urls (i.e opening them in the default browser)
5. Other problems to be found?

View File

@ -1,26 +1,24 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Clan Webui",
"type": "python",
"request": "launch",
"module": "clan_cli.webui",
"justMyCode": false,
"args": [ "--reload", "--no-open", "--log-level", "debug" ],
},
{
"name": "Clan Cli VMs",
"type": "python",
"request": "launch",
"module": "clan_cli",
"justMyCode": false,
"args": [ "vms" ],
}
]
}
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Clan Webui",
"type": "python",
"request": "launch",
"module": "clan_cli.webui",
"justMyCode": false,
"args": ["--reload", "--no-open", "--log-level", "debug"]
},
{
"name": "Clan Cli VMs",
"type": "python",
"request": "launch",
"module": "clan_cli",
"justMyCode": false,
"args": ["vms"]
}
]
}

View File

@ -1,22 +1,22 @@
{
"python.testing.pytestArgs": [
// Coverage is not supported by vscode:
// https://github.com/Microsoft/vscode-python/issues/693
// Note that this will make pytest fail if pytest-cov is not installed,
// if that's the case, then this option needs to be be removed (overrides
// can be set at a workspace level, it's up to you to decide what's the
// best approach). You might also prefer to only set this option
// per-workspace (wherever coverage is used).
"--no-cov",
"tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"search.exclude": {
"**/.direnv": true
},
"python.linting.mypyPath": "mypy",
"python.linting.mypyEnabled": true,
"python.linting.enabled": true,
"python.defaultInterpreterPath": "python"
}
"python.testing.pytestArgs": [
// Coverage is not supported by vscode:
// https://github.com/Microsoft/vscode-python/issues/693
// Note that this will make pytest fail if pytest-cov is not installed,
// if that's the case, then this option needs to be be removed (overrides
// can be set at a workspace level, it's up to you to decide what's the
// best approach). You might also prefer to only set this option
// per-workspace (wherever coverage is used).
"--no-cov",
"tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"search.exclude": {
"**/.direnv": true
},
"python.linting.mypyPath": "mypy",
"python.linting.mypyEnabled": true,
"python.linting.enabled": true,
"python.defaultInterpreterPath": "python"
}

View File

@ -4,8 +4,9 @@ The clan-cli contains the command line interface
## Hacking on the cli
We recommend setting up [direnv](https://direnv.net/) to load the developement with nix.
If you do not have it set up you can also use `nix develop` directly like this:
We recommend setting up [direnv](https://direnv.net/) to load the developement
with nix. If you do not have it set up you can also use `nix develop` directly
like this:
```
use flake .#clan-cli --builders ''
@ -19,8 +20,8 @@ After you can use the local bin wrapper to test things in the cli:
## Run locally single-threaded for debugging
By default tests run in parallel using pytest-parallel.
pytest-parallel however breaks `breakpoint()`. To disable it, use this:
By default tests run in parallel using pytest-parallel. pytest-parallel however
breaks `breakpoint()`. To disable it, use this:
```bash
pytest -n0 -s

View File

@ -1,5 +1,7 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"tailwindCSS.experimental.classRegex": [["cx\\(([^)]*)\\)", "[\"'`]([^\"'`]*)[\"'`]"]],
"editor.wordWrap": "on"
"typescript.tsdk": "node_modules/typescript/lib",
"tailwindCSS.experimental.classRegex": [
["cx\\(([^)]*)\\)", "[\"'`]([^\"'`]*)[\"'`]"]
],
"editor.wordWrap": "on"
}

View File

@ -1,8 +1,10 @@
## Usage
Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`.
Those templates dependencies are maintained via [pnpm](https://pnpm.io) via
`pnpm up -Lri`.
This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely be removed once you clone a template.
This is the reason you see a `pnpm-lock.yaml`. That being said, any package
manager will work. This file can be safely be removed once you clone a template.
```bash
$ npm install # or pnpm install or yarn install
@ -16,19 +18,20 @@ In the project directory, you can run:
### `npm run dev` or `npm start`
Runs the app in the development mode.<br>
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
Runs the app in the development mode.<br> Open
[http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.<br>
### `npm run build`
Builds the app for production to the `dist` folder.<br>
It correctly bundles Solid in production mode and optimizes the build for the best performance.
Builds the app for production to the `dist` folder.<br> It correctly bundles
Solid in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.<br>
Your app is ready to be deployed!
The build is minified and the filenames include the hashes.<br> Your app is
ready to be deployed!
## Deployment
You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.)
You can deploy the `dist` folder to any static host provider (netlify, surge,
now, etc.)

View File

@ -43,7 +43,7 @@ fs.readFile(manifestPath, { encoding: "utf8" }, (err, data) => {
console.log(`Rewriting CSS url(): ${asset.url} to ${res}`);
return res;
},
})
}),
)
.process(css, {
from: `dist/${cssEntry}`,

View File

@ -1,4 +1,4 @@
import { createSignal, type Component } from "solid-js";
import { type Component, createSignal } from "solid-js";
import { MachineProvider } from "./Config";
import { Layout } from "./layout/layout";
import { Route, Router } from "./Routes";
@ -8,7 +8,7 @@ import { Toaster } from "solid-toast";
const [route, setRoute] = createSignal<Route>("machines");
const [currClanURI, setCurrClanURI] = createSignal<string>(
"/home/johannes/git/testing/xd"
"/home/johannes/git/testing/xd",
);
export { currClanURI, setCurrClanURI };

View File

@ -1,16 +1,17 @@
import {
createSignal,
createContext,
useContext,
JSXElement,
createEffect,
createSignal,
JSXElement,
useContext,
} from "solid-js";
import { OperationResponse, pyApi } from "./api";
import { currClanURI } from "./App";
export const makeMachineContext = () => {
const [machines, setMachines] =
createSignal<OperationResponse<"list_machines">>();
const [machines, setMachines] = createSignal<
OperationResponse<"list_machines">
>();
const [loading, setLoading] = createSignal(false);
pyApi.list_machines.receive((machines) => {

View File

@ -48,18 +48,17 @@ const obs: ObserverRegistry = operationNames.reduce(
...acc,
[opName]: [],
}),
{} as ObserverRegistry
{} as ObserverRegistry,
);
interface ReceiveOptions {
/**
* Calls only the registered function that has the same key as used with dispatch
*
*/
fnKey: string;
}
function createFunctions<K extends OperationNames>(
operationName: K
operationName: K,
): {
dispatch: (args: OperationArgs<K>) => void;
receive: (fn: (response: OperationResponse<K>) => void) => void;
@ -76,7 +75,7 @@ function createFunctions<K extends OperationNames>(
});
},
receive: (
fn: (response: OperationResponse<K>) => void
fn: (response: OperationResponse<K>) => void,
// options?: ReceiveOptions
) => {
obs[operationName].push(fn);
@ -94,16 +93,14 @@ type PyApi = {
};
};
const deserialize =
<T>(fn: (response: T) => void) =>
(str: string) => {
try {
fn(JSON.parse(str) as T);
} catch (e) {
console.error(str);
alert(`Error parsing JSON: ${e}`);
}
};
const deserialize = <T>(fn: (response: T) => void) => (str: string) => {
try {
fn(JSON.parse(str) as T);
} catch (e) {
console.error(str);
alert(`Error parsing JSON: ${e}`);
}
};
// Create the API object

View File

@ -1,5 +1,5 @@
import { Match, Show, Switch, createSignal } from "solid-js";
import { ErrorData, SuccessData, pyApi } from "../api";
import { createSignal, Match, Show, Switch } from "solid-js";
import { ErrorData, pyApi, SuccessData } from "../api";
import { currClanURI } from "../App";
type MachineDetails = SuccessData<"list_machines">["data"][string];

View File

@ -10,7 +10,7 @@ window.clan = window.clan || {};
if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
throw new Error(
"Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?"
"Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?",
);
}

View File

@ -26,7 +26,8 @@ export const Layout: Component<LayoutProps> = (props) => {
for="toplevel-drawer"
aria-label="close sidebar"
class="drawer-overlay"
></label>
>
</label>
<Sidebar route={route} setRoute={setRoute} />
</div>
</div>

View File

@ -1,6 +1,6 @@
import { route } from "@/src/App";
import { OperationResponse, pyApi } from "@/src/api";
import { Component, For, Show, createEffect, createSignal } from "solid-js";
import { Component, createEffect, createSignal, For, Show } from "solid-js";
type DevicesModel = Extract<
OperationResponse<"show_block_devices">,

View File

@ -1,18 +1,18 @@
import { OperationResponse, pyApi } from "@/src/api";
import {
createEffect,
createSignal,
For,
JSX,
Match,
Show,
Switch,
createEffect,
createSignal,
} from "solid-js";
import {
SubmitHandler,
createForm,
email,
required,
SubmitHandler,
} from "@modular-forms/solid";
interface ClanDetailsProps {
@ -172,9 +172,9 @@ export const ClanDetails = (props: ClanDetailsProps) => {
const [loading, setLoading] = createSignal(false);
const [errors, setErrors] = createSignal<
| Extract<
OperationResponse<"show_clan_meta">,
{ status: "error" }
>["errors"]
OperationResponse<"show_clan_meta">,
{ status: "error" }
>["errors"]
| null
>(null);
const [data, setData] = createSignal<ClanMeta>();

View File

@ -1,5 +1,5 @@
import { pyApi } from "@/src/api";
import { Match, Switch, createEffect, createSignal } from "solid-js";
import { createEffect, createSignal, Match, Switch } from "solid-js";
import toast from "solid-toast";
import { ClanDetails, ClanForm } from "./clanDetails";
@ -56,9 +56,7 @@ export const clan = () => {
<ClanForm
actions={
<div class="card-actions justify-end">
<button
class="btn btn-primary"
// onClick={() => {
<button class="btn btn-primary" // onClick={() => {
// pyApi.open_file.dispatch({
// file_request: { mode: "save" },
// });

View File

@ -1,9 +1,9 @@
import {
For,
Show,
type Component,
createEffect,
createSignal,
type Component,
For,
Show,
} from "solid-js";
import { route } from "@/src/App";
import { OperationResponse, pyApi } from "@/src/api";

View File

@ -1,11 +1,11 @@
import {
type Component,
createEffect,
createSignal,
For,
Match,
Show,
Switch,
createEffect,
createSignal,
type Component,
} from "solid-js";
import { useMachineContext } from "../../Config";
import { route } from "@/src/App";
@ -69,7 +69,7 @@ export const MachineListView: Component = () => {
toast.error("Error loading machines");
response.errors.forEach((error) =>
toast.error(
`${error.message}: ${error.description} From ${error.location}`
`${error.message}: ${error.description} From ${error.location}`,
)
);
}
@ -86,8 +86,7 @@ export const MachineListView: Component = () => {
title: "Open Clan",
mode: "select_folder",
},
})
}
})}
>
<span class="material-icons ">folder_open</span>
</button>

View File

@ -1,4 +1,4 @@
import { describe, it, expectTypeOf } from "vitest";
import { describe, expectTypeOf, it } from "vitest";
import { OperationNames, pyApi } from "@/src/api";
@ -44,13 +44,13 @@ describe.concurrent("API types work properly", () => {
.parameter(0)
.toMatchTypeOf<
| {
status: "success";
data: {
machine_name: string;
machine_icon?: string | null;
machine_description?: string | null;
};
}
status: "success";
data: {
machine_name: string;
machine_icon?: string | null;
machine_description?: string | null;
};
}
| { status: "error"; errors: any }
>();
});

View File

@ -14,6 +14,7 @@
"allowJs": true,
"isolatedModules": true,
"paths": {
"@/*": ["./*"]}
},
"@/*": ["./*"]
}
}
}