Compare commits
No commits in common. "main" and "auto-modules" have entirely different histories.
main
...
auto-modul
|
@ -20,8 +20,41 @@ indent_style = unset
|
||||||
indent_size = unset
|
indent_size = unset
|
||||||
|
|
||||||
[{.*,secrets}/**]
|
[{.*,secrets}/**]
|
||||||
end_of_line = false
|
end_of_line = unset
|
||||||
insert_final_newline = false
|
insert_final_newline = unset
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
charset = unset
|
||||||
|
indent_style = unset
|
||||||
|
indent_size = unset
|
||||||
|
|
||||||
|
[*.rom]
|
||||||
|
end_of_line = unset
|
||||||
|
insert_final_newline = unset
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
charset = unset
|
||||||
|
indent_style = unset
|
||||||
|
indent_size = unset
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
max_line_length = off
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
# Ignore diffs/patches
|
||||||
|
[*.{diff,patch}]
|
||||||
|
end_of_line = unset
|
||||||
|
insert_final_newline = unset
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
indent_size = unset
|
||||||
|
charset = unset
|
||||||
|
indent_style = unset
|
||||||
|
indent_size = unset
|
||||||
|
|
||||||
|
[{.*,secrets}/**]
|
||||||
|
end_of_line = unset
|
||||||
|
insert_final_newline = unset
|
||||||
trim_trailing_whitespace = unset
|
trim_trailing_whitespace = unset
|
||||||
charset = unset
|
charset = unset
|
||||||
indent_style = unset
|
indent_style = unset
|
||||||
|
|
|
@ -1,37 +1,71 @@
|
||||||
name: Flake checks
|
name: Flake checks
|
||||||
on: [pull_request]
|
on: [pull_request]
|
||||||
|
env:
|
||||||
|
USER: ci
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Check:
|
Check:
|
||||||
runs-on: self-hosted
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
uses: https://code.forgejo.org/actions/checkout@v4
|
uses: https://code.forgejo.org/actions/checkout@v4
|
||||||
|
|
||||||
- name: Check formatting
|
- uses: https://github.com/nixbuild/nix-quick-install-action@v27
|
||||||
|
with:
|
||||||
|
load_nixConfig: false
|
||||||
|
nix_conf: |
|
||||||
|
substituters = https://cache.nixos.org/ https://nix-community.cachix.org
|
||||||
|
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
|
||||||
|
keep-outputs = true
|
||||||
|
|
||||||
|
- name: Calculate flake.lock hash
|
||||||
|
id: flake-lock-hash
|
||||||
run: |
|
run: |
|
||||||
nix --accept-flake-config --access-tokens '' develop --command treefmt --ci
|
echo "hash=$(md5sum flake.lock | awk '{print $1}')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Restore and cache Nix store
|
||||||
|
uses: https://github.com/nix-community/cache-nix-action@v4.0.3
|
||||||
|
id: nix-store-cache
|
||||||
|
with:
|
||||||
|
key: cache-${{ runner.os }}-nix-store-${{ steps.flake-lock-hash.outputs.hash }}
|
||||||
|
restore-keys: |
|
||||||
|
cache-${{ runner.os }}-nix-store-
|
||||||
|
|
||||||
|
gc-linux: true
|
||||||
|
gc-max-store-size-linux: 10000000000
|
||||||
|
|
||||||
|
purge-caches: true
|
||||||
|
purge-key: cache-${{ runner.os }}-nix-store-
|
||||||
|
purge-created: true
|
||||||
|
purge-created-max-age: 42
|
||||||
|
|
||||||
|
- name: Prepare cachix
|
||||||
|
uses: https://github.com/cachix/cachix-action@v14
|
||||||
|
with:
|
||||||
|
name: pub-solar
|
||||||
|
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||||
|
useDaemon: false
|
||||||
|
|
||||||
- name: Run flake checks
|
- name: Run flake checks
|
||||||
run: |
|
run: |
|
||||||
set -exuo pipefail
|
|
||||||
# Prevent cache garbage collection by creating GC roots
|
# Prevent cache garbage collection by creating GC roots
|
||||||
mkdir -p /var/lib/gitea-runner/tankstelle/.local/state/nix/results
|
for target in $(nix flake show --json --all-systems | jq '
|
||||||
|
|
||||||
for target in $(nix flake show --json --all-systems | jq --raw-output '
|
|
||||||
.["nixosConfigurations"] |
|
.["nixosConfigurations"] |
|
||||||
to_entries[] |
|
to_entries[] |
|
||||||
.key'
|
.key
|
||||||
|
' | tr -d '"'
|
||||||
); do
|
); do
|
||||||
nix --print-build-logs --verbose --accept-flake-config --access-tokens '' \
|
nix --print-build-logs --verbose --accept-flake-config --access-tokens '' \
|
||||||
build --out-link /var/lib/gitea-runner/tankstelle/.local/state/nix/results/"$target" ".#nixosConfigurations.${target}.config.system.build.toplevel"
|
build --out-link ./result-$target ".#nixosConfigurations.${target}.config.system.build.toplevel"
|
||||||
done
|
done
|
||||||
|
|
||||||
for check in $(nix flake show --json --all-systems | jq --raw-output '
|
nix --print-build-logs --verbose --accept-flake-config --access-tokens '' flake check
|
||||||
.checks."x86_64-linux" |
|
|
||||||
to_entries[] |
|
# Add GC roots for flake inputs, too
|
||||||
.key'
|
# https://github.com/NixOS/nix/issues/4250#issuecomment-1146878407
|
||||||
); do
|
mkdir --parents "$NIX_USER_PROFILE_DIR"
|
||||||
nix --print-build-logs --verbose --accept-flake-config --access-tokens '' \
|
gc_root_prefix="$NIX_USER_PROFILE_DIR"/infra-flake-
|
||||||
build --out-link /var/lib/gitea-runner/tankstelle/.local/state/nix/results/"$check" ".#checks.x86_64-linux.${check}"
|
echo "Adding gcroots flake inputs with prefix $gc_root_prefix ..."
|
||||||
|
nix flake archive --json 2>/dev/null | jq --raw-output '.inputs | to_entries[] | "ln --force --symbolic --no-target-directory "+.value.path+" \"'"$gc_root_prefix"'"+.key+"\""' | while read -r line; do
|
||||||
|
eval "$line"
|
||||||
done
|
done
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
# Apply treewide formatting with treefmt
|
|
||||||
2ca0bd7c3e743e699edb6e9c09d48b7c9106a64d
|
|
||||||
# Apply treewide formatting with nixpkgs-fmt
|
# Apply treewide formatting with nixpkgs-fmt
|
||||||
815033c764660e1468b1564a02570bad0f84f77a
|
815033c764660e1468b1564a02570bad0f84f77a
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,4 +4,3 @@
|
||||||
.terraform
|
.terraform
|
||||||
*.plan
|
*.plan
|
||||||
result
|
result
|
||||||
results
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
# Contributing guide
|
|
||||||
|
|
||||||
Things you'll need:
|
|
||||||
|
|
||||||
- To create [Pull Requests](https://forgejo.org/docs/latest/user/pull-requests-and-git-flow/), you will need to register your [pub.solar ID](https://auth.pub.solar) first.
|
|
||||||
- For small changes, e.g. to documentation, you can directly edit files in the browser.
|
|
||||||
|
|
||||||
### Getting a development shell
|
|
||||||
|
|
||||||
First, get a local copy of this repository:
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone https://git.pub.solar/pub-solar/infra.git
|
|
||||||
cd infra
|
|
||||||
```
|
|
||||||
|
|
||||||
then, install [the package manager nix](https://nixos.org/download).
|
|
||||||
|
|
||||||
Finally, run:
|
|
||||||
|
|
||||||
```
|
|
||||||
nix develop
|
|
||||||
```
|
|
||||||
|
|
||||||
This will install a development shell (devshell) with all required tools.
|
|
||||||
|
|
||||||
### Final checks before creating a Pull Request
|
|
||||||
|
|
||||||
Before creating a pull request, it's recommended to check the formatting:
|
|
||||||
|
|
||||||
```
|
|
||||||
treefmt
|
|
||||||
```
|
|
||||||
|
|
||||||
If you are a terminal-lover, the [AGit alternative](https://forgejo.org/docs/latest/user/agit-support/) to the web based Pull Request workflow might be interesting.
|
|
660
LICENSE.md
660
LICENSE.md
|
@ -1,660 +0,0 @@
|
||||||
### GNU AFFERO GENERAL PUBLIC LICENSE
|
|
||||||
|
|
||||||
Version 3, 19 November 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
|
||||||
<https://fsf.org/>
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies of this
|
|
||||||
license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
### Preamble
|
|
||||||
|
|
||||||
The GNU Affero General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works, specifically designed to ensure
|
|
||||||
cooperation with the community in the case of network server software.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
our General Public Licenses are intended to guarantee your freedom to
|
|
||||||
share and change all versions of a program--to make sure it remains
|
|
||||||
free software for all its users.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
Developers that use our General Public Licenses protect your rights
|
|
||||||
with two steps: (1) assert copyright on the software, and (2) offer
|
|
||||||
you this License which gives you legal permission to copy, distribute
|
|
||||||
and/or modify the software.
|
|
||||||
|
|
||||||
A secondary benefit of defending all users' freedom is that
|
|
||||||
improvements made in alternate versions of the program, if they
|
|
||||||
receive widespread use, become available for other developers to
|
|
||||||
incorporate. Many developers of free software are heartened and
|
|
||||||
encouraged by the resulting cooperation. However, in the case of
|
|
||||||
software used on network servers, this result may fail to come about.
|
|
||||||
The GNU General Public License permits making a modified version and
|
|
||||||
letting the public access it on a server without ever releasing its
|
|
||||||
source code to the public.
|
|
||||||
|
|
||||||
The GNU Affero General Public License is designed specifically to
|
|
||||||
ensure that, in such cases, the modified source code becomes available
|
|
||||||
to the community. It requires the operator of a network server to
|
|
||||||
provide the source code of the modified version running there to the
|
|
||||||
users of that server. Therefore, public use of a modified version, on
|
|
||||||
a publicly accessible server, gives the public access to the source
|
|
||||||
code of the modified version.
|
|
||||||
|
|
||||||
An older license, called the Affero General Public License and
|
|
||||||
published by Affero, was designed to accomplish similar goals. This is
|
|
||||||
a different license, not a version of the Affero GPL, but Affero has
|
|
||||||
released a new version of the Affero GPL which permits relicensing
|
|
||||||
under this license.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
### TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
#### 0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU Affero General Public
|
|
||||||
License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds
|
|
||||||
of works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of
|
|
||||||
an exact copy. The resulting work is called a "modified version" of
|
|
||||||
the earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user
|
|
||||||
through a computer network, with no transfer of a copy, is not
|
|
||||||
conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices" to
|
|
||||||
the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
#### 1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. "Object code" means any non-source form of
|
|
||||||
a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users can
|
|
||||||
regenerate automatically from other parts of the Corresponding Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that same
|
|
||||||
work.
|
|
||||||
|
|
||||||
#### 2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not convey,
|
|
||||||
without conditions so long as your license otherwise remains in force.
|
|
||||||
You may convey covered works to others for the sole purpose of having
|
|
||||||
them make modifications exclusively for you, or provide you with
|
|
||||||
facilities for running those works, provided that you comply with the
|
|
||||||
terms of this License in conveying all material for which you do not
|
|
||||||
control copyright. Those thus making or running the covered works for
|
|
||||||
you must do so exclusively on your behalf, under your direction and
|
|
||||||
control, on terms that prohibit them from making any copies of your
|
|
||||||
copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under the
|
|
||||||
conditions stated below. Sublicensing is not allowed; section 10 makes
|
|
||||||
it unnecessary.
|
|
||||||
|
|
||||||
#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such
|
|
||||||
circumvention is effected by exercising rights under this License with
|
|
||||||
respect to the covered work, and you disclaim any intention to limit
|
|
||||||
operation or modification of the work as a means of enforcing, against
|
|
||||||
the work's users, your or third parties' legal rights to forbid
|
|
||||||
circumvention of technological measures.
|
|
||||||
|
|
||||||
#### 4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
#### 5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
- a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
- b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under
|
|
||||||
section 7. This requirement modifies the requirement in section 4
|
|
||||||
to "keep intact all notices".
|
|
||||||
- c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
- d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
#### 6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms of
|
|
||||||
sections 4 and 5, provided that you also convey the machine-readable
|
|
||||||
Corresponding Source under the terms of this License, in one of these
|
|
||||||
ways:
|
|
||||||
|
|
||||||
- a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
- b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the Corresponding
|
|
||||||
Source from a network server at no charge.
|
|
||||||
- c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
- d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
- e) Convey the object code using peer-to-peer transmission,
|
|
||||||
provided you inform other peers where the object code and
|
|
||||||
Corresponding Source of the work are being offered to the general
|
|
||||||
public at no charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal,
|
|
||||||
family, or household purposes, or (2) anything designed or sold for
|
|
||||||
incorporation into a dwelling. In determining whether a product is a
|
|
||||||
consumer product, doubtful cases shall be resolved in favor of
|
|
||||||
coverage. For a particular product received by a particular user,
|
|
||||||
"normally used" refers to a typical or common use of that class of
|
|
||||||
product, regardless of the status of the particular user or of the way
|
|
||||||
in which the particular user actually uses, or expects or is expected
|
|
||||||
to use, the product. A product is a consumer product regardless of
|
|
||||||
whether the product has substantial commercial, industrial or
|
|
||||||
non-consumer uses, unless such uses represent the only significant
|
|
||||||
mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to
|
|
||||||
install and execute modified versions of a covered work in that User
|
|
||||||
Product from a modified version of its Corresponding Source. The
|
|
||||||
information must suffice to ensure that the continued functioning of
|
|
||||||
the modified object code is in no case prevented or interfered with
|
|
||||||
solely because modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or
|
|
||||||
updates for a work that has been modified or installed by the
|
|
||||||
recipient, or for the User Product in which it has been modified or
|
|
||||||
installed. Access to a network may be denied when the modification
|
|
||||||
itself materially and adversely affects the operation of the network
|
|
||||||
or violates the rules and protocols for communication across the
|
|
||||||
network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
#### 7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders
|
|
||||||
of that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
- a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
- b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
- c) Prohibiting misrepresentation of the origin of that material,
|
|
||||||
or requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
- d) Limiting the use for publicity purposes of names of licensors
|
|
||||||
or authors of the material; or
|
|
||||||
- e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
- f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions
|
|
||||||
of it) with contractual assumptions of liability to the recipient,
|
|
||||||
for any liability that these contractual assumptions directly
|
|
||||||
impose on those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions; the
|
|
||||||
above requirements apply either way.
|
|
||||||
|
|
||||||
#### 8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your license
|
|
||||||
from a particular copyright holder is reinstated (a) provisionally,
|
|
||||||
unless and until the copyright holder explicitly and finally
|
|
||||||
terminates your license, and (b) permanently, if the copyright holder
|
|
||||||
fails to notify you of the violation by some reasonable means prior to
|
|
||||||
60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
#### 9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or run
|
|
||||||
a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
#### 10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
#### 11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims owned
|
|
||||||
or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within the
|
|
||||||
scope of its coverage, prohibits the exercise of, or is conditioned on
|
|
||||||
the non-exercise of one or more of the rights that are specifically
|
|
||||||
granted under this License. You may not convey a covered work if you
|
|
||||||
are a party to an arrangement with a third party that is in the
|
|
||||||
business of distributing software, under which you make payment to the
|
|
||||||
third party based on the extent of your activity of conveying the
|
|
||||||
work, and under which the third party grants, to any of the parties
|
|
||||||
who would receive the covered work from you, a discriminatory patent
|
|
||||||
license (a) in connection with copies of the covered work conveyed by
|
|
||||||
you (or copies made from those copies), or (b) primarily for and in
|
|
||||||
connection with specific products or compilations that contain the
|
|
||||||
covered work, unless you entered into that arrangement, or that patent
|
|
||||||
license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
#### 12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under
|
|
||||||
this License and any other pertinent obligations, then as a
|
|
||||||
consequence you may not convey it at all. For example, if you agree to
|
|
||||||
terms that obligate you to collect a royalty for further conveying
|
|
||||||
from those to whom you convey the Program, the only way you could
|
|
||||||
satisfy both those terms and this License would be to refrain entirely
|
|
||||||
from conveying the Program.
|
|
||||||
|
|
||||||
#### 13. Remote Network Interaction; Use with the GNU General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, if you modify the
|
|
||||||
Program, your modified version must prominently offer all users
|
|
||||||
interacting with it remotely through a computer network (if your
|
|
||||||
version supports such interaction) an opportunity to receive the
|
|
||||||
Corresponding Source of your version by providing access to the
|
|
||||||
Corresponding Source from a network server at no charge, through some
|
|
||||||
standard or customary means of facilitating copying of software. This
|
|
||||||
Corresponding Source shall include the Corresponding Source for any
|
|
||||||
work covered by version 3 of the GNU General Public License that is
|
|
||||||
incorporated pursuant to the following paragraph.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the work with which it is combined will remain governed by version
|
|
||||||
3 of the GNU General Public License.
|
|
||||||
|
|
||||||
#### 14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the GNU Affero General Public License from time to time. Such new
|
|
||||||
versions will be similar in spirit to the present version, but may
|
|
||||||
differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies that a certain numbered version of the GNU Affero General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU Affero General Public License, you may choose any version ever
|
|
||||||
published by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future versions
|
|
||||||
of the GNU Affero General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
#### 15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
|
|
||||||
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
|
||||||
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
|
|
||||||
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
|
|
||||||
CORRECTION.
|
|
||||||
|
|
||||||
#### 16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
|
|
||||||
CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
|
|
||||||
ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
|
|
||||||
NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
|
|
||||||
LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
|
|
||||||
TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
|
|
||||||
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
#### 17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
### How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these
|
|
||||||
terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest to
|
|
||||||
attach them to the start of each source file to most effectively state
|
|
||||||
the exclusion of warranty; and each file should have at least the
|
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as
|
|
||||||
published by the Free Software Foundation, either version 3 of the
|
|
||||||
License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper
|
|
||||||
mail.
|
|
||||||
|
|
||||||
If your software can interact with users remotely through a computer
|
|
||||||
network, you should also make sure that it provides a way for users to
|
|
||||||
get its source. For example, if your program is a web application, its
|
|
||||||
interface could display a "Source" link that leads users to an archive
|
|
||||||
of the code. There are many ways you could offer source, and different
|
|
||||||
solutions will be better for different programs; see section 13 for
|
|
||||||
the specific requirements.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. For more information on this, and how to apply and follow
|
|
||||||
the GNU AGPL, see <https://www.gnu.org/licenses/>.
|
|
|
@ -6,6 +6,6 @@ The architecture we are working towards is a vast simplification of what it was
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
If you'd like to contribute, it makes sense to talk to the crew on Matrix via [#hakken](https://matrix.to/#/#hakken:pub.solar?via=chat.pub.solar). We can help figuring out how things work and can make sure your ideas fit the pub.solar philosophy. Of course [popping a pull request](https://forgejo.org/docs/latest/user/pull-requests-and-git-flow/) is always celebrated.
|
If you'd like to contribute, it makes sense to talk to the crew on Matrix via [#hakken](https://matrix.to/#/#hakken:pub.solar?via=chat.pub.solar). We can help figuring out how things work and can make sure your ideas fit the pub.solar philosophy. Of course [popping a pull request](https://docs.gitea.com/next/usage/pull-request#creating-a-pull-request) is always celebrated.
|
||||||
|
|
||||||
To start, check our [contributing guide](./CONTRIBUTING.md).
|
To start, see [how to get a development shell](./docs/development-shell.md).
|
||||||
|
|
|
@ -14,7 +14,7 @@ People with admin access to the infrastructure are added to [`logins/admins.nix`
|
||||||
publicKey = <pubkey-string>;
|
publicKey = <pubkey-string>;
|
||||||
allowedIPs = [ "10.7.6.<ip-address>/32" "fd00:fae:fae:fae:fae:<ip-address>::/96" ];
|
allowedIPs = [ "10.7.6.<ip-address>/32" "fd00:fae:fae:fae:fae:<ip-address>::/96" ];
|
||||||
}
|
}
|
||||||
];
|
}];
|
||||||
|
|
||||||
secretEncryptionKeys = {
|
secretEncryptionKeys = {
|
||||||
<name> = <encryption-key-string>;
|
<name> = <encryption-key-string>;
|
||||||
|
@ -28,96 +28,7 @@ People with admin access to the infrastructure are added to [`logins/admins.nix`
|
||||||
SSH is not reachable from the open internet. Instead, SSH Port 22 is protected by a wireguard VPN network. Thus, to get root access on the servers, at least two pieces of information have to be added to the admins config:
|
SSH is not reachable from the open internet. Instead, SSH Port 22 is protected by a wireguard VPN network. Thus, to get root access on the servers, at least two pieces of information have to be added to the admins config:
|
||||||
|
|
||||||
1. **SSH Public key**: self-explanatory. Add your public key to your user attrset under `sshPubKeys`.
|
1. **SSH Public key**: self-explanatory. Add your public key to your user attrset under `sshPubKeys`.
|
||||||
2. **Wireguard device**: each wireguard device has two parts: the public key and the IP addresses it should have in the wireguard network. The pub.solar wireguard network uses the subnets `10.7.6.0/24` and `fd00:fae:fae:fae:fae::/80`. To add your device, it's best to choose a free number between 200 and 255 and use that in both the ipv4 and ipv6 ranges: `10.7.6.<ip-address>/32` `fd00:fae:fae:fae:fae:<ip-address>::/96`. For more information on how to generate keypairs, see [the NixOS Wireguard docs](https://nixos.wiki/wiki/WireGuard#Generate_keypair).
|
2. **Wireguard device**: each wireguard device has two parts: the public key and the IP addresses it should have in the wireguard network. The pub.solar wireguard network is spaced under `10.7.6.0/24` and `fd00:fae:fae:fae:fae::/80`. To add your device, it's best to choose a free number between 200 and 255 and use that in both the ipv4 and ipv6 ranges: `10.7.6.<ip-address>/32` `fd00:fae:fae:fae:fae:<ip-address>::/96`. For more information on how to generate keypairs, see [the NixOS Wireguard docs](https://nixos.wiki/wiki/WireGuard#Generate_keypair).
|
||||||
|
|
||||||
One can access our hosts using this domain scheme:
|
|
||||||
|
|
||||||
```
|
|
||||||
ssh <unix-username>@<hostname>.wg.pub.solar
|
|
||||||
```
|
|
||||||
|
|
||||||
So, for example for `nachtigall`:
|
|
||||||
|
|
||||||
```
|
|
||||||
ssh teutat3s@nachtigall.wg.pub.solar
|
|
||||||
```
|
|
||||||
|
|
||||||
Example NixOS snippet for WireGuard client config
|
|
||||||
|
|
||||||
```
|
|
||||||
{
|
|
||||||
networking = {
|
|
||||||
wireguard.enable = true;
|
|
||||||
wg-quick.interfaces = {
|
|
||||||
wg-pub-solar = {
|
|
||||||
address = ["10.7.6.201/32"];
|
|
||||||
address = ["10.7.6.201/32" "fd00:fae:fae:fae:fae:201::/96"];
|
|
||||||
privateKeyFile = "/etc/wireguard/wg-pub-solar.privatekey";
|
|
||||||
|
|
||||||
peers = [
|
|
||||||
{ # nachtigall.pub.solar
|
|
||||||
publicKey = "qzNywKY9RvqTnDO8eLik75/SHveaSk9OObilDzv+xkk=";
|
|
||||||
allowedIPs = [ "10.7.6.1/32" "fd00:fae:fae:fae:fae:1::/96" ];
|
|
||||||
endpoint = "[2a01:4f8:172:1c25::1]:51820";
|
|
||||||
# Use this endpoint in IPv4 only networks
|
|
||||||
#endpoint = "138.201.80.102:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
{ # metronom.pub.solar
|
|
||||||
publicKey = "zOSYGO7MfnOOUnzaTcWiKRQM0qqxR3JQrwx/gtEtHmo=";
|
|
||||||
allowedIPs = [ "10.7.6.3/32" "fd00:fae:fae:fae:fae:3::/96" ];
|
|
||||||
#endpoint = "[2a01:4f8:c2c:7082::]:51820";
|
|
||||||
# Use this endpoint in IPv4 only networks
|
|
||||||
endpoint = "49.13.236.167:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
{ # tankstelle.pub.solar
|
|
||||||
publicKey = "iRTlY1lB7nPXf2eXzX8ZZDkfMmXyGjff5/joccbP8Cg=";
|
|
||||||
allowedIPs = [ "10.7.6.4/32" "fd00:fae:fae:fae:fae:4::/96" ];
|
|
||||||
endpoint = "[2001:4d88:1ffa:26::5]:51820";
|
|
||||||
# Use this endpoint in IPv4 only networks
|
|
||||||
#endpoint = "80.244.242.5:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# trinkgenossin.pub.solar
|
|
||||||
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.5/32"
|
|
||||||
"fd00:fae:fae:fae:fae:5::/96"
|
|
||||||
];
|
|
||||||
#endpoint = "85.215.152.22:51820";
|
|
||||||
endpoint = "[2a01:239:35d:f500::1]:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# delite.pub.solar
|
|
||||||
publicKey = "ZT2qGWgMPwHRUOZmTQHWCRX4m14YwOsiszjsA5bpc2k=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.6/32"
|
|
||||||
"fd00:fae:fae:fae:fae:6::/96"
|
|
||||||
];
|
|
||||||
#endpoint = "5.255.119.132:51820";
|
|
||||||
endpoint = "[2a04:52c0:124:9d8c::2]:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# blue-shell.pub.solar
|
|
||||||
publicKey = "bcrIpWrKc1M+Hq4ds3aN1lTaKE26f2rvXhd+93QrzR8=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.7/32"
|
|
||||||
"fd00:fae:fae:fae:fae:7::/96"
|
|
||||||
];
|
|
||||||
#endpoint = "194.13.83.205:51820";
|
|
||||||
endpoint = "[2a03:4000:43:24e::1]:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
# Secret encryption
|
# Secret encryption
|
||||||
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
# Backups
|
|
||||||
|
|
||||||
We use [Restic](https://restic.readthedocs.io/en/stable/) to create backups and push them to two repositories.
|
|
||||||
Check `./modules/backups.nix` and `./hosts/nachtigall/backups.nix` for working examples.
|
|
||||||
|
|
||||||
### Hetzner Storagebox
|
|
||||||
|
|
||||||
- Uses SFTP for transfer of backups
|
|
||||||
|
|
||||||
Adding a new host SSH public key to the storagebox:
|
|
||||||
|
|
||||||
First, [SSH to nachtigall](./administrative-access.md#ssh-access), then become root and add the new SSH public key
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo -i
|
|
||||||
echo '<ssh-public-key>' | ssh -p23 u377325@u377325.your-storagebox.de install-ssh-key
|
|
||||||
```
|
|
||||||
|
|
||||||
[Link to Hetzner storagebox docs](https://docs.hetzner.com/robot/storage-box/backup-space-ssh-keys).
|
|
||||||
|
|
||||||
### Garage S3 buckets
|
|
||||||
|
|
||||||
- Uses S3 for transfer of backups
|
|
||||||
- One bucket per host, e.g. `nachtigall-backups`, `metronom-backups`
|
|
||||||
|
|
||||||
To start transfering backups from a new hosts, this is how to create a new bucket:
|
|
||||||
|
|
||||||
First, [SSH to trinkgenossin](./administrative-access.md#ssh-access), then use the `garage` CLI to create a new key and bucket:
|
|
||||||
|
|
||||||
```
|
|
||||||
export GARAGE_RPC_SECRET=<secret-in-keepass>
|
|
||||||
|
|
||||||
garage bucket create <hostname>-backups
|
|
||||||
garage key create <hostname>-backups-key
|
|
||||||
garage bucket allow <hostname>-backups --read --write --key <hostname>-backups-key
|
|
||||||
```
|
|
|
@ -1,55 +0,0 @@
|
||||||
# Cachix usage
|
|
||||||
|
|
||||||
URL: https://pub-solar.cachix.org
|
|
||||||
|
|
||||||
Requirements:
|
|
||||||
|
|
||||||
- [Install cachix](https://docs.cachix.org/installation)
|
|
||||||
- Optional: To push to the cache, you need to set `CACHIX_AUTH_TOKEN` in your environment. To generate one for you, follow the [Getting Started](https://docs.cachix.org/getting-started#authenticating) docs and login with your GitHub account.
|
|
||||||
- Add our binary cache [to your nix config](https://docs.cachix.org/faq#cachix-use-effects). To add the pub-solar cache, run:
|
|
||||||
|
|
||||||
```
|
|
||||||
cachix use pub-solar
|
|
||||||
```
|
|
||||||
|
|
||||||
Example to build and push a custom package of a host in this flake (e.g. after creating an overlay):
|
|
||||||
|
|
||||||
```
|
|
||||||
nix build --json -f . '.#nixosConfigurations.nachtigall.pkgs.keycloak^*' \
|
|
||||||
| jq -r '.[].outputs | to_entries[].value' \
|
|
||||||
| cachix push pub-solar
|
|
||||||
```
|
|
||||||
|
|
||||||
Example to build and push a package in the `nixpkgs` repo:
|
|
||||||
|
|
||||||
```
|
|
||||||
cd nixpkgs
|
|
||||||
nix build --json -f . 'pkgs.lix^*' \
|
|
||||||
| jq -r '.[].outputs | to_entries[].value' \
|
|
||||||
| cachix push pub-solar
|
|
||||||
```
|
|
||||||
|
|
||||||
Checking if a package has been correctly pushed to the cache:
|
|
||||||
|
|
||||||
```
|
|
||||||
❯ nix build --json '/nix/store/f76xi83z4xk9sn6pbh38rh97yvqhb5m0-noto-fonts-color-emoji-png-2.042.drv^*' | jq -r '.[].outputs | to_entries[].value' | cachix push pub-solar
|
|
||||||
Pushing 1 paths (0 are already present) using zstd to cache pub-solar ⏳
|
|
||||||
|
|
||||||
✓ /nix/store/xpgpi84765dxqja3gd5pldj49xx2v0xl-noto-fonts-color-emoji-png-2.042 (10.30 MiB)
|
|
||||||
|
|
||||||
All done.
|
|
||||||
|
|
||||||
❯ curl -I https://pub-solar.cachix.org/xpgpi84765dxqja3gd5pldj49xx2v0xl.narinfo
|
|
||||||
HTTP/2 200
|
|
||||||
date: Mon, 26 Aug 2024 09:31:10 GMT
|
|
||||||
content-type: text/x-nix-narinfo
|
|
||||||
traceparent: 00-b99db37cc9c2581b8d226cdf81e54507-794fc49193659c03-01
|
|
||||||
tracestate:
|
|
||||||
cache-control: public, max-age=14400
|
|
||||||
last-modified: Mon, 26 Aug 2024 09:31:10 GMT
|
|
||||||
cf-cache-status: EXPIRED
|
|
||||||
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=A67KGsCIsYjoFdvndxJ0rkmb7BZ5ztIpm8WUJKAiUPRVWvbYeXU9gU27P7zryiUtArbwrLzHhhMija0yyXk0kwNa3suz8gNzKK6z1CX1FWDZiiP07rnq7zAg8nZbSBiEU%2FZrU9nSrR6mhuL9ihbmW1Hf"}],"group":"cf-nel","max_age":604800}
|
|
||||||
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
|
|
||||||
server: cloudflare
|
|
||||||
cf-ray: 8b92ceab0d19c80e-DUS
|
|
||||||
```
|
|
|
@ -1,16 +1,13 @@
|
||||||
# Process for handling a deletion request
|
# Process for handling a deletion request
|
||||||
|
|
||||||
### Keycloak
|
### Keycloak
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
|
- auth.pub.solar ops user credentials
|
||||||
- auth.pub.solar `admin-cli` service user credentials
|
- SSH access to host nachtigall
|
||||||
- [SSH access to host `nachtigall`](./administrative-access.md#ssh-access)
|
|
||||||
|
|
||||||
Run each of the following after SSH'ing to `nachtigall`:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo --user keycloak kcadm.sh config credentials --config /tmp/kcadm.config --server http://localhost:8080 --realm pub.solar --client admin-cli
|
ssh barkeeper@nachtigall.pub.solar
|
||||||
|
|
||||||
|
sudo --user keycloak kcadm.sh config credentials --config /tmp/kcadm.config --server http://localhost:8080 --realm pub.solar --user ops
|
||||||
|
|
||||||
# Take note of user id in response from following command
|
# Take note of user id in response from following command
|
||||||
sudo --user keycloak kcadm.sh get --config /tmp/kcadm.config users --realm pub.solar --query email=<email-address>
|
sudo --user keycloak kcadm.sh get --config /tmp/kcadm.config users --realm pub.solar --query email=<email-address>
|
||||||
|
@ -23,38 +20,42 @@ sudo --user keycloak kcadm.sh update --config /tmp/kcadm.config users/2ec6f173-3
|
||||||
|
|
||||||
Docs: https://www.keycloak.org/docs/latest/server_admin/index.html#updating-a-user
|
Docs: https://www.keycloak.org/docs/latest/server_admin/index.html#updating-a-user
|
||||||
|
|
||||||
### Nextcloud
|
|
||||||
|
|
||||||
|
### Nextcloud
|
||||||
```
|
```
|
||||||
|
ssh barkeeper@nachtigall.pub.solar
|
||||||
nextcloud-occ user:delete <username>
|
nextcloud-occ user:delete <username>
|
||||||
```
|
```
|
||||||
|
|
||||||
Docs: https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#user-commands-label
|
Docs: https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#user-commands-label
|
||||||
|
|
||||||
### Mastodon
|
|
||||||
|
|
||||||
|
### Mastodon
|
||||||
```
|
```
|
||||||
|
ssh barkeeper@nachtigall.pub.solar
|
||||||
sudo -u mastodon mastodon-tootctl accounts delete --email <mail-address>
|
sudo -u mastodon mastodon-tootctl accounts delete --email <mail-address>
|
||||||
```
|
```
|
||||||
|
|
||||||
Docs: https://docs.joinmastodon.org/admin/tootctl/#accounts-delete
|
Docs: https://docs.joinmastodon.org/admin/tootctl/#accounts-delete
|
||||||
|
|
||||||
### Forgejo
|
|
||||||
|
|
||||||
|
### Forgejo
|
||||||
```
|
```
|
||||||
|
ssh barkeeper@nachtigall.pub.solar
|
||||||
sudo -u gitea gitea admin user delete --config /var/lib/forgejo/custom/conf/app.ini --purge --email <mail-address>
|
sudo -u gitea gitea admin user delete --config /var/lib/forgejo/custom/conf/app.ini --purge --email <mail-address>
|
||||||
```
|
```
|
||||||
|
|
||||||
Docs: https://forgejo.org/docs/latest/admin/command-line/#delete
|
Docs: https://forgejo.org/docs/latest/admin/command-line/#delete
|
||||||
|
|
||||||
### Matrix
|
|
||||||
|
|
||||||
|
### Matrix
|
||||||
```
|
```
|
||||||
curl --header "Authorization: Bearer <admin-access-token>" --request POST http://127.0.0.1:8008/_synapse/admin/v1/deactivate/@<username>:pub.solar --data '{"erase": true}'
|
ssh bartender@matrix.pub.solar -p 2020
|
||||||
|
curl --header "Authorization: Bearer <admin-access-token>" --request POST http://172.18.0.3:8008/_synapse/admin/v1/deactivate/@<username>:pub.solar --data '{"erase": true}'
|
||||||
```
|
```
|
||||||
|
|
||||||
Docs: https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#deactivate-account
|
Docs: https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#deactivate-account
|
||||||
|
|
||||||
### OpenBikeSensor
|
|
||||||
|
|
||||||
|
### OpenBikeSensor
|
||||||
Not implemented, see: https://github.com/openbikesensor/portal/issues/95
|
Not implemented, see: https://github.com/openbikesensor/portal/issues/95
|
||||||
|
|
|
@ -7,29 +7,14 @@ be manually deployed.
|
||||||
To deploy, make sure you have a [working development shell](./development-shell.md).
|
To deploy, make sure you have a [working development shell](./development-shell.md).
|
||||||
Then, run `deploy-rs` with the hostname of the server you want to deploy:
|
Then, run `deploy-rs` with the hostname of the server you want to deploy:
|
||||||
|
|
||||||
### Dry-run
|
|
||||||
|
|
||||||
Use `--dry-activate` to show a diff of updated packages and all services that
|
|
||||||
would be restarted by the update. This will also put all files in place without
|
|
||||||
switching to the new generation, enabling a quick switch to the new config at a
|
|
||||||
later moment.
|
|
||||||
|
|
||||||
For nachtigall.pub.solar:
|
For nachtigall.pub.solar:
|
||||||
|
|
||||||
```
|
```
|
||||||
deploy --targets '.#nachtigall' --ssh-user <unix-username> --magic-rollback false --auto-rollback false --keep-result --result-path ./results --dry-activate
|
deploy --targets '.#nachtigall' --magic-rollback false --auto-rollback false
|
||||||
```
|
```
|
||||||
|
|
||||||
After reviewing the changes, apply the update with:
|
For flora-6.pub.solar:
|
||||||
|
|
||||||
```
|
```
|
||||||
deploy --targets '.#nachtigall' --ssh-user <unix-username> --magic-rollback false --auto-rollback false --keep-result --result-path ./results
|
deploy --targets '.#flora-6' --magic-rollback false --auto-rollback false
|
||||||
```
|
|
||||||
|
|
||||||
For metronom.pub.solar (aarch64-linux):
|
|
||||||
|
|
||||||
```
|
|
||||||
deploy --targets '.#metronom' --ssh-user <unix-username> --magic-rollback false --auto-rollback false --keep-result --result-path ./results --remote-build
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Usually we skip all rollback functionality, but if you want to deploy a change
|
Usually we skip all rollback functionality, but if you want to deploy a change
|
||||||
|
@ -38,13 +23,10 @@ that might lock you out, e.g. to SSH, it might make sense to set these to `true`
|
||||||
To skip flake checks, e.g. because you already ran them manually before
|
To skip flake checks, e.g. because you already ran them manually before
|
||||||
deployment, add the flag `--skip-checks` at the end of the command.
|
deployment, add the flag `--skip-checks` at the end of the command.
|
||||||
|
|
||||||
We use `--keep-result --result-path ./results` to keep the last `result`
|
`--dry-activate` can be used to only put all files in place without switching,
|
||||||
symlink of each `deploy` from being garbage collected. That way, we keep builds
|
to enable switching to the new config quickly at a later moment.
|
||||||
cached in the Nix store. This is optional and both flags can be removed if disk
|
|
||||||
space is a scarce resource on your machine.
|
|
||||||
|
|
||||||
You'll need to have SSH Access to the boxes to be able to run `deploy`.
|
You'll need to have SSH Access to the boxes to be able to run `deploy`.
|
||||||
|
|
||||||
### Getting SSH access
|
### Getting SSH access
|
||||||
|
|
||||||
See [administrative-access.md](./administrative-access.md).
|
See [administrative-access.md](./administrative-access.md).
|
||||||
|
|
18
docs/development-shell.md
Normal file
18
docs/development-shell.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Getting a development shell
|
||||||
|
|
||||||
|
Clone this repository:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://git.pub.solar/pub-solar/infra.git
|
||||||
|
cd infra
|
||||||
|
```
|
||||||
|
|
||||||
|
then, install [the package manager nix](https://nixos.org/download).
|
||||||
|
|
||||||
|
Finally, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
nix develop
|
||||||
|
```
|
||||||
|
|
||||||
|
This will install a development shell (devshell) with all required tools.
|
35
docs/dns.md
35
docs/dns.md
|
@ -1,61 +1,58 @@
|
||||||
# Changing DNS entries
|
# Changing DNS entries
|
||||||
|
|
||||||
Our current DNS provider is [namecheap](https://www.namecheap.com/).
|
Our current DNS provider is [namecheap](https://www.namecheap.com/).
|
||||||
We use [OpenTofu](https://opentofu.org) to declaratively manage our pub.solar DNS records.
|
We use [Terraform](https://www.terraform.io) to declaratively manage our pub.solar DNS records.
|
||||||
|
|
||||||
### Initial setup
|
### Initial setup
|
||||||
|
|
||||||
|
Skip this step if you already have a `triton` profile setup.
|
||||||
|
|
||||||
|
```
|
||||||
|
triton profile create
|
||||||
|
```
|
||||||
|
|
||||||
|
Please follow https://docs.greenbaum.cloud/en/devops/triton-cli.html for the details.
|
||||||
|
|
||||||
You will need to setup the following [namecheap API credentials](https://www.namecheap.com/support/api/intro),
|
You will need to setup the following [namecheap API credentials](https://www.namecheap.com/support/api/intro),
|
||||||
look for "namecheap API key" in the pub.solar Keepass database.
|
look for "namecheap API key" in the pub.solar Keepass database.
|
||||||
|
|
||||||
```
|
```
|
||||||
NAMECHEAP_API_KEY
|
NAMECHEAP_API_KEY
|
||||||
NAMECHEAP_API_USER
|
NAMECHEAP_API_USER
|
||||||
NAMECHEAP_USER_NAME
|
NAMECHEAP_USER_NAME
|
||||||
```
|
```
|
||||||
|
|
||||||
You will probably also need to add your external IP to the [API allow list](https://ap.www.namecheap.com/settings/tools/apiaccess/whitelisted-ips).
|
You will probably also need to add your external IP to the [API allow list](https://ap.www.namecheap.com/settings/tools/apiaccess/whitelisted-ips).
|
||||||
|
|
||||||
```
|
```
|
||||||
dig -4 ip @dns.toys
|
dig -4 ip @dns.toys
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, change into the terraform directory and initialize the terraform providers. To decrypt existing state,
|
Now, change into the terraform directory and initialize the terraform providers.
|
||||||
search for "terraform state passphrase" in the pub.solar Keepass database.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
cd terraform
|
cd terraform
|
||||||
export TF_VAR_state_passphrase=$(secret-tool lookup pub.solar terraform-state-passphrase-dns)
|
export TRITON_KEY_ID=$(cat ~/.config/triton/profiles.d/lev-1-pub_solar.json | jq --raw-output .keyId)
|
||||||
|
|
||||||
alias tofu="terraform-backend-git --access-logs --tf tofu git terraform"
|
terraform init
|
||||||
tofu init
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Make your changes, e.g. in `dns.tf`.
|
Make your changes, e.g. in `dns.tf`.
|
||||||
|
|
||||||
```
|
```
|
||||||
$EDITOR dns.tf
|
$EDITOR dns.tf
|
||||||
```
|
```
|
||||||
|
|
||||||
Plan your changes using:
|
Plan your changes using:
|
||||||
|
|
||||||
```
|
```
|
||||||
tofu plan -out pub-solar-infra.plan
|
terraform plan -out pub-solar-infra.plan
|
||||||
```
|
```
|
||||||
|
|
||||||
After verification, apply your changes with:
|
After verification, apply your changes with:
|
||||||
|
|
||||||
```
|
```
|
||||||
tofu apply "pub-solar-infra.plan"
|
terraform apply "pub-solar-infra.plan"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Useful links
|
### Useful links
|
||||||
|
|
||||||
We use terraform-backend-git remote backend with opentofu state encryption for collaboration.
|
We use the Manta remote backend to save the terraform state for collaboration.
|
||||||
|
- https://www.terraform.io/language/v1.2.x/settings/backends/manta
|
||||||
- https://github.com/plumber-cd/terraform-backend-git
|
|
||||||
- https://opentofu.org/docs/language/state/encryption
|
|
||||||
|
|
||||||
Namecheap Terraform provider docs:
|
Namecheap Terraform provider docs:
|
||||||
|
|
||||||
- https://registry.terraform.io/providers/namecheap/namecheap/latest/docs
|
- https://registry.terraform.io/providers/namecheap/namecheap/latest/docs
|
||||||
|
|
19
docs/drone-ci.md
Normal file
19
docs/drone-ci.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Drone CI
|
||||||
|
|
||||||
|
We currently use two CI systems, [drone CI](https://drone.io), reachable via
|
||||||
|
https://ci.pub.solar and [Forgejo Actions](https://forgejo.org/docs/latest/user/actions/),
|
||||||
|
which UI is integrated into https://git.pub.solar, for example
|
||||||
|
https://git.pub.solar/pub-solar/infra/actions.
|
||||||
|
|
||||||
|
### Signing the `.drone.yml` file
|
||||||
|
|
||||||
|
Login to https://ci.pub.solar by clicking on the user icon in the bottom left.
|
||||||
|
After logging in, you can view your personal API token by clicking on the same
|
||||||
|
icon. If you're using the nix [development-shell](./development-shell.md), the
|
||||||
|
`drone` command will already be installed.
|
||||||
|
|
||||||
|
```
|
||||||
|
export DRONE_TOKEN=<your-drone-api-token>
|
||||||
|
|
||||||
|
drone --token $DRONE_TOKEN sign --save pub-solar/os
|
||||||
|
```
|
|
@ -1,84 +0,0 @@
|
||||||
# Garage
|
|
||||||
|
|
||||||
### How-To create a new bucket + keys
|
|
||||||
|
|
||||||
Requirements:
|
|
||||||
|
|
||||||
- `garage` RPC credentials, in the shared keepass, search for 'garage rpc secret'.
|
|
||||||
- [Setup WireGuard](./administrative-access.md#ssh-access) for hosts: `trinkgenossin`, optionally: `delite`, `blue-shell`
|
|
||||||
|
|
||||||
```
|
|
||||||
ssh <unix-username>@trinkgenossin.wg.pub.solar
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
# Add a few spaces to avoid leaking the secret to the shell history
|
|
||||||
export GARAGE_RPC_SECRET=<secret-in-keepass>
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, you can run the following command to check the cluster status:
|
|
||||||
|
|
||||||
```
|
|
||||||
garage status
|
|
||||||
```
|
|
||||||
|
|
||||||
Command to list all existing buckets:
|
|
||||||
|
|
||||||
```
|
|
||||||
garage bucket list
|
|
||||||
```
|
|
||||||
|
|
||||||
Creating a new bucket and access keys:
|
|
||||||
|
|
||||||
```
|
|
||||||
garage bucket create <bucket-name>
|
|
||||||
garage key create <bucket-name>-key
|
|
||||||
garage bucket allow <bucket-name> --read --write --key <bucket-name>-key
|
|
||||||
```
|
|
||||||
|
|
||||||
Full example for `mastodon` bucket:
|
|
||||||
|
|
||||||
```
|
|
||||||
garage bucket create mastodon
|
|
||||||
|
|
||||||
garage key create mastodon-key
|
|
||||||
|
|
||||||
garage bucket allow mastodon --read --write --key mastodon-key
|
|
||||||
```
|
|
||||||
|
|
||||||
Then [setup your favourite S3 client](https://garagehq.deuxfleurs.fr/documentation/connect/cli/)
|
|
||||||
or use the bucket with any [S3 compatible software](https://garagehq.deuxfleurs.fr/documentation/connect/).
|
|
||||||
|
|
||||||
Further reading:
|
|
||||||
|
|
||||||
- https://garagehq.deuxfleurs.fr/documentation/quick-start/
|
|
||||||
- https://garagehq.deuxfleurs.fr/documentation/connect/
|
|
||||||
- https://garagehq.deuxfleurs.fr/documentation/connect/apps/#mastodon
|
|
||||||
|
|
||||||
### Notes on manual setup steps
|
|
||||||
|
|
||||||
```
|
|
||||||
ssh <unix-username>@trinkgenossin.wg.pub.solar
|
|
||||||
|
|
||||||
# Add a few spaces to avoid leaking the secret to the shell history
|
|
||||||
export GARAGE_RPC_SECRET=<secret-in-keepass>
|
|
||||||
|
|
||||||
# Uses the default config /etc/garage.toml
|
|
||||||
garage node id
|
|
||||||
|
|
||||||
garage node connect <node-id2>
|
|
||||||
garage node connect <node-id3>
|
|
||||||
|
|
||||||
garage status
|
|
||||||
|
|
||||||
#Zones
|
|
||||||
#DE-1 DE-2 NL-1
|
|
||||||
|
|
||||||
garage layout assign fdaa -z DE-1 -c 800G -t trinkgenossin
|
|
||||||
garage layout assign 8835 -z DE-2 -c 800G -t blue-shell
|
|
||||||
garage layout assign 73da -z NL-1 -c 800G -t delite
|
|
||||||
garage layout show
|
|
||||||
garage layout apply --version 1
|
|
||||||
```
|
|
||||||
|
|
||||||
Source: https://garagehq.deuxfleurs.fr/documentation/cookbook/real-world/#creating-a-cluster-layout
|
|
|
@ -1,79 +0,0 @@
|
||||||
# Delete accounts without verified email address
|
|
||||||
|
|
||||||
### Keycloak
|
|
||||||
|
|
||||||
Required:
|
|
||||||
|
|
||||||
- auth.pub.solar admin-cli service user credentials
|
|
||||||
- [SSH access to host `nachtigall`](../administrative-access.md#ssh-access)
|
|
||||||
|
|
||||||
Run following after SSH'ing to `nachtigall`.
|
|
||||||
|
|
||||||
Credentials for the following command are in keepass. Create a keycloak
|
|
||||||
config/credentials file at `/tmp/kcadm.config`:
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo --user keycloak kcadm.sh config credentials \
|
|
||||||
--config /tmp/kcadm.config \
|
|
||||||
--server https://auth.pub.solar \
|
|
||||||
--realm pub.solar \
|
|
||||||
--client admin-cli
|
|
||||||
```
|
|
||||||
|
|
||||||
Get list of accounts without a verified email address:
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo --user keycloak kcadm.sh get \
|
|
||||||
--config /tmp/kcadm.config \
|
|
||||||
users \
|
|
||||||
--realm pub.solar \
|
|
||||||
--query emailVerified=false \
|
|
||||||
> /tmp/keycloak-unverified-accounts
|
|
||||||
```
|
|
||||||
|
|
||||||
Review list of accounts, especially check `createdTimestamp` if any accounts
|
|
||||||
were created in the past 2 days. If so, delete those from the
|
|
||||||
`/tmp/keycloak-unverified-accounts` file.
|
|
||||||
|
|
||||||
```
|
|
||||||
createdTimestamps=( $( nix run nixpkgs#jq -- -r '.[].createdTimestamp' < /tmp/keycloak-unverified-accounts ) )
|
|
||||||
|
|
||||||
# timestamps are in nanoseconds since epoch, so we need to strip the last three digits
|
|
||||||
for timestamp in ${createdTimestamps[@]}; do date --date="@${timestamp::-3}"; done
|
|
||||||
|
|
||||||
vim /tmp/keycloak-unverified-accounts
|
|
||||||
```
|
|
||||||
|
|
||||||
Check how many accounts are going to be deleted:
|
|
||||||
|
|
||||||
```
|
|
||||||
jq -r '.[].id' < /tmp/keycloak-unverified-accounts | wc -l
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
jq -r '.[].id' < /tmp/keycloak-unverified-accounts > /tmp/keycloak-unverified-account-ids
|
|
||||||
```
|
|
||||||
|
|
||||||
Final check before deletion (dry-run):
|
|
||||||
|
|
||||||
```
|
|
||||||
for id in $(cat /tmp/keycloak-unverified-account-ids)
|
|
||||||
do
|
|
||||||
echo sudo --user keycloak kcadm.sh delete \
|
|
||||||
--config /tmp/kcadm.config \
|
|
||||||
users/$id \
|
|
||||||
--realm pub.solar
|
|
||||||
done
|
|
||||||
```
|
|
||||||
|
|
||||||
THIS WILL DELETE ACCOUNTS:
|
|
||||||
|
|
||||||
```
|
|
||||||
for id in $(cat /tmp/keycloak-unverified-account-ids)
|
|
||||||
do
|
|
||||||
sudo --user keycloak kcadm.sh delete \
|
|
||||||
--config /tmp/kcadm.config \
|
|
||||||
users/$id \
|
|
||||||
--realm pub.solar
|
|
||||||
done
|
|
||||||
```
|
|
|
@ -1,15 +1,12 @@
|
||||||
# Process for getting a list of email addresses of all keycloak users
|
# Process for getting a list of email addresses of all keycloak users
|
||||||
|
|
||||||
### Keycloak
|
### Keycloak
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
|
- auth.pub.solar ops user credentials
|
||||||
- auth.pub.solar admin-cli service user credentials
|
- SSH access to host nachtigall
|
||||||
- [SSH access to host `nachtigall`](../administrative-access.md#ssh-access)
|
|
||||||
|
|
||||||
Run following after SSH'ing to `nachtigall`:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
ssh barkeeper@nachtigall.pub.solar
|
||||||
|
|
||||||
sudo --user keycloak kcadm.sh get users \
|
sudo --user keycloak kcadm.sh get users \
|
||||||
-r pub.solar \
|
-r pub.solar \
|
||||||
--offset 0 \
|
--offset 0 \
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
# Process for resetting keycloak user passwords
|
# Process for resetting keycloak user passwords
|
||||||
|
|
||||||
### Keycloak
|
### Keycloak
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
|
- auth.pub.solar ops user credentials
|
||||||
- auth.pub.solar admin-cli service user credentials
|
- SSH access to host nachtigall
|
||||||
- [SSH access to host `nachtigall`](../administrative-access.md#ssh-access)
|
|
||||||
|
|
||||||
Run the following after SSH'ing to `nachtigall`:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
ssh barkeeper@nachtigall.pub.solar
|
||||||
|
|
||||||
mkdir /tmp/keycloak-credential-reset
|
mkdir /tmp/keycloak-credential-reset
|
||||||
|
|
||||||
sudo --user keycloak kcadm.sh config credentials --config /tmp/kcadm.config --server http://localhost:8080 --realm pub.solar --client admin-cli
|
sudo --user keycloak kcadm.sh config credentials --config /tmp/kcadm.config --server http://localhost:8080 --realm pub.solar --user ops
|
||||||
|
|
||||||
sudo --user keycloak kcadm.sh get --config /tmp/kcadm.config users --realm pub.solar | jq --raw-output '.[] | .id' > /tmp/keycloak-credential-reset/all-uuids
|
sudo --user keycloak kcadm.sh get --config /tmp/kcadm.config users --realm pub.solar | jq --raw-output '.[] | .id' > /tmp/keycloak-credential-reset/all-uuids
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
# Process for updating a keycloak realm via CLI
|
# Process for updating a keycloak realm via CLI
|
||||||
|
|
||||||
### Keycloak
|
### Keycloak
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
|
- auth.pub.solar ops user credentials
|
||||||
- auth.pub.solar admin-cli service user credentials
|
- SSH access to host nachtigall
|
||||||
- [SSH access to host `nachtigall`](../administrative-access.md#ssh-access)
|
|
||||||
|
|
||||||
Run the following after SSH'ing to `nachtigall`:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
ssh barkeeper@nachtigall.pub.solar
|
||||||
|
|
||||||
sudo -u keycloak kcadm.sh config credentials --config /tmp/kcadm.config --server http://localhost:8080 --realm master --user admin
|
sudo -u keycloak kcadm.sh config credentials --config /tmp/kcadm.config --server http://localhost:8080 --realm master --user admin
|
||||||
|
|
||||||
sudo -u keycloak kcadm.sh get --config /tmp/kcadm.config realms/pub.solar
|
sudo -u keycloak kcadm.sh get --config /tmp/kcadm.config realms/pub.solar
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
### Mail
|
|
||||||
|
|
||||||
mail.pub.solar aka metronom.pub.solar hosts our internal mails.
|
|
||||||
This is a small Hetzner cloud instance on https://console.hetzner.cloud.
|
|
|
@ -4,27 +4,28 @@ See the [mediawiki-oidc-docker repository](https://git.pub.solar/pub-solar/media
|
||||||
for instructions on updating our customized mediawiki docker image.
|
for instructions on updating our customized mediawiki docker image.
|
||||||
|
|
||||||
To deploy a new docker image to `nachtigall`, first bump the mediawiki version
|
To deploy a new docker image to `nachtigall`, first bump the mediawiki version
|
||||||
of the docker image tag in `modules/mediawiki/default.nix` (search for
|
of the docker image tag in `hosts/nachtigall/apps/mediawiki.nix` (search for
|
||||||
`image`).
|
`image`).
|
||||||
|
|
||||||
Next, push your changes to https://git.pub.solar and get them reviewed and
|
Next, push your changes to https://git.pub.solar and get them reviewed and
|
||||||
approved.
|
approved.
|
||||||
|
|
||||||
After approval, create a fresh backup of the database and deploy the changes to
|
After approval, create a fresh backup of the database and deploy the changes to
|
||||||
`nachtigall`. Run the following after [SSH'ing to `nachtigall`](./administrative-access.md#ssh-access):
|
`nachtigall`:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
ssh barkeeper@nachtigall.pub.solar
|
||||||
sudo -u postgres pg_dump --create -Fc mediawiki > mediawiki-db-$(date +%F).dump
|
sudo -u postgres pg_dump --create -Fc mediawiki > mediawiki-db-$(date +%F).dump
|
||||||
exit
|
exit
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
deploy --targets '.#nachtigall' --magic-rollback false --auto-rollback false --keep-result --result-path ./results
|
deploy --targets '.#nachtigall'
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, finalize the update by running the database migration script (in a [SSH](./administrative-access.md#ssh-access) shell on `nachtigall`):
|
Then, finalize the update by running the database migration script:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
ssh barkeeper@nachtigall.pub.solar
|
||||||
docker exec -it mediawiki bash
|
docker exec -it mediawiki bash
|
||||||
php maintenance/run.php update.php
|
php maintenance/run.php update.php
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
# Nextcloud debugging
|
|
||||||
|
|
||||||
Set loglevel to `0` for debug logs:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
services.nextcloud.settings.loglevel = 0;
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, logs appear in the `phpfpm-nextcloud.service` logs:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo journalctl -fu phpfpm-nextcloud
|
|
||||||
```
|
|
||||||
|
|
||||||
Make sure to set the loglevel back to the default `2` warning after debugging:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
services.nextcloud.settings.loglevel = 2;
|
|
||||||
```
|
|
|
@ -41,7 +41,3 @@ wrapped-ruby-mastodon-gems: 4.2.1 → 4.2.3
|
||||||
zfs-kernel: 2.2.1-6.1.64 → 2.2.2-6.1.66
|
zfs-kernel: 2.2.1-6.1.64 → 2.2.2-6.1.66
|
||||||
zfs-user: 2.2.1 → 2.2.2
|
zfs-user: 2.2.1 → 2.2.2
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying updates
|
|
||||||
|
|
||||||
See [deploying.md](./deploying.md).
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
```
|
|
||||||
curl -L https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz | tar -xzf- -C /root
|
|
||||||
/root/kexec/run
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
mkdir -p /etc/secrets/initrd
|
|
||||||
ssh-keygen -t ed25519 -f /etc/secrets/initrd/ssh_host_ed25519_key
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
nix run github:nix-community/nixos-anywhere -- --flake .#blue-shell root@194.13.83.205
|
|
||||||
```
|
|
|
@ -1,10 +1,10 @@
|
||||||
# OpenBikeSensor Portal
|
# OpenBikeSensor Portal
|
||||||
|
|
||||||
## Docker Containers
|
## Docker Containers
|
||||||
|
* portal
|
||||||
|
* worker
|
||||||
|
* db
|
||||||
|
|
||||||
- portal
|
|
||||||
- worker
|
|
||||||
- db
|
|
||||||
|
|
||||||
## Run database migrations
|
## Run database migrations
|
||||||
|
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
# Reverting to an old version
|
# Reverting to an old version
|
||||||
|
|
||||||
|
|
||||||
|
|
9
docs/unlocking-root.md
Normal file
9
docs/unlocking-root.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Unlocking the root partition on boot
|
||||||
|
|
||||||
|
After a boot, the encrypted root partition will have to be unlocked. This is done by accessing the server via SSH with user root on port 2222.
|
||||||
|
|
||||||
|
```
|
||||||
|
ssh root@nachtigall.pub.solar -p2222
|
||||||
|
```
|
||||||
|
|
||||||
|
After connecting, paste the crypt passphrase you can find in the shared keepass. This will disconnect the SSH session right away and the server will keep booting into stage 2.
|
|
@ -1,20 +0,0 @@
|
||||||
# Unlocking the ZFS pool on boot
|
|
||||||
|
|
||||||
After a reboot, the encrypted ZFS pool will have to be unlocked. This is done by
|
|
||||||
accessing the server via SSH as user `root` on port 2222.
|
|
||||||
|
|
||||||
Nachtigall:
|
|
||||||
|
|
||||||
```
|
|
||||||
ssh -4 root@nachtigall.pub.solar -p2222
|
|
||||||
```
|
|
||||||
|
|
||||||
Metronom:
|
|
||||||
|
|
||||||
```
|
|
||||||
ssh -4 root@metronom.pub.solar -p2222
|
|
||||||
```
|
|
||||||
|
|
||||||
After connecting, paste the encryption passphrase you can find in the shared
|
|
||||||
keepass. This will disconnect the SSH session immediately and the server will
|
|
||||||
continue to boot into stage 2.
|
|
303
flake.lock
303
flake.lock
|
@ -14,11 +14,11 @@
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1723293904,
|
"lastModified": 1712079060,
|
||||||
"narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=",
|
"narHash": "sha256-/JdiT9t+zzjChc5qQiF+jhrVhRt8figYH29rZO7pFe4=",
|
||||||
"owner": "ryantm",
|
"owner": "ryantm",
|
||||||
"repo": "agenix",
|
"repo": "agenix",
|
||||||
"rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41",
|
"rev": "1381a759b205dff7a6818733118d02253340fd5e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -27,22 +27,6 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"blobs": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1604995301,
|
|
||||||
"narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
|
|
||||||
"owner": "simple-nixos-mailserver",
|
|
||||||
"repo": "blobs",
|
|
||||||
"rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
|
|
||||||
"type": "gitlab"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "simple-nixos-mailserver",
|
|
||||||
"repo": "blobs",
|
|
||||||
"type": "gitlab"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"deploy-rs": {
|
"deploy-rs": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
|
@ -52,11 +36,11 @@
|
||||||
"utils": "utils"
|
"utils": "utils"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1727447169,
|
"lastModified": 1711973905,
|
||||||
"narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=",
|
"narHash": "sha256-UFKME/N1pbUtn+2Aqnk+agUt8CekbpuqwzljivfIme8=",
|
||||||
"owner": "serokell",
|
"owner": "serokell",
|
||||||
"repo": "deploy-rs",
|
"repo": "deploy-rs",
|
||||||
"rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76",
|
"rev": "88b3059b020da69cbe16526b8d639bd5e0b51c8b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -87,58 +71,14 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"disko": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1734343412,
|
|
||||||
"narHash": "sha256-b7G8oFp0Nj01BYUJ6ENC9Qf/HsYAIZvN9k/p0Kg/PFU=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "disko",
|
|
||||||
"rev": "a08bfe06b39e94eec98dd089a2c1b18af01fef19",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "disko",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"element-stickers": {
|
|
||||||
"inputs": {
|
|
||||||
"maunium-stickerpicker": [
|
|
||||||
"maunium-stickerpicker"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1714430716,
|
|
||||||
"narHash": "sha256-+WmgGbONe5u2wpvkUC5wNhYnrE6eziIv3Liq4pv7jro=",
|
|
||||||
"ref": "main",
|
|
||||||
"rev": "85716a9e30fb6fae47336ed0cae3d1425c80f17c",
|
|
||||||
"revCount": 6,
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.pub.solar/pub-solar/maunium-stickerpicker-nix"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"ref": "main",
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.pub.solar/pub-solar/maunium-stickerpicker-nix"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"element-themes": {
|
"element-themes": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1718859621,
|
"lastModified": 1707755689,
|
||||||
"narHash": "sha256-ZOOm6UFGNSkGrdwbG5saLAYgAPYJ7E80ogA40CaW+E4=",
|
"narHash": "sha256-pMwrpZwLp7tw0nBbz/ENVJ2LoN9jIxEfjcq7OXoiKEw=",
|
||||||
"owner": "aaronraimist",
|
"owner": "aaronraimist",
|
||||||
"repo": "element-themes",
|
"repo": "element-themes",
|
||||||
"rev": "3bc82abc3dd468dabc933f0f9d0b443ed97554a6",
|
"rev": "2368b58c16d2c4aabb82a245f036d228cbb6e5f5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -164,32 +104,16 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat_2": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1696426674,
|
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-parts": {
|
"flake-parts": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": "nixpkgs-lib"
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733312601,
|
"lastModified": 1712014858,
|
||||||
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
|
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
|
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -234,19 +158,18 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fork": {
|
"flake-utils_3": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1729963002,
|
"lastModified": 1653893745,
|
||||||
"narHash": "sha256-2zrYfd/qdfExU5zVwvH80uJnKc/dMeK6zp3O1UtW2Mo=",
|
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
|
||||||
"owner": "teutat3s",
|
"owner": "numtide",
|
||||||
"repo": "nixpkgs",
|
"repo": "flake-utils",
|
||||||
"rev": "005faaacbeede0296dec5c844f508027ab8a3ff6",
|
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "teutat3s",
|
"owner": "numtide",
|
||||||
"ref": "init-matrix-authentication-service-module",
|
"repo": "flake-utils",
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -257,16 +180,16 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1726989464,
|
"lastModified": 1714043624,
|
||||||
"narHash": "sha256-Vl+WVTJwutXkimwGprnEtXc/s/s8sMuXzqXaspIGlwM=",
|
"narHash": "sha256-Xn2r0Jv95TswvPlvamCC46wwNo8ALjRCMBJbGykdhcM=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "2f23fa308a7c067e52dfcc30a0758f47043ec176",
|
"rev": "86853e31dc1b62c6eeed11c667e8cdd0285d4411",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"ref": "release-24.05",
|
"ref": "release-23.11",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
@ -280,11 +203,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731518114,
|
"lastModified": 1707424749,
|
||||||
"narHash": "sha256-h9Wb3VjmXBZwTO3prRweUKwp2H9hZHCQKrkbU+2WPQs=",
|
"narHash": "sha256-eTvts5E3zmD4/DoAI9KedQjRwica0cg36wwIVp1NWbM=",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"rev": "060ecccc5f8c92a0705ab91ff047811efd559468",
|
"rev": "1202a23c205b3c07a5feb5caf6813f21b3c69307",
|
||||||
"revCount": 36,
|
"revCount": 30,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.pub.solar/pub-solar/keycloak-theme"
|
"url": "https://git.pub.solar/pub-solar/keycloak-theme"
|
||||||
},
|
},
|
||||||
|
@ -294,25 +217,6 @@
|
||||||
"url": "https://git.pub.solar/pub-solar/keycloak-theme"
|
"url": "https://git.pub.solar/pub-solar/keycloak-theme"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"maunium-stickerpicker": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"dir": "web",
|
|
||||||
"lastModified": 1733177811,
|
|
||||||
"narHash": "sha256-1n7bPSCRw7keTCIu4tJGnUlkoId6H1+dPsTPzKo3Rrk=",
|
|
||||||
"owner": "maunium",
|
|
||||||
"repo": "stickerpicker",
|
|
||||||
"rev": "89d3aece041c85ebe5a1ad4e620388af5227cbb0",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"dir": "web",
|
|
||||||
"owner": "maunium",
|
|
||||||
"ref": "master",
|
|
||||||
"repo": "stickerpicker",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nix-darwin": {
|
"nix-darwin": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
@ -320,11 +224,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733570843,
|
"lastModified": 1713946171,
|
||||||
"narHash": "sha256-sQJAxY1TYWD1UyibN/FnN97paTFuwBw3Vp3DNCyKsMk=",
|
"narHash": "sha256-lc75rgRQLdp4Dzogv5cfqOg6qYc5Rp83oedF2t0kDp8=",
|
||||||
"owner": "lnl7",
|
"owner": "lnl7",
|
||||||
"repo": "nix-darwin",
|
"repo": "nix-darwin",
|
||||||
"rev": "a35b08d09efda83625bef267eb24347b446c80b8",
|
"rev": "230a197063de9287128e2c68a7a4b0cd7d0b50a7",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -334,79 +238,87 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixos-flake": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1711376798,
|
||||||
|
"narHash": "sha256-37wawZGSX/dD1rn7TwFJhUdpozC2VPEQXetpfpK/D+w=",
|
||||||
|
"owner": "srid",
|
||||||
|
"repo": "nixos-flake",
|
||||||
|
"rev": "7b19503e7f8c7cc0884fc2fbd669c0cc2e05aef5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "srid",
|
||||||
|
"repo": "nixos-flake",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1734202038,
|
"lastModified": 1713995372,
|
||||||
"narHash": "sha256-LwcGIkORU8zfQ/8jAgptgPY8Zf9lGKB0vtNdQyEkaN8=",
|
"narHash": "sha256-fFE3M0vCoiSwCX02z8VF58jXFRj9enYUSTqjyHAjrds=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "bcba2fbf6963bf6bed3a749f9f4cf5bff4adb96d",
|
"rev": "dd37924974b9202f8226ed5d74a252a9785aedf8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"ref": "nixos-24.05",
|
"ref": "nixos-23.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-2205": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1685573264,
|
||||||
|
"narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "380be19fbd2d9079f677978361792cb25e8a3635",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-22.05",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs-lib": {
|
"nixpkgs-lib": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733096140,
|
"dir": "lib",
|
||||||
"narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=",
|
"lastModified": 1711703276,
|
||||||
"type": "tarball",
|
"narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=",
|
||||||
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "d8fe5e6c92d0d190646fb9f1056741a229980089",
|
||||||
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "tarball",
|
"dir": "lib",
|
||||||
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"agenix": "agenix",
|
"agenix": "agenix",
|
||||||
"deploy-rs": "deploy-rs",
|
"deploy-rs": "deploy-rs",
|
||||||
"disko": "disko",
|
|
||||||
"element-stickers": "element-stickers",
|
|
||||||
"element-themes": "element-themes",
|
"element-themes": "element-themes",
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"fork": "fork",
|
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"keycloak-theme-pub-solar": "keycloak-theme-pub-solar",
|
"keycloak-theme-pub-solar": "keycloak-theme-pub-solar",
|
||||||
"maunium-stickerpicker": "maunium-stickerpicker",
|
|
||||||
"nix-darwin": "nix-darwin",
|
"nix-darwin": "nix-darwin",
|
||||||
|
"nixos-flake": "nixos-flake",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"simple-nixos-mailserver": "simple-nixos-mailserver",
|
"nixpkgs-2205": "nixpkgs-2205",
|
||||||
|
"triton-vmtools": "triton-vmtools",
|
||||||
"unstable": "unstable"
|
"unstable": "unstable"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"simple-nixos-mailserver": {
|
|
||||||
"inputs": {
|
|
||||||
"blobs": "blobs",
|
|
||||||
"flake-compat": "flake-compat_2",
|
|
||||||
"nixpkgs": [
|
|
||||||
"unstable"
|
|
||||||
],
|
|
||||||
"nixpkgs-24_05": [
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"utils": "utils_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1718084203,
|
|
||||||
"narHash": "sha256-Cx1xoVfSMv1XDLgKg08CUd1EoTYWB45VmB9XIQzhmzI=",
|
|
||||||
"owner": "simple-nixos-mailserver",
|
|
||||||
"repo": "nixos-mailserver",
|
|
||||||
"rev": "29916981e7b3b5782dc5085ad18490113f8ff63b",
|
|
||||||
"type": "gitlab"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "simple-nixos-mailserver",
|
|
||||||
"ref": "nixos-24.05",
|
|
||||||
"repo": "nixos-mailserver",
|
|
||||||
"type": "gitlab"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
"systems": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"lastModified": 1681028828,
|
||||||
|
@ -467,28 +379,37 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems_5": {
|
"triton-vmtools": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils_3",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"dir": "vmtools",
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
"lastModified": 1698443513,
|
||||||
"owner": "nix-systems",
|
"narHash": "sha256-wX2JIJ3JmJn6MAurdyjwZU+FZjLCwBArMrVSeeCb/ZU=",
|
||||||
"repo": "default",
|
"ref": "main",
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
"rev": "0d039dcf06afb8cbddd7ac54bae4d0d185f3e88e",
|
||||||
"type": "github"
|
"revCount": 85,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.pub.solar/pub-solar/infra-vintage?dir=vmtools"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nix-systems",
|
"dir": "vmtools",
|
||||||
"repo": "default",
|
"ref": "main",
|
||||||
"type": "github"
|
"type": "git",
|
||||||
|
"url": "https://git.pub.solar/pub-solar/infra-vintage?dir=vmtools"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"unstable": {
|
"unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1734119587,
|
"lastModified": 1713895582,
|
||||||
"narHash": "sha256-AKU6qqskl0yf2+JdRdD0cfxX4b9x3KKV5RqA6wijmPM=",
|
"narHash": "sha256-cfh1hi+6muQMbi9acOlju3V1gl8BEaZBXBR9jQfQi4U=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "3566ab7246670a43abd2ffa913cc62dad9cdf7d5",
|
"rev": "572af610f6151fd41c212f897c71f7056e3fb518",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -515,24 +436,6 @@
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"utils_2": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems_5"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1709126324,
|
|
||||||
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|
192
flake.nix
192
flake.nix
|
@ -1,24 +1,23 @@
|
||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
# Track channels with commits tested and built by hydra
|
# Track channels with commits tested and built by hydra
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
|
||||||
unstable.url = "github:nixos/nixpkgs/nixos-unstable";
|
unstable.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
fork.url = "github:teutat3s/nixpkgs/init-matrix-authentication-service-module";
|
|
||||||
|
nixpkgs-2205.url = "github:nixos/nixpkgs/nixos-22.05";
|
||||||
|
|
||||||
nix-darwin.url = "github:lnl7/nix-darwin/master";
|
nix-darwin.url = "github:lnl7/nix-darwin/master";
|
||||||
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
|
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
||||||
home-manager.url = "github:nix-community/home-manager/release-24.05";
|
home-manager.url = "github:nix-community/home-manager/release-23.11";
|
||||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
nixos-flake.url = "github:srid/nixos-flake";
|
||||||
|
|
||||||
deploy-rs.url = "github:serokell/deploy-rs";
|
deploy-rs.url = "github:serokell/deploy-rs";
|
||||||
deploy-rs.inputs.nixpkgs.follows = "nixpkgs";
|
deploy-rs.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
||||||
disko.url = "github:nix-community/disko";
|
|
||||||
disko.inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
|
|
||||||
agenix.url = "github:ryantm/agenix";
|
agenix.url = "github:ryantm/agenix";
|
||||||
agenix.inputs.nixpkgs.follows = "nixpkgs";
|
agenix.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
agenix.inputs.darwin.follows = "nix-darwin";
|
agenix.inputs.darwin.follows = "nix-darwin";
|
||||||
|
@ -27,136 +26,91 @@
|
||||||
keycloak-theme-pub-solar.url = "git+https://git.pub.solar/pub-solar/keycloak-theme?ref=main";
|
keycloak-theme-pub-solar.url = "git+https://git.pub.solar/pub-solar/keycloak-theme?ref=main";
|
||||||
keycloak-theme-pub-solar.inputs.nixpkgs.follows = "nixpkgs";
|
keycloak-theme-pub-solar.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
||||||
|
triton-vmtools.url = "git+https://git.pub.solar/pub-solar/infra-vintage?ref=main&dir=vmtools";
|
||||||
|
triton-vmtools.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
||||||
element-themes.url = "github:aaronraimist/element-themes/master";
|
element-themes.url = "github:aaronraimist/element-themes/master";
|
||||||
element-themes.flake = false;
|
element-themes.flake = false;
|
||||||
|
|
||||||
maunium-stickerpicker.url = "github:maunium/stickerpicker?ref=master&dir=web";
|
|
||||||
maunium-stickerpicker.flake = false;
|
|
||||||
|
|
||||||
element-stickers.url = "git+https://git.pub.solar/pub-solar/maunium-stickerpicker-nix?ref=main";
|
|
||||||
element-stickers.inputs.maunium-stickerpicker.follows = "maunium-stickerpicker";
|
|
||||||
element-stickers.inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
|
|
||||||
simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/nixos-24.05";
|
|
||||||
simple-nixos-mailserver.inputs.nixpkgs-24_05.follows = "nixpkgs";
|
|
||||||
simple-nixos-mailserver.inputs.nixpkgs.follows = "unstable";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs = inputs@{ self, ... }:
|
||||||
inputs@{ self, ... }:
|
|
||||||
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
|
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
|
||||||
systems = [
|
systems = [ "x86_64-linux" "aarch64-linux" ];
|
||||||
"x86_64-linux"
|
|
||||||
"aarch64-linux"
|
|
||||||
];
|
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
|
inputs.nixos-flake.flakeModule
|
||||||
./logins
|
./logins
|
||||||
./lib
|
./lib
|
||||||
./overlays
|
./overlays
|
||||||
./hosts
|
./hosts
|
||||||
];
|
];
|
||||||
|
|
||||||
perSystem =
|
perSystem = { system, pkgs, config, ... }: {
|
||||||
{
|
_module.args = {
|
||||||
system,
|
inherit inputs;
|
||||||
pkgs,
|
pkgs = import inputs.nixpkgs {
|
||||||
config,
|
inherit system;
|
||||||
lib,
|
overlays = [
|
||||||
...
|
inputs.agenix.overlays.default
|
||||||
}:
|
|
||||||
{
|
|
||||||
_module.args = {
|
|
||||||
inherit inputs;
|
|
||||||
pkgs = import inputs.nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
overlays = [ inputs.agenix.overlays.default ];
|
|
||||||
};
|
|
||||||
unstable = import inputs.unstable { inherit system; };
|
|
||||||
master = import inputs.master { inherit system; };
|
|
||||||
};
|
|
||||||
|
|
||||||
checks =
|
|
||||||
let
|
|
||||||
nixos-lib = import (inputs.nixpkgs + "/nixos/lib") { };
|
|
||||||
testDir = builtins.attrNames (builtins.readDir ./tests);
|
|
||||||
testFiles = builtins.filter (n: builtins.match "^.*.nix$" n != null) testDir;
|
|
||||||
in
|
|
||||||
builtins.listToAttrs (
|
|
||||||
map (x: {
|
|
||||||
name = "test-${lib.strings.removeSuffix ".nix" x}";
|
|
||||||
value = nixos-lib.runTest (
|
|
||||||
import (./tests + "/${x}") {
|
|
||||||
inherit self;
|
|
||||||
inherit pkgs;
|
|
||||||
inherit lib;
|
|
||||||
inherit config;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}) testFiles
|
|
||||||
);
|
|
||||||
|
|
||||||
devShells.default = pkgs.mkShell {
|
|
||||||
buildInputs = with pkgs; [
|
|
||||||
deploy-rs
|
|
||||||
nixpkgs-fmt
|
|
||||||
agenix
|
|
||||||
age-plugin-yubikey
|
|
||||||
cachix
|
|
||||||
editorconfig-checker
|
|
||||||
nodePackages.prettier
|
|
||||||
nvfetcher
|
|
||||||
shellcheck
|
|
||||||
shfmt
|
|
||||||
inputs.unstable.legacyPackages.${system}.treefmt2
|
|
||||||
nixos-generators
|
|
||||||
inputs.unstable.legacyPackages.${system}.opentofu
|
|
||||||
terraform-backend-git
|
|
||||||
terraform-ls
|
|
||||||
jq
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
unstable = import inputs.unstable { inherit system; };
|
||||||
devShells.ci = pkgs.mkShell { buildInputs = with pkgs; [ nodejs ]; };
|
master = import inputs.master { inherit system; };
|
||||||
};
|
};
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
flake = {
|
buildInputs = with pkgs; [
|
||||||
nixosModules = builtins.listToAttrs (
|
deploy-rs
|
||||||
map (x: {
|
nixpkgs-fmt
|
||||||
name = x;
|
agenix
|
||||||
value = import (./modules + "/${x}");
|
age-plugin-yubikey
|
||||||
}) (builtins.attrNames (builtins.readDir ./modules))
|
cachix
|
||||||
);
|
editorconfig-checker
|
||||||
|
nodePackages.prettier
|
||||||
checks = builtins.mapAttrs (
|
nvfetcher
|
||||||
system: deployLib: deployLib.deployChecks self.deploy
|
shellcheck
|
||||||
) inputs.deploy-rs.lib;
|
shfmt
|
||||||
|
treefmt
|
||||||
formatter."x86_64-linux" = inputs.unstable.legacyPackages."x86_64-linux".nixfmt-rfc-style;
|
nixos-generators
|
||||||
|
inputs.nixpkgs-2205.legacyPackages.${system}.terraform
|
||||||
deploy.nodes = self.lib.deploy.mkDeployNodes self.nixosConfigurations {
|
jq
|
||||||
nachtigall = {
|
];
|
||||||
hostname = "nachtigall.wg.pub.solar";
|
|
||||||
};
|
|
||||||
metronom = {
|
|
||||||
hostname = "metronom.wg.pub.solar";
|
|
||||||
};
|
|
||||||
tankstelle = {
|
|
||||||
hostname = "tankstelle.wg.pub.solar";
|
|
||||||
};
|
|
||||||
underground = {
|
|
||||||
hostname = "80.244.242.3";
|
|
||||||
};
|
|
||||||
trinkgenossin = {
|
|
||||||
hostname = "trinkgenossin.wg.pub.solar";
|
|
||||||
};
|
|
||||||
delite = {
|
|
||||||
hostname = "delite.wg.pub.solar";
|
|
||||||
};
|
|
||||||
blue-shell = {
|
|
||||||
hostname = "blue-shell.wg.pub.solar";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
flake =
|
||||||
|
let
|
||||||
|
username = "barkeeper";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit username;
|
||||||
|
|
||||||
|
nixosModules = builtins.listToAttrs (
|
||||||
|
map
|
||||||
|
(x: {
|
||||||
|
name = x;
|
||||||
|
value = import (./modules + "/${x}");
|
||||||
|
})
|
||||||
|
(builtins.attrNames (builtins.readDir ./modules))
|
||||||
|
);
|
||||||
|
|
||||||
|
checks = builtins.mapAttrs
|
||||||
|
(
|
||||||
|
system: deployLib: deployLib.deployChecks self.deploy
|
||||||
|
)
|
||||||
|
inputs.deploy-rs.lib;
|
||||||
|
|
||||||
|
formatter."x86_64-linux" = inputs.unstable.legacyPackages."x86_64-linux".nixfmt-rfc-style;
|
||||||
|
|
||||||
|
deploy.nodes = self.lib.deploy.mkDeployNodes self.nixosConfigurations {
|
||||||
|
nachtigall = {
|
||||||
|
hostname = "10.7.6.1";
|
||||||
|
sshUser = username;
|
||||||
|
};
|
||||||
|
flora-6 = {
|
||||||
|
hostname = "10.7.6.2";
|
||||||
|
sshUser = username;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
boot.loader.grub.enable = true;
|
|
||||||
|
|
||||||
boot.kernelParams = [
|
|
||||||
"boot.shell_on_fail=1"
|
|
||||||
"ip=dhcp"
|
|
||||||
];
|
|
||||||
|
|
||||||
# This option defines the first version of NixOS you have installed on this particular machine,
|
|
||||||
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
|
|
||||||
#
|
|
||||||
# Most users should NEVER change this value after the initial install, for any reason,
|
|
||||||
# even if you've upgraded your system to a new NixOS release.
|
|
||||||
#
|
|
||||||
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
|
|
||||||
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
|
|
||||||
# to actually do that.
|
|
||||||
#
|
|
||||||
# This value being lower than the current NixOS release does NOT mean your system is
|
|
||||||
# out of date, out of support, or vulnerable.
|
|
||||||
#
|
|
||||||
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
|
|
||||||
# and migrated your data accordingly.
|
|
||||||
#
|
|
||||||
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
|
||||||
system.stateVersion = "24.05"; # Did you read the comment?
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{ flake, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./hardware-configuration.nix
|
|
||||||
./configuration.nix
|
|
||||||
./disk-config.nix
|
|
||||||
|
|
||||||
./networking.nix
|
|
||||||
./wireguard.nix
|
|
||||||
#./backups.nix
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
{
|
|
||||||
disko.devices = {
|
|
||||||
disk = {
|
|
||||||
main = {
|
|
||||||
type = "disk";
|
|
||||||
device = "/dev/vdb";
|
|
||||||
content = {
|
|
||||||
type = "gpt";
|
|
||||||
partitions = {
|
|
||||||
bios = {
|
|
||||||
size = "1M";
|
|
||||||
type = "EF02"; # for grub MBR
|
|
||||||
};
|
|
||||||
boot = {
|
|
||||||
size = "1G";
|
|
||||||
type = "8300";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "ext4";
|
|
||||||
mountpoint = "/boot";
|
|
||||||
mountOptions = [ "defaults" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
luks = {
|
|
||||||
size = "100%";
|
|
||||||
content = {
|
|
||||||
type = "luks";
|
|
||||||
name = "cryptroot";
|
|
||||||
extraOpenArgs = [ ];
|
|
||||||
# if you want to use the key for interactive login be sure there is no trailing newline
|
|
||||||
# for example use `echo -n "password" > /tmp/secret.key`
|
|
||||||
passwordFile = "/tmp/luks-password";
|
|
||||||
content = {
|
|
||||||
type = "lvm_pv";
|
|
||||||
vg = "vg0";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
data = {
|
|
||||||
type = "disk";
|
|
||||||
device = "/dev/vdc";
|
|
||||||
content = {
|
|
||||||
type = "gpt";
|
|
||||||
partitions = {
|
|
||||||
luks = {
|
|
||||||
size = "100%";
|
|
||||||
content = {
|
|
||||||
type = "luks";
|
|
||||||
name = "cryptdata";
|
|
||||||
extraOpenArgs = [ ];
|
|
||||||
# if you want to use the key for interactive login be sure there is no trailing newline
|
|
||||||
# for example use `echo -n "password" > /tmp/secret.key`
|
|
||||||
passwordFile = "/tmp/luks-password";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "xfs";
|
|
||||||
mountpoint = "/var/lib/garage/data";
|
|
||||||
mountOptions = [ "defaults" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
lvm_vg = {
|
|
||||||
vg0 = {
|
|
||||||
type = "lvm_vg";
|
|
||||||
lvs = {
|
|
||||||
root = {
|
|
||||||
size = "100G";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "ext4";
|
|
||||||
mountpoint = "/";
|
|
||||||
mountOptions = [ "defaults" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
swap = {
|
|
||||||
size = "16G";
|
|
||||||
content = {
|
|
||||||
type = "swap";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
metadata = {
|
|
||||||
size = "50G";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "btrfs";
|
|
||||||
mountpoint = "/var/lib/garage/meta";
|
|
||||||
mountOptions = [ "defaults" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
|
||||||
"ata_piix"
|
|
||||||
"uhci_hcd"
|
|
||||||
"virtio_pci"
|
|
||||||
"sr_mod"
|
|
||||||
"virtio_blk"
|
|
||||||
];
|
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.kernelModules = [ ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
services.garage.settings.rpc_public_addr = "[2a03:4000:43:24e::1]:3901";
|
|
||||||
|
|
||||||
networking.hostName = "blue-shell";
|
|
||||||
networking.hostId = "00000005";
|
|
||||||
|
|
||||||
networking.useDHCP = false;
|
|
||||||
systemd.network.enable = true;
|
|
||||||
systemd.network.networks."10-wan" = {
|
|
||||||
matchConfig.Name = "ens3";
|
|
||||||
address = [
|
|
||||||
"194.13.83.205/22"
|
|
||||||
"2a03:4000:43:24e::1/64"
|
|
||||||
];
|
|
||||||
gateway = [
|
|
||||||
"194.13.80.1"
|
|
||||||
"fe80::1"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
wireguardIPv4 = "10.7.6.7";
|
|
||||||
wireguardIPv6 = "fd00:fae:fae:fae:fae:7::";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
|
||||||
|
|
||||||
age.secrets.wg-private-key.file = "${flake.self}/secrets/blue-shell-wg-private-key.age";
|
|
||||||
|
|
||||||
networking.wireguard.interfaces = {
|
|
||||||
wg-ssh = {
|
|
||||||
listenPort = 51820;
|
|
||||||
mtu = 1300;
|
|
||||||
ips = [
|
|
||||||
"${wireguardIPv4}/32"
|
|
||||||
"${wireguardIPv6}/96"
|
|
||||||
];
|
|
||||||
privateKeyFile = config.age.secrets.wg-private-key.path;
|
|
||||||
peers = flake.self.logins.wireguardDevices ++ [
|
|
||||||
{
|
|
||||||
# trinkgenossin.pub.solar
|
|
||||||
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.5/32"
|
|
||||||
"fd00:fae:fae:fae:fae:5::/96"
|
|
||||||
];
|
|
||||||
#endpoint = "85.215.152.22:51820";
|
|
||||||
endpoint = "[2a01:239:35d:f500::1]:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.openssh.listenAddresses = [
|
|
||||||
{
|
|
||||||
addr = wireguardIPv4;
|
|
||||||
port = 22;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
addr = "[${wireguardIPv6}]";
|
|
||||||
port = 22;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,35 +1,9 @@
|
||||||
{
|
{ self, ... }:
|
||||||
self,
|
|
||||||
inputs,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
{
|
||||||
flake = {
|
flake = {
|
||||||
nixosModules = {
|
|
||||||
home-manager = {
|
|
||||||
imports = [
|
|
||||||
inputs.home-manager.nixosModules.home-manager
|
|
||||||
{
|
|
||||||
home-manager.useGlobalPkgs = true;
|
|
||||||
home-manager.useUserPackages = true;
|
|
||||||
home-manager.extraSpecialArgs = {
|
|
||||||
flake = {
|
|
||||||
inherit self inputs config;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
nixosConfigurations = {
|
nixosConfigurations = {
|
||||||
nachtigall = self.inputs.nixpkgs.lib.nixosSystem {
|
nachtigall = self.nixos-flake.lib.mkLinuxSystem {
|
||||||
specialArgs = {
|
imports = [
|
||||||
flake = {
|
|
||||||
inherit self inputs config;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
modules = [
|
|
||||||
self.inputs.agenix.nixosModules.default
|
self.inputs.agenix.nixosModules.default
|
||||||
self.nixosModules.home-manager
|
self.nixosModules.home-manager
|
||||||
./nachtigall
|
./nachtigall
|
||||||
|
@ -37,7 +11,6 @@
|
||||||
self.nixosModules.unlock-zfs-on-boot
|
self.nixosModules.unlock-zfs-on-boot
|
||||||
self.nixosModules.core
|
self.nixosModules.core
|
||||||
self.nixosModules.docker
|
self.nixosModules.docker
|
||||||
self.nixosModules.backups
|
|
||||||
|
|
||||||
self.nixosModules.nginx
|
self.nixosModules.nginx
|
||||||
self.nixosModules.collabora
|
self.nixosModules.collabora
|
||||||
|
@ -60,7 +33,6 @@
|
||||||
self.nixosModules.promtail
|
self.nixosModules.promtail
|
||||||
self.nixosModules.searx
|
self.nixosModules.searx
|
||||||
self.nixosModules.tmate
|
self.nixosModules.tmate
|
||||||
self.nixosModules.tt-rss
|
|
||||||
self.nixosModules.obs-portal
|
self.nixosModules.obs-portal
|
||||||
self.nixosModules.matrix
|
self.nixosModules.matrix
|
||||||
self.nixosModules.matrix-irc
|
self.nixosModules.matrix-irc
|
||||||
|
@ -69,139 +41,22 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
metronom = self.inputs.nixpkgs.lib.nixosSystem {
|
flora-6 = self.nixos-flake.lib.mkLinuxSystem {
|
||||||
specialArgs = {
|
imports = [
|
||||||
flake = {
|
|
||||||
inherit self inputs config;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
modules = [
|
|
||||||
self.inputs.agenix.nixosModules.default
|
self.inputs.agenix.nixosModules.default
|
||||||
self.nixosModules.home-manager
|
self.nixosModules.home-manager
|
||||||
./metronom
|
./flora-6
|
||||||
self.nixosModules.overlays
|
|
||||||
self.nixosModules.unlock-zfs-on-boot
|
|
||||||
self.nixosModules.core
|
|
||||||
self.nixosModules.backups
|
|
||||||
self.nixosModules.mail
|
|
||||||
self.nixosModules.prometheus-exporters
|
|
||||||
self.nixosModules.promtail
|
|
||||||
|
|
||||||
self.inputs.simple-nixos-mailserver.nixosModule
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
tankstelle = self.inputs.nixpkgs.lib.nixosSystem {
|
|
||||||
specialArgs = {
|
|
||||||
flake = {
|
|
||||||
inherit self inputs config;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
modules = [
|
|
||||||
self.inputs.agenix.nixosModules.default
|
|
||||||
self.nixosModules.home-manager
|
|
||||||
./tankstelle
|
|
||||||
self.nixosModules.overlays
|
self.nixosModules.overlays
|
||||||
self.nixosModules.core
|
self.nixosModules.core
|
||||||
self.nixosModules.backups
|
|
||||||
self.nixosModules.prometheus-exporters
|
|
||||||
self.nixosModules.promtail
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
trinkgenossin = self.inputs.nixpkgs.lib.nixosSystem {
|
self.nixosModules.caddy
|
||||||
specialArgs = {
|
self.nixosModules.drone
|
||||||
flake = {
|
self.nixosModules.forgejo-actions-runner
|
||||||
inherit self inputs config;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
modules = [
|
|
||||||
self.inputs.agenix.nixosModules.default
|
|
||||||
self.nixosModules.home-manager
|
|
||||||
./trinkgenossin
|
|
||||||
self.nixosModules.backups
|
|
||||||
self.nixosModules.overlays
|
|
||||||
self.nixosModules.unlock-luks-on-boot
|
|
||||||
self.nixosModules.core
|
|
||||||
|
|
||||||
self.nixosModules.garage
|
|
||||||
self.nixosModules.nginx
|
|
||||||
|
|
||||||
# This module is already using options, and those options are used by the grafana module
|
|
||||||
self.nixosModules.keycloak
|
|
||||||
self.nixosModules.grafana
|
self.nixosModules.grafana
|
||||||
self.nixosModules.prometheus
|
self.nixosModules.prometheus
|
||||||
self.nixosModules.loki
|
self.nixosModules.loki
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
delite = self.inputs.nixpkgs.lib.nixosSystem {
|
|
||||||
specialArgs = {
|
|
||||||
flake = {
|
|
||||||
inherit self inputs config;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
modules = [
|
|
||||||
self.inputs.agenix.nixosModules.default
|
|
||||||
self.inputs.disko.nixosModules.disko
|
|
||||||
self.nixosModules.home-manager
|
|
||||||
./delite
|
|
||||||
self.nixosModules.overlays
|
|
||||||
self.nixosModules.unlock-luks-on-boot
|
|
||||||
self.nixosModules.core
|
|
||||||
self.nixosModules.prometheus-exporters
|
|
||||||
self.nixosModules.promtail
|
|
||||||
|
|
||||||
self.nixosModules.garage
|
|
||||||
self.nixosModules.nginx
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
blue-shell = self.inputs.nixpkgs.lib.nixosSystem {
|
|
||||||
specialArgs = {
|
|
||||||
flake = {
|
|
||||||
inherit self inputs config;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
modules = [
|
|
||||||
self.inputs.agenix.nixosModules.default
|
|
||||||
self.inputs.disko.nixosModules.disko
|
|
||||||
self.nixosModules.home-manager
|
|
||||||
./blue-shell
|
|
||||||
self.nixosModules.overlays
|
|
||||||
self.nixosModules.unlock-luks-on-boot
|
|
||||||
self.nixosModules.core
|
|
||||||
self.nixosModules.prometheus-exporters
|
|
||||||
self.nixosModules.promtail
|
|
||||||
|
|
||||||
self.nixosModules.garage
|
|
||||||
self.nixosModules.nginx
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
underground = self.inputs.nixpkgs.lib.nixosSystem {
|
|
||||||
specialArgs = {
|
|
||||||
flake = {
|
|
||||||
inherit self inputs config;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
modules = [
|
|
||||||
self.inputs.agenix.nixosModules.default
|
|
||||||
self.nixosModules.home-manager
|
|
||||||
./underground
|
|
||||||
self.nixosModules.overlays
|
|
||||||
self.nixosModules.unlock-luks-on-boot
|
|
||||||
self.nixosModules.core
|
|
||||||
|
|
||||||
self.nixosModules.backups
|
|
||||||
self.nixosModules.keycloak
|
|
||||||
self.nixosModules.postgresql
|
|
||||||
self.nixosModules.matrix
|
|
||||||
self.nixosModules.matrix-irc
|
|
||||||
self.nixosModules.nginx
|
|
||||||
self.nixosModules.nginx-matrix
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
{
|
|
||||||
flake,
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
boot.loader.grub.enable = true;
|
|
||||||
|
|
||||||
boot.kernelParams = [
|
|
||||||
"boot.shell_on_fail=1"
|
|
||||||
"ip=5.255.119.132::5.255.119.1:255.255.255.0:delite::off"
|
|
||||||
];
|
|
||||||
|
|
||||||
# This option defines the first version of NixOS you have installed on this particular machine,
|
|
||||||
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
|
|
||||||
#
|
|
||||||
# Most users should NEVER change this value after the initial install, for any reason,
|
|
||||||
# even if you've upgraded your system to a new NixOS release.
|
|
||||||
#
|
|
||||||
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
|
|
||||||
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
|
|
||||||
# to actually do that.
|
|
||||||
#
|
|
||||||
# This value being lower than the current NixOS release does NOT mean your system is
|
|
||||||
# out of date, out of support, or vulnerable.
|
|
||||||
#
|
|
||||||
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
|
|
||||||
# and migrated your data accordingly.
|
|
||||||
#
|
|
||||||
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
|
||||||
system.stateVersion = "24.05"; # Did you read the comment?
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{ flake, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./hardware-configuration.nix
|
|
||||||
./configuration.nix
|
|
||||||
./disk-config.nix
|
|
||||||
|
|
||||||
./networking.nix
|
|
||||||
./wireguard.nix
|
|
||||||
#./backups.nix
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
{
|
|
||||||
disko.devices = {
|
|
||||||
disk = {
|
|
||||||
main = {
|
|
||||||
type = "disk";
|
|
||||||
device = "/dev/vda";
|
|
||||||
content = {
|
|
||||||
type = "gpt";
|
|
||||||
partitions = {
|
|
||||||
bios = {
|
|
||||||
size = "1M";
|
|
||||||
type = "EF02"; # for grub MBR
|
|
||||||
};
|
|
||||||
boot = {
|
|
||||||
size = "1G";
|
|
||||||
type = "8300";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "ext4";
|
|
||||||
mountpoint = "/boot";
|
|
||||||
mountOptions = [ "defaults" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
luks = {
|
|
||||||
size = "100%";
|
|
||||||
content = {
|
|
||||||
type = "luks";
|
|
||||||
name = "cryptroot";
|
|
||||||
extraOpenArgs = [ ];
|
|
||||||
# if you want to use the key for interactive login be sure there is no trailing newline
|
|
||||||
# for example use `echo -n "password" > /tmp/secret.key`
|
|
||||||
passwordFile = "/tmp/luks-password";
|
|
||||||
content = {
|
|
||||||
type = "lvm_pv";
|
|
||||||
vg = "vg0";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
lvm_vg = {
|
|
||||||
vg0 = {
|
|
||||||
type = "lvm_vg";
|
|
||||||
lvs = {
|
|
||||||
root = {
|
|
||||||
size = "40G";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "ext4";
|
|
||||||
mountpoint = "/";
|
|
||||||
mountOptions = [ "defaults" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
swap = {
|
|
||||||
size = "8G";
|
|
||||||
content = {
|
|
||||||
type = "swap";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
data = {
|
|
||||||
size = "800G";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "xfs";
|
|
||||||
mountpoint = "/var/lib/garage/data";
|
|
||||||
mountOptions = [ "defaults" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
metadata = {
|
|
||||||
size = "50G";
|
|
||||||
content = {
|
|
||||||
type = "filesystem";
|
|
||||||
format = "btrfs";
|
|
||||||
mountpoint = "/var/lib/garage/meta";
|
|
||||||
mountOptions = [ "defaults" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
|
||||||
"ata_piix"
|
|
||||||
"uhci_hcd"
|
|
||||||
"virtio_pci"
|
|
||||||
"virtio_blk"
|
|
||||||
];
|
|
||||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
|
||||||
boot.kernelModules = [ ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
services.garage.settings.rpc_public_addr = "[2a04:52c0:124:9d8c::2]:3901";
|
|
||||||
|
|
||||||
networking.hostName = "delite";
|
|
||||||
networking.hostId = "00000004";
|
|
||||||
|
|
||||||
networking.useDHCP = false;
|
|
||||||
systemd.network.enable = true;
|
|
||||||
systemd.network.networks."10-wan" = {
|
|
||||||
matchConfig.Name = "ens3";
|
|
||||||
address = [
|
|
||||||
"5.255.119.132/24"
|
|
||||||
"2a04:52c0:124:9d8c::2/48"
|
|
||||||
];
|
|
||||||
gateway = [
|
|
||||||
"5.255.119.1"
|
|
||||||
"2a04:52c0:124::1"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
wireguardIPv4 = "10.7.6.6";
|
|
||||||
wireguardIPv6 = "fd00:fae:fae:fae:fae:6::";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
|
||||||
|
|
||||||
age.secrets.wg-private-key.file = "${flake.self}/secrets/delite-wg-private-key.age";
|
|
||||||
|
|
||||||
networking.wireguard.interfaces = {
|
|
||||||
wg-ssh = {
|
|
||||||
listenPort = 51820;
|
|
||||||
mtu = 1300;
|
|
||||||
ips = [
|
|
||||||
"${wireguardIPv4}/32"
|
|
||||||
"${wireguardIPv6}/96"
|
|
||||||
];
|
|
||||||
privateKeyFile = config.age.secrets.wg-private-key.path;
|
|
||||||
peers = flake.self.logins.wireguardDevices ++ [
|
|
||||||
{
|
|
||||||
# trinkgenossin.pub.solar
|
|
||||||
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.5/32"
|
|
||||||
"fd00:fae:fae:fae:fae:5::/96"
|
|
||||||
];
|
|
||||||
#endpoint = "85.215.152.22:51820";
|
|
||||||
endpoint = "[2a01:239:35d:f500::1]:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.openssh.listenAddresses = [
|
|
||||||
{
|
|
||||||
addr = wireguardIPv4;
|
|
||||||
port = 22;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
addr = "[${wireguardIPv6}]";
|
|
||||||
port = 22;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
71
hosts/flora-6/configuration.nix
Normal file
71
hosts/flora-6/configuration.nix
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, flake
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
psCfg = config.pub-solar;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
# Override nix.conf for more agressive garbage collection
|
||||||
|
nix.extraOptions = lib.mkForce ''
|
||||||
|
experimental-features = flakes nix-command
|
||||||
|
min-free = 536870912
|
||||||
|
keep-outputs = false
|
||||||
|
keep-derivations = false
|
||||||
|
fallback = true
|
||||||
|
'';
|
||||||
|
|
||||||
|
# # #
|
||||||
|
# # # Triton host specific options
|
||||||
|
# # # DO NOT ALTER below this line, changes might render system unbootable
|
||||||
|
# # #
|
||||||
|
|
||||||
|
# Use the systemd-boot EFI boot loader.
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
# Force getting the hostname from cloud-init
|
||||||
|
networking.hostName = lib.mkDefault "";
|
||||||
|
|
||||||
|
# We use cloud-init to configure networking, this option should fix
|
||||||
|
# systemd-networkd-wait-online timeouts
|
||||||
|
#systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||||
|
systemd.network.wait-online.ignoredInterfaces = [
|
||||||
|
"docker0"
|
||||||
|
"wg-ssh"
|
||||||
|
];
|
||||||
|
|
||||||
|
# List services that you want to enable:
|
||||||
|
services.cloud-init.enable = true;
|
||||||
|
services.cloud-init.ext4.enable = true;
|
||||||
|
services.cloud-init.network.enable = true;
|
||||||
|
# use the default NixOS cloud-init config, but add some SmartOS customization to it
|
||||||
|
environment.etc."cloud/cloud.cfg.d/90_smartos.cfg".text = ''
|
||||||
|
datasource_list: [ SmartOS ]
|
||||||
|
|
||||||
|
# Do not create the centos/ubuntu/debian user
|
||||||
|
users: [ ]
|
||||||
|
|
||||||
|
# mount second disk with label ephemeral0, gets formated by cloud-init
|
||||||
|
# this will fail to get added to /etc/fstab as it's read-only, but should
|
||||||
|
# mount at boot anyway
|
||||||
|
mounts:
|
||||||
|
- [ vdb, /data, auto, "defaults,nofail" ]
|
||||||
|
'';
|
||||||
|
|
||||||
|
# We manage the firewall with nix, too
|
||||||
|
# altough triton can also manage firewall rules via the triton fwrule subcommand
|
||||||
|
networking.firewall.enable = true;
|
||||||
|
|
||||||
|
# This value determines the NixOS release from which the default
|
||||||
|
# settings for stateful data, like file locations and database versions
|
||||||
|
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||||
|
# this value at the release version of the first install of this system.
|
||||||
|
# Before changing this value read the documentation for this option
|
||||||
|
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||||
|
system.stateVersion = "22.05"; # Did you read the comment?
|
||||||
|
};
|
||||||
|
}
|
12
hosts/flora-6/default.nix
Normal file
12
hosts/flora-6/default.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[
|
||||||
|
# Include the results of the hardware scan.
|
||||||
|
./hardware-configuration.nix
|
||||||
|
./configuration.nix
|
||||||
|
./triton-vmtools.nix
|
||||||
|
./wireguard.nix
|
||||||
|
];
|
||||||
|
}
|
44
hosts/flora-6/hardware-configuration.nix
Normal file
44
hosts/flora-6/hardware-configuration.nix
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, modulesPath
|
||||||
|
, ...
|
||||||
|
}: {
|
||||||
|
imports = [ ];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "ahci" "virtio_pci" "xhci_pci" "sr_mod" "virtio_blk" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-label/nixos";
|
||||||
|
autoResize = true;
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-label/boot";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/data" = {
|
||||||
|
device = "/dev/disk/by-label/ephemeral0";
|
||||||
|
fsType = "ext4";
|
||||||
|
options = [
|
||||||
|
"defaults"
|
||||||
|
"nofail"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
networking.useDHCP = lib.mkDefault false;
|
||||||
|
networking.networkmanager.enable = lib.mkForce false;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
8
hosts/flora-6/triton-vmtools.nix
Normal file
8
hosts/flora-6/triton-vmtools.nix
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{ pkgs
|
||||||
|
, flake
|
||||||
|
, ...
|
||||||
|
}: {
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
flake.inputs.triton-vmtools.packages.${pkgs.system}.default
|
||||||
|
];
|
||||||
|
}
|
40
hosts/flora-6/wireguard.nix
Normal file
40
hosts/flora-6/wireguard.nix
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
flake,
|
||||||
|
... }:
|
||||||
|
{
|
||||||
|
networking.firewall.allowedUDPPorts = [ 51820 ];
|
||||||
|
|
||||||
|
age.secrets.wg-private-key.file = "${flake.self}/secrets/flora6-wg-private-key.age";
|
||||||
|
|
||||||
|
networking.wireguard.interfaces = {
|
||||||
|
wg-ssh = {
|
||||||
|
listenPort = 51820;
|
||||||
|
mtu = 1300;
|
||||||
|
ips = [
|
||||||
|
"10.7.6.2/32"
|
||||||
|
"fd00:fae:fae:fae:fae:2::/96"
|
||||||
|
];
|
||||||
|
privateKeyFile = config.age.secrets.wg-private-key.path;
|
||||||
|
peers = flake.self.logins.admins.wireguardDevices ++ [
|
||||||
|
{ # nachtigall.pub.solar
|
||||||
|
endpoint = "138.201.80.102:51820";
|
||||||
|
publicKey = "qzNywKY9RvqTnDO8eLik75/SHveaSk9OObilDzv+xkk=";
|
||||||
|
allowedIPs = [ "10.7.6.1/32" "fd00:fae:fae:fae:fae:1::/96" ];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh.listenAddresses = [
|
||||||
|
{
|
||||||
|
addr = "10.7.6.2";
|
||||||
|
port = 22;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
addr = "[fd00:fae:fae:fae:fae:2::]";
|
||||||
|
port = 22;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
|
@ -1,29 +0,0 @@
|
||||||
{ config, flake, ... }:
|
|
||||||
{
|
|
||||||
age.secrets."restic-repo-storagebox-metronom" = {
|
|
||||||
file = "${flake.self}/secrets/restic-repo-storagebox-metronom.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "root";
|
|
||||||
};
|
|
||||||
age.secrets.restic-repo-garage-metronom = {
|
|
||||||
file = "${flake.self}/secrets/restic-repo-garage-metronom.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "root";
|
|
||||||
};
|
|
||||||
age.secrets.restic-repo-garage-metronom-env = {
|
|
||||||
file = "${flake.self}/secrets/restic-repo-garage-metronom-env.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "root";
|
|
||||||
};
|
|
||||||
|
|
||||||
pub-solar-os.backups.repos.storagebox = {
|
|
||||||
passwordFile = config.age.secrets."restic-repo-storagebox-metronom".path;
|
|
||||||
repository = "sftp:u377325@u377325.your-storagebox.de:/metronom-backups";
|
|
||||||
};
|
|
||||||
|
|
||||||
pub-solar-os.backups.repos.garage = {
|
|
||||||
passwordFile = config.age.secrets."restic-repo-garage-metronom".path;
|
|
||||||
environmentFile = config.age.secrets."restic-repo-garage-metronom-env".path;
|
|
||||||
repository = "s3:https://buckets.pub.solar/metronom-backups";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
{
|
|
||||||
flake,
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
|
||||||
boot.supportedFilesystems = [ "zfs" ];
|
|
||||||
|
|
||||||
boot.kernelParams = [
|
|
||||||
"boot.shell_on_fail=1"
|
|
||||||
"ip=dhcp"
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "igb" ];
|
|
||||||
|
|
||||||
# https://nixos.wiki/wiki/ZFS#declarative_mounting_of_ZFS_datasets
|
|
||||||
systemd.services.zfs-mount.enable = false;
|
|
||||||
|
|
||||||
services.zfs.autoScrub = {
|
|
||||||
enable = true;
|
|
||||||
pools = [ "root_pool" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Declarative SSH private key
|
|
||||||
age.secrets."metronom-root-ssh-key" = {
|
|
||||||
file = "${flake.self}/secrets/metronom-root-ssh-key.age";
|
|
||||||
path = "/root/.ssh/id_ed25519";
|
|
||||||
mode = "400";
|
|
||||||
owner = "root";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Declarative SSH private key
|
|
||||||
#age.secrets."metronom-root-ssh-key" = {
|
|
||||||
# file = "${flake.self}/secrets/metronom-root-ssh-key.age";
|
|
||||||
# path = "/root/.ssh/id_ed25519";
|
|
||||||
# mode = "400";
|
|
||||||
# owner = "root";
|
|
||||||
#};
|
|
||||||
|
|
||||||
# This value determines the NixOS release with which your system is to be
|
|
||||||
# compatible, in order to avoid breaking some software such as database
|
|
||||||
# servers. You should change this only after NixOS release notes say you
|
|
||||||
# should.
|
|
||||||
system.stateVersion = "23.11"; # Did you read the comment?
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
{ flake, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./hardware-configuration.nix
|
|
||||||
./configuration.nix
|
|
||||||
|
|
||||||
./networking.nix
|
|
||||||
./wireguard.nix
|
|
||||||
./backups.nix
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
|
||||||
"xhci_pci"
|
|
||||||
"virtio_pci"
|
|
||||||
"virtio_scsi"
|
|
||||||
"usbhid"
|
|
||||||
"sr_mod"
|
|
||||||
];
|
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.kernelModules = [ ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
fileSystems."/" = {
|
|
||||||
device = "root_pool/root";
|
|
||||||
fsType = "zfs";
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
|
||||||
device = "/dev/disk/by-uuid/2083-C68E";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices = [ ];
|
|
||||||
|
|
||||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
|
||||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
|
||||||
# still possible to use this option, but it's recommended to use it in conjunction
|
|
||||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
|
||||||
networking.useDHCP = lib.mkDefault true;
|
|
||||||
# networking.interfaces.eth0.useDHCP = lib.mkDefault true;
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
|
|
||||||
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
|
|
||||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
|
|
||||||
networking.hostName = "metronom";
|
|
||||||
networking.extraHosts = ''
|
|
||||||
127.0.0.2 mail.pub.solar mail
|
|
||||||
::1 mail.pub.solar mail
|
|
||||||
'';
|
|
||||||
networking.hostId = "00000002";
|
|
||||||
|
|
||||||
networking.enableIPv6 = true;
|
|
||||||
networking.useDHCP = false;
|
|
||||||
networking.interfaces."enp1s0".useDHCP = true;
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
|
||||||
|
|
||||||
age.secrets.wg-private-key.file = "${flake.self}/secrets/metronom-wg-private-key.age";
|
|
||||||
|
|
||||||
networking.wireguard.interfaces = {
|
|
||||||
wg-ssh = {
|
|
||||||
listenPort = 51820;
|
|
||||||
mtu = 1300;
|
|
||||||
ips = [
|
|
||||||
"10.7.6.3/32"
|
|
||||||
"fd00:fae:fae:fae:fae:3::/96"
|
|
||||||
];
|
|
||||||
privateKeyFile = config.age.secrets.wg-private-key.path;
|
|
||||||
peers = flake.self.logins.wireguardDevices ++ [
|
|
||||||
{
|
|
||||||
# nachtigall.pub.solar
|
|
||||||
endpoint = "138.201.80.102:51820";
|
|
||||||
publicKey = "qzNywKY9RvqTnDO8eLik75/SHveaSk9OObilDzv+xkk=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.1/32"
|
|
||||||
"fd00:fae:fae:fae:fae:1::/96"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# trinkgenossin.pub.solar
|
|
||||||
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.5/32"
|
|
||||||
"fd00:fae:fae:fae:fae:5::/96"
|
|
||||||
];
|
|
||||||
#endpoint = "85.215.152.22:51820";
|
|
||||||
endpoint = "[2a01:239:35d:f500::1]:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.openssh.listenAddresses = [
|
|
||||||
{
|
|
||||||
addr = "10.7.6.3";
|
|
||||||
port = 22;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
addr = "[fd00:fae:fae:fae:fae:3::]";
|
|
||||||
port = 22;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,34 +1,12 @@
|
||||||
{ config, flake, ... }:
|
{ flake, ... }: {
|
||||||
{
|
|
||||||
age.secrets."restic-repo-droppie" = {
|
age.secrets."restic-repo-droppie" = {
|
||||||
file = "${flake.self}/secrets/restic-repo-droppie.age";
|
file = "${flake.self}/secrets/restic-repo-droppie.age";
|
||||||
mode = "400";
|
mode = "400";
|
||||||
owner = "root";
|
owner = "root";
|
||||||
};
|
};
|
||||||
age.secrets."restic-repo-storagebox-nachtigall" = {
|
age.secrets."restic-repo-storagebox" = {
|
||||||
file = "${flake.self}/secrets/restic-repo-storagebox-nachtigall.age";
|
file = "${flake.self}/secrets/restic-repo-storagebox.age";
|
||||||
mode = "400";
|
mode = "400";
|
||||||
owner = "root";
|
owner = "root";
|
||||||
};
|
};
|
||||||
age.secrets.restic-repo-garage-nachtigall = {
|
|
||||||
file = "${flake.self}/secrets/restic-repo-garage-nachtigall.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "root";
|
|
||||||
};
|
|
||||||
age.secrets.restic-repo-garage-nachtigall-env = {
|
|
||||||
file = "${flake.self}/secrets/restic-repo-garage-nachtigall-env.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "root";
|
|
||||||
};
|
|
||||||
|
|
||||||
pub-solar-os.backups.repos.storagebox = {
|
|
||||||
passwordFile = config.age.secrets."restic-repo-storagebox-nachtigall".path;
|
|
||||||
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
|
|
||||||
};
|
|
||||||
|
|
||||||
pub-solar-os.backups.repos.garage = {
|
|
||||||
passwordFile = config.age.secrets."restic-repo-garage-nachtigall".path;
|
|
||||||
environmentFile = config.age.secrets."restic-repo-garage-nachtigall-env".path;
|
|
||||||
repository = "s3:https://buckets.pub.solar/nachtigall-backups";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
{
|
{ flake
|
||||||
flake,
|
, config
|
||||||
config,
|
, pkgs
|
||||||
pkgs,
|
, ...
|
||||||
...
|
}: {
|
||||||
}:
|
|
||||||
{
|
|
||||||
# Use GRUB2 as the boot loader.
|
# Use GRUB2 as the boot loader.
|
||||||
# We don't use systemd-boot because Hetzner uses BIOS legacy boot.
|
# We don't use systemd-boot because Hetzner uses BIOS legacy boot.
|
||||||
boot.loader.systemd-boot.enable = false;
|
boot.loader.systemd-boot.enable = false;
|
||||||
|
@ -13,11 +11,15 @@
|
||||||
efiSupport = false;
|
efiSupport = false;
|
||||||
mirroredBoots = [
|
mirroredBoots = [
|
||||||
{
|
{
|
||||||
devices = [ "/dev/disk/by-id/nvme-SAMSUNG_MZVL21T0HCLR-00B00_S676NF0R517371" ];
|
devices = [
|
||||||
|
"/dev/disk/by-id/nvme-SAMSUNG_MZVL21T0HCLR-00B00_S676NF0R517371"
|
||||||
|
];
|
||||||
path = "/boot1";
|
path = "/boot1";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
devices = [ "/dev/disk/by-id/nvme-KXG60ZNV1T02_TOSHIBA_Z9NF704ZF9ZL" ];
|
devices = [
|
||||||
|
"/dev/disk/by-id/nvme-KXG60ZNV1T02_TOSHIBA_Z9NF704ZF9ZL"
|
||||||
|
];
|
||||||
path = "/boot2";
|
path = "/boot2";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -35,11 +37,6 @@
|
||||||
# https://nixos.wiki/wiki/ZFS#declarative_mounting_of_ZFS_datasets
|
# https://nixos.wiki/wiki/ZFS#declarative_mounting_of_ZFS_datasets
|
||||||
systemd.services.zfs-mount.enable = false;
|
systemd.services.zfs-mount.enable = false;
|
||||||
|
|
||||||
services.zfs.autoScrub = {
|
|
||||||
enable = true;
|
|
||||||
pools = [ "root_pool" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Declarative SSH private key
|
# Declarative SSH private key
|
||||||
age.secrets."nachtigall-root-ssh-key" = {
|
age.secrets."nachtigall-root-ssh-key" = {
|
||||||
file = "${flake.self}/secrets/nachtigall-root-ssh-key.age";
|
file = "${flake.self}/secrets/nachtigall-root-ssh-key.age";
|
||||||
|
@ -48,78 +45,6 @@
|
||||||
owner = "root";
|
owner = "root";
|
||||||
};
|
};
|
||||||
|
|
||||||
# keycloak
|
|
||||||
age.secrets.keycloak-database-password = {
|
|
||||||
file = "${flake.self}/secrets/keycloak-database-password.age";
|
|
||||||
mode = "600";
|
|
||||||
#owner = "keycloak";
|
|
||||||
};
|
|
||||||
|
|
||||||
pub-solar-os.auth = {
|
|
||||||
enable = true;
|
|
||||||
database-password-file = config.age.secrets.keycloak-database-password.path;
|
|
||||||
};
|
|
||||||
|
|
||||||
# matrix-synapse
|
|
||||||
age.secrets."matrix-synapse-signing-key" = {
|
|
||||||
file = "${flake.self}/secrets/matrix-synapse-signing-key.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "matrix-synapse";
|
|
||||||
};
|
|
||||||
|
|
||||||
age.secrets."matrix-synapse-secret-config.yaml" = {
|
|
||||||
file = "${flake.self}/secrets/matrix-synapse-secret-config.yaml.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "matrix-synapse";
|
|
||||||
};
|
|
||||||
|
|
||||||
age.secrets."matrix-synapse-sliding-sync-secret" = {
|
|
||||||
file = "${flake.self}/secrets/matrix-synapse-sliding-sync-secret.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "matrix-synapse";
|
|
||||||
};
|
|
||||||
|
|
||||||
age.secrets."matrix-authentication-service-secret-config.yml" = {
|
|
||||||
file = "${flake.self}/secrets/matrix-authentication-service-secret-config.yml.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "matrix-authentication-service";
|
|
||||||
};
|
|
||||||
|
|
||||||
pub-solar-os.matrix = {
|
|
||||||
enable = true;
|
|
||||||
synapse = {
|
|
||||||
sliding-sync.enable = false;
|
|
||||||
signing_key_path = config.age.secrets."matrix-synapse-signing-key".path;
|
|
||||||
extra-config-files = [
|
|
||||||
config.age.secrets."matrix-synapse-secret-config.yaml".path
|
|
||||||
|
|
||||||
# The registration file is automatically generated after starting the
|
|
||||||
# appservice for the first time.
|
|
||||||
# cp /var/lib/mautrix-telegram/telegram-registration.yaml \
|
|
||||||
# /var/lib/matrix-synapse/
|
|
||||||
# chown matrix-synapse:matrix-synapse \
|
|
||||||
# /var/lib/matrix-synapse/telegram-registration.yaml
|
|
||||||
"/var/lib/matrix-synapse/telegram-registration.yaml"
|
|
||||||
];
|
|
||||||
app-service-config-files = [
|
|
||||||
"/var/lib/matrix-synapse/telegram-registration.yaml"
|
|
||||||
"/var/lib/matrix-appservice-irc/registration.yml"
|
|
||||||
# "/matrix-appservice-slack-registration.yaml"
|
|
||||||
# "/hookshot-registration.yml"
|
|
||||||
# "/matrix-mautrix-signal-registration.yaml"
|
|
||||||
# "/matrix-mautrix-telegram-registration.yaml"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
matrix-authentication-service.extra-config-files = [
|
|
||||||
config.age.secrets."matrix-authentication-service-secret-config.yml".path
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.postgresql = {
|
|
||||||
after = [ "var-lib-postgresql.mount" ];
|
|
||||||
requisite = [ "var-lib-postgresql.mount" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# This value determines the NixOS release with which your system is to be
|
# This value determines the NixOS release with which your system is to be
|
||||||
# compatible, in order to avoid breaking some software such as database
|
# compatible, in order to avoid breaking some software such as database
|
||||||
# servers. You should change this only after NixOS release notes say you
|
# servers. You should change this only after NixOS release notes say you
|
||||||
|
|
|
@ -1,20 +1,15 @@
|
||||||
{ flake, ... }:
|
{ flake, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports =
|
||||||
# Include the results of the hardware scan.
|
[
|
||||||
./hardware-configuration.nix
|
# Include the results of the hardware scan.
|
||||||
./configuration.nix
|
./hardware-configuration.nix
|
||||||
|
./configuration.nix
|
||||||
|
|
||||||
./networking.nix
|
./networking.nix
|
||||||
./wireguard.nix
|
./wireguard.nix
|
||||||
./backups.nix
|
./backups.nix
|
||||||
"${flake.inputs.fork}/nixos/modules/services//matrix/matrix-authentication-service.nix"
|
|
||||||
"${flake.inputs.unstable}/nixos/modules/services/web-apps/mastodon.nix"
|
|
||||||
];
|
|
||||||
|
|
||||||
disabledModules = [
|
];
|
||||||
"services/matrix/matrix-authentication-service.nix "
|
|
||||||
"services/web-apps/mastodon.nix"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +1,54 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
# and may be overwritten by future invocations. Please make changes
|
# and may be overwritten by future invocations. Please make changes
|
||||||
# to /etc/nixos/configuration.nix instead.
|
# to /etc/nixos/configuration.nix instead.
|
||||||
{
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
|
imports =
|
||||||
|
[
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
boot.initrd.availableKernelModules = [ "ahci" "nvme" ];
|
||||||
"ahci"
|
|
||||||
"nvme"
|
|
||||||
];
|
|
||||||
boot.initrd.kernelModules = [ ];
|
boot.initrd.kernelModules = [ ];
|
||||||
boot.kernelModules = [ "kvm-amd" ];
|
boot.kernelModules = [ "kvm-amd" ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
fileSystems."/" = {
|
fileSystems."/" =
|
||||||
device = "root_pool/root";
|
{
|
||||||
fsType = "zfs";
|
device = "root_pool/root";
|
||||||
};
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
fileSystems."/var/lib" = {
|
fileSystems."/var/lib" =
|
||||||
device = "root_pool/data";
|
{
|
||||||
fsType = "zfs";
|
device = "root_pool/data";
|
||||||
};
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
fileSystems."/var/lib/postgresql" = {
|
fileSystems."/var/lib/postgresql" =
|
||||||
device = "root_pool/data/postgresql";
|
{
|
||||||
fsType = "zfs";
|
device = "root_pool/data/postgresql";
|
||||||
};
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
fileSystems."/var/lib/docker" = {
|
fileSystems."/var/lib/docker" =
|
||||||
device = "root_pool/data/docker";
|
{
|
||||||
fsType = "zfs";
|
device = "root_pool/data/docker";
|
||||||
};
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
fileSystems."/boot1" = {
|
fileSystems."/boot1" =
|
||||||
device = "/dev/disk/by-uuid/5493-EFF5";
|
{
|
||||||
fsType = "vfat";
|
device = "/dev/disk/by-uuid/5493-EFF5";
|
||||||
};
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
|
||||||
fileSystems."/boot2" = {
|
fileSystems."/boot2" =
|
||||||
device = "/dev/disk/by-uuid/5494-BA1E";
|
{
|
||||||
fsType = "vfat";
|
device = "/dev/disk/by-uuid/5494-BA1E";
|
||||||
};
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
|
||||||
swapDevices = [ ];
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
flake,
|
flake,
|
||||||
...
|
... }:
|
||||||
}:
|
|
||||||
{
|
{
|
||||||
|
|
||||||
networking.hostName = "nachtigall";
|
networking.hostName = "nachtigall";
|
||||||
|
networking.domain = "pub.solar";
|
||||||
networking.hostId = "00000001";
|
networking.hostId = "00000001";
|
||||||
|
|
||||||
# Network (Hetzner uses static IP assignments, and we don't use DHCP here)
|
# Network (Hetzner uses static IP assignments, and we don't use DHCP here)
|
||||||
|
@ -24,8 +24,5 @@
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
networking.defaultGateway = "138.201.80.65";
|
networking.defaultGateway = "138.201.80.65";
|
||||||
networking.defaultGateway6 = {
|
networking.defaultGateway6 = { address = "fe80::1"; interface = "enp35s0"; };
|
||||||
address = "fe80::1";
|
|
||||||
interface = "enp35s0";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
flake,
|
flake,
|
||||||
...
|
... }:
|
||||||
}:
|
|
||||||
{
|
{
|
||||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
networking.firewall.allowedUDPPorts = [ 51820 ];
|
||||||
|
|
||||||
|
@ -18,32 +17,17 @@
|
||||||
"fd00:fae:fae:fae:fae:1::/96"
|
"fd00:fae:fae:fae:fae:1::/96"
|
||||||
];
|
];
|
||||||
privateKeyFile = config.age.secrets.wg-private-key.path;
|
privateKeyFile = config.age.secrets.wg-private-key.path;
|
||||||
peers = flake.self.logins.wireguardDevices ++ [
|
peers = flake.self.logins.admins.wireguardDevices ++ [
|
||||||
{
|
{ # flora-6.pub.solar
|
||||||
# tankstelle.pub.solar
|
endpoint = "80.71.153.210:51820";
|
||||||
endpoint = "80.244.242.5:51820";
|
publicKey = "jtSR5G2P/nm9s8WrVc26Xc/SQLupRxyXE+5eIeqlsTU=";
|
||||||
publicKey = "iRTlY1lB7nPXf2eXzX8ZZDkfMmXyGjff5/joccbP8Cg=";
|
allowedIPs = [ "10.7.6.2/32" "fd00:fae:fae:fae:fae:2::/96" ];
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.4/32"
|
|
||||||
"fd00:fae:fae:fae:fae:4::/96"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# trinkgenossin.pub.solar
|
|
||||||
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.5/32"
|
|
||||||
"fd00:fae:fae:fae:fae:5::/96"
|
|
||||||
];
|
|
||||||
#endpoint = "85.215.152.22:51820";
|
|
||||||
endpoint = "[2a01:239:35d:f500::1]:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.openssh.listenAddresses = [
|
services.openssh.listenAddresses = [
|
||||||
{
|
{
|
||||||
addr = "10.7.6.1";
|
addr = "10.7.6.1";
|
||||||
port = 22;
|
port = 22;
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
{ flake, ... }:
|
|
||||||
{
|
|
||||||
age.secrets."restic-repo-droppie" = {
|
|
||||||
file = "${flake.self}/secrets/restic-repo-droppie.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "root";
|
|
||||||
};
|
|
||||||
age.secrets."restic-repo-storagebox-tankstelle" = {
|
|
||||||
file = "${flake.self}/secrets/restic-repo-storagebox-tankstelle.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "root";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
flake,
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
imports = [ ./hardware-configuration.nix ];
|
|
||||||
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
|
||||||
|
|
||||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
|
||||||
|
|
||||||
system.stateVersion = "23.11";
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
{ flake, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./hardware-configuration.nix
|
|
||||||
./configuration.nix
|
|
||||||
|
|
||||||
./networking.nix
|
|
||||||
./forgejo-actions-runner.nix
|
|
||||||
./wireguard.nix
|
|
||||||
#./backups.nix
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
age.secrets.tankstelle-forgejo-actions-runner-token = {
|
|
||||||
file = "${flake.self}/secrets/tankstelle-forgejo-actions-runner-token.age";
|
|
||||||
mode = "440";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Trust docker bridge interface traffic
|
|
||||||
# Needed for the docker runner to communicate with the act_runner cache
|
|
||||||
networking.firewall.trustedInterfaces = [ "br-+" ];
|
|
||||||
|
|
||||||
users.users.gitea-runner = {
|
|
||||||
home = "/var/lib/gitea-runner/tankstelle";
|
|
||||||
useDefaultShell = true;
|
|
||||||
group = "gitea-runner";
|
|
||||||
# Required to interact with nix daemon
|
|
||||||
extraGroups = [ "wheel" ];
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups.gitea-runner = { };
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [ "d '/var/lib/gitea-runner' 0750 gitea-runner gitea-runner - -" ];
|
|
||||||
|
|
||||||
systemd.services."gitea-runner-tankstelle" = {
|
|
||||||
serviceConfig.DynamicUser = lib.mkForce false;
|
|
||||||
path = with pkgs; [
|
|
||||||
coreutils
|
|
||||||
bash
|
|
||||||
coreutils
|
|
||||||
curl
|
|
||||||
gawk
|
|
||||||
gitMinimal
|
|
||||||
gnused
|
|
||||||
nodejs
|
|
||||||
wget
|
|
||||||
cachix
|
|
||||||
jq
|
|
||||||
nix
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# forgejo actions runner
|
|
||||||
# https://forgejo.org/docs/latest/admin/actions/
|
|
||||||
# https://docs.gitea.com/usage/actions/quickstart
|
|
||||||
services.gitea-actions-runner = {
|
|
||||||
package = pkgs.forgejo-runner;
|
|
||||||
instances."tankstelle" = {
|
|
||||||
enable = true;
|
|
||||||
name = config.networking.hostName;
|
|
||||||
url = "https://git.pub.solar";
|
|
||||||
tokenFile = config.age.secrets.tankstelle-forgejo-actions-runner-token.path;
|
|
||||||
labels = [ "self-hosted:host://-self-hosted" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
|
||||||
"ahci"
|
|
||||||
"xhci_pci"
|
|
||||||
"virtio_pci"
|
|
||||||
"sr_mod"
|
|
||||||
"virtio_blk"
|
|
||||||
];
|
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.kernelModules = [ "kvm-intel" ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
fileSystems."/" = {
|
|
||||||
device = "/dev/disk/by-uuid/17531ffc-46bd-4259-8287-2dea73804b5b";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
|
||||||
device = "/dev/disk/by-uuid/AF98-AA5C";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices = [ { device = "/dev/disk/by-uuid/7aee04b5-1ef9-43de-acb4-70ac1238b58a"; } ];
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
|
||||||
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
|
|
||||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
networking = {
|
|
||||||
hostName = "tankstelle";
|
|
||||||
enableIPv6 = true;
|
|
||||||
defaultGateway = {
|
|
||||||
address = "80.244.242.1";
|
|
||||||
interface = "enp1s0";
|
|
||||||
};
|
|
||||||
defaultGateway6 = {
|
|
||||||
address = "2001:4d88:1ffa:26::1";
|
|
||||||
interface = "enp1s0";
|
|
||||||
};
|
|
||||||
nameservers = [
|
|
||||||
"95.129.51.51"
|
|
||||||
"80.244.244.244"
|
|
||||||
];
|
|
||||||
interfaces."enp1s0" = {
|
|
||||||
ipv4.addresses = [
|
|
||||||
{
|
|
||||||
address = "80.244.242.5";
|
|
||||||
prefixLength = 29;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
ipv6.addresses = [
|
|
||||||
{
|
|
||||||
address = "2001:4d88:1ffa:26::5";
|
|
||||||
prefixLength = 64;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
|
||||||
|
|
||||||
age.secrets.wg-private-key.file = "${flake.self}/secrets/tankstelle-wg-private-key.age";
|
|
||||||
|
|
||||||
networking.wireguard.interfaces = {
|
|
||||||
wg-ssh = {
|
|
||||||
listenPort = 51820;
|
|
||||||
mtu = 1300;
|
|
||||||
ips = [
|
|
||||||
"10.7.6.4/32"
|
|
||||||
"fd00:fae:fae:fae:fae:4::/96"
|
|
||||||
];
|
|
||||||
privateKeyFile = config.age.secrets.wg-private-key.path;
|
|
||||||
peers = flake.self.logins.wireguardDevices ++ [
|
|
||||||
{
|
|
||||||
# nachtigall.pub.solar
|
|
||||||
endpoint = "138.201.80.102:51820";
|
|
||||||
publicKey = "qzNywKY9RvqTnDO8eLik75/SHveaSk9OObilDzv+xkk=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.1/32"
|
|
||||||
"fd00:fae:fae:fae:fae:1::/96"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# trinkgenossin.pub.solar
|
|
||||||
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.5/32"
|
|
||||||
"fd00:fae:fae:fae:fae:5::/96"
|
|
||||||
];
|
|
||||||
#endpoint = "85.215.152.22:51820";
|
|
||||||
endpoint = "[2a01:239:35d:f500::1]:51820";
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.openssh.listenAddresses = [
|
|
||||||
{
|
|
||||||
addr = "10.7.6.4";
|
|
||||||
port = 22;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
addr = "[fd00:fae:fae:fae:fae:4::]";
|
|
||||||
port = 22;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
{
|
|
||||||
flake,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
boot.loader.grub.enable = true;
|
|
||||||
boot.loader.grub.devices = [ "/dev/vda" ];
|
|
||||||
|
|
||||||
boot.kernelParams = [
|
|
||||||
"boot.shell_on_fail=1"
|
|
||||||
"ip=dhcp"
|
|
||||||
];
|
|
||||||
|
|
||||||
# This option defines the first version of NixOS you have installed on this particular machine,
|
|
||||||
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
|
|
||||||
#
|
|
||||||
# Most users should NEVER change this value after the initial install, for any reason,
|
|
||||||
# even if you've upgraded your system to a new NixOS release.
|
|
||||||
#
|
|
||||||
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
|
|
||||||
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
|
|
||||||
# to actually do that.
|
|
||||||
#
|
|
||||||
# This value being lower than the current NixOS release does NOT mean your system is
|
|
||||||
# out of date, out of support, or vulnerable.
|
|
||||||
#
|
|
||||||
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
|
|
||||||
# and migrated your data accordingly.
|
|
||||||
#
|
|
||||||
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
|
||||||
system.stateVersion = "24.05"; # Did you read the comment?
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
{ flake, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./hardware-configuration.nix
|
|
||||||
./configuration.nix
|
|
||||||
|
|
||||||
./networking.nix
|
|
||||||
./wireguard.nix
|
|
||||||
#./backups.nix
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [ ];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
|
||||||
"ata_piix"
|
|
||||||
"uhci_hcd"
|
|
||||||
"virtio_pci"
|
|
||||||
"sr_mod"
|
|
||||||
"virtio_blk"
|
|
||||||
"virtio_net"
|
|
||||||
];
|
|
||||||
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
|
||||||
boot.kernelModules = [ "kvm-amd" ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
boot.initrd.luks.devices."cryptroot" = {
|
|
||||||
device = "/dev/disk/by-uuid/52a1fd17-63d7-4d0a-b7ff-74aceaf6085a";
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/" = {
|
|
||||||
device = "/dev/disk/by-label/nixos";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
|
||||||
device = "/dev/disk/by-label/boot";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/var/lib/garage/data" = {
|
|
||||||
device = "/dev/disk/by-label/data";
|
|
||||||
fsType = "xfs";
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/var/lib/garage/meta" = {
|
|
||||||
device = "/dev/disk/by-label/metadata";
|
|
||||||
fsType = "btrfs";
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
services.garage.settings.rpc_public_addr = "[2a01:239:35d:f500::1]:3901";
|
|
||||||
|
|
||||||
networking.hostName = "trinkgenossin";
|
|
||||||
networking.hostId = "00000003";
|
|
||||||
|
|
||||||
networking.enableIPv6 = true;
|
|
||||||
networking.useDHCP = true;
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
wireguardIPv4 = "10.7.6.5";
|
|
||||||
wireguardIPv6 = "fd00:fae:fae:fae:fae:5::";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
|
||||||
|
|
||||||
age.secrets.wg-private-key.file = "${flake.self}/secrets/trinkgenossin-wg-private-key.age";
|
|
||||||
|
|
||||||
networking.wireguard.interfaces = {
|
|
||||||
wg-ssh = {
|
|
||||||
listenPort = 51820;
|
|
||||||
mtu = 1300;
|
|
||||||
ips = [
|
|
||||||
"${wireguardIPv4}/32"
|
|
||||||
"${wireguardIPv6}/96"
|
|
||||||
];
|
|
||||||
privateKeyFile = config.age.secrets.wg-private-key.path;
|
|
||||||
peers = flake.self.logins.wireguardDevices ++ [
|
|
||||||
{
|
|
||||||
# nachtigall.pub.solar
|
|
||||||
endpoint = "138.201.80.102:51820";
|
|
||||||
publicKey = "qzNywKY9RvqTnDO8eLik75/SHveaSk9OObilDzv+xkk=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.1/32"
|
|
||||||
"fd00:fae:fae:fae:fae:1::/96"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# metronom.pub.solar
|
|
||||||
endpoint = "49.13.236.167:51820";
|
|
||||||
publicKey = "zOSYGO7MfnOOUnzaTcWiKRQM0qqxR3JQrwx/gtEtHmo=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.3/32"
|
|
||||||
"fd00:fae:fae:fae:fae:3::/96"
|
|
||||||
];
|
|
||||||
persistentKeepalive = 15;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# tankstelle.pub.solar
|
|
||||||
endpoint = "80.244.242.5:51820";
|
|
||||||
publicKey = "iRTlY1lB7nPXf2eXzX8ZZDkfMmXyGjff5/joccbP8Cg=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.4/32"
|
|
||||||
"fd00:fae:fae:fae:fae:4::/96"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# delite.pub.solar
|
|
||||||
endpoint = "5.255.119.132:51820";
|
|
||||||
publicKey = "ZT2qGWgMPwHRUOZmTQHWCRX4m14YwOsiszjsA5bpc2k=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.6/32"
|
|
||||||
"fd00:fae:fae:fae:fae:6::/96"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# blue-shell.pub.solar
|
|
||||||
endpoint = "194.13.83.205:51820";
|
|
||||||
publicKey = "bcrIpWrKc1M+Hq4ds3aN1lTaKE26f2rvXhd+93QrzR8=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.7/32"
|
|
||||||
"fd00:fae:fae:fae:fae:7::/96"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.openssh.listenAddresses = [
|
|
||||||
{
|
|
||||||
addr = wireguardIPv4;
|
|
||||||
port = 22;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
addr = "[${wireguardIPv6}]";
|
|
||||||
port = 22;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
{
|
|
||||||
flake,
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
# Use GRUB2 as the boot loader.
|
|
||||||
boot.loader.grub = {
|
|
||||||
enable = true;
|
|
||||||
devices = [ "/dev/vda" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
pub-solar-os.networking.domain = "test.pub.solar";
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [ "f /tmp/dbf 1777 root root 10d password" ];
|
|
||||||
|
|
||||||
# keycloak
|
|
||||||
pub-solar-os.auth = {
|
|
||||||
enable = true;
|
|
||||||
database-password-file = "/tmp/dbf";
|
|
||||||
};
|
|
||||||
services.keycloak.database.createLocally = true;
|
|
||||||
|
|
||||||
# matrix-synapse
|
|
||||||
# test.pub.solar /.well-known is required for federation
|
|
||||||
services.nginx.virtualHosts."${config.pub-solar-os.networking.domain}" = {
|
|
||||||
default = true;
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
age.secrets."staging-matrix-synapse-secret-config.yaml" = {
|
|
||||||
file = "${flake.self}/secrets/staging-matrix-synapse-secret-config.yaml.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "matrix-synapse";
|
|
||||||
};
|
|
||||||
|
|
||||||
age.secrets."staging-matrix-authentication-service-secret-config.yml" = {
|
|
||||||
file = "${flake.self}/secrets/staging-matrix-authentication-service-secret-config.yml.age";
|
|
||||||
mode = "400";
|
|
||||||
owner = "matrix-authentication-service";
|
|
||||||
};
|
|
||||||
|
|
||||||
pub-solar-os.matrix = {
|
|
||||||
enable = true;
|
|
||||||
synapse = {
|
|
||||||
extra-config-files = [
|
|
||||||
config.age.secrets."staging-matrix-synapse-secret-config.yaml".path
|
|
||||||
|
|
||||||
# The registration file is automatically generated after starting the
|
|
||||||
# appservice for the first time.
|
|
||||||
# cp /var/lib/mautrix-telegram/telegram-registration.yaml \
|
|
||||||
# /var/lib/matrix-synapse/
|
|
||||||
# chown matrix-synapse:matrix-synapse \
|
|
||||||
# /var/lib/matrix-synapse/telegram-registration.yaml
|
|
||||||
#"/var/lib/matrix-synapse/telegram-registration.yaml"
|
|
||||||
];
|
|
||||||
app-service-config-files = [
|
|
||||||
"/var/lib/matrix-appservice-irc/registration.yml"
|
|
||||||
#"/var/lib/matrix-synapse/telegram-registration.yaml"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
matrix-authentication-service.extra-config-files = [
|
|
||||||
config.age.secrets."staging-matrix-authentication-service-secret-config.yml".path
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.openssh.openFirewall = true;
|
|
||||||
|
|
||||||
system.stateVersion = "24.05";
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
{ flake, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
# Include the results of the hardware scan.
|
|
||||||
./hardware-configuration.nix
|
|
||||||
./configuration.nix
|
|
||||||
|
|
||||||
./networking.nix
|
|
||||||
"${flake.inputs.fork}/nixos/modules/services//matrix/matrix-authentication-service.nix"
|
|
||||||
];
|
|
||||||
|
|
||||||
disabledModules = [
|
|
||||||
"services/matrix/matrix-authentication-service.nix "
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
|
||||||
# and may be overwritten by future invocations. Please make changes
|
|
||||||
# to /etc/nixos/configuration.nix instead.
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
(modulesPath + "/profiles/qemu-guest.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
|
||||||
"ahci"
|
|
||||||
"xhci_pci"
|
|
||||||
"virtio_pci"
|
|
||||||
"virtio_scsi"
|
|
||||||
"sd_mod"
|
|
||||||
"sr_mod"
|
|
||||||
];
|
|
||||||
boot.kernelModules = [ "kvm-intel" ];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
|
|
||||||
boot.initrd.luks.devices."cryptroot" = {
|
|
||||||
device = "/dev/disk/by-label/cryptroot";
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/" = {
|
|
||||||
device = "/dev/disk/by-label/root";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
|
||||||
device = "/dev/disk/by-label/boot";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices = [
|
|
||||||
{ device = "/dev/disk/by-label/swap"; }
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
|
|
||||||
networking.hostName = "underground";
|
|
||||||
|
|
||||||
networking = {
|
|
||||||
defaultGateway = {
|
|
||||||
address = "80.244.242.1";
|
|
||||||
interface = "enp1s0";
|
|
||||||
};
|
|
||||||
nameservers = [
|
|
||||||
"95.129.51.51"
|
|
||||||
"80.244.244.244"
|
|
||||||
];
|
|
||||||
interfaces.enp1s0 = {
|
|
||||||
useDHCP = false;
|
|
||||||
ipv4.addresses = [
|
|
||||||
{
|
|
||||||
address = "80.244.242.3";
|
|
||||||
prefixLength = 29;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,16 +1,16 @@
|
||||||
let
|
let
|
||||||
lock = builtins.fromJSON (
|
lock = builtins.fromJSON (builtins.readFile builtins.path {
|
||||||
builtins.readFile builtins.path {
|
path = ../../flake.lock;
|
||||||
path = ../../flake.lock;
|
name = "lockPath";
|
||||||
name = "lockPath";
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
flake =
|
flake =
|
||||||
import
|
import
|
||||||
(fetchTarball {
|
(
|
||||||
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
fetchTarball {
|
||||||
sha256 = lock.nodes.flake-compat.locked.narHash;
|
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
|
||||||
})
|
sha256 = lock.nodes.flake-compat.locked.narHash;
|
||||||
|
}
|
||||||
|
)
|
||||||
{
|
{
|
||||||
src = builtins.path {
|
src = builtins.path {
|
||||||
path = ../../.;
|
path = ../../.;
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
{
|
{ self, lib, inputs, ... }: {
|
||||||
self,
|
|
||||||
lib,
|
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
# Configuration common to all Linux systems
|
# Configuration common to all Linux systems
|
||||||
flake = {
|
flake = {
|
||||||
lib =
|
lib =
|
||||||
|
|
119
lib/deploy.nix
119
lib/deploy.nix
|
@ -1,80 +1,75 @@
|
||||||
/*
|
/*
|
||||||
The contents of this file are adapted from digga
|
* The contents of this file are adapted from digga
|
||||||
https://github.com/divnix/digga
|
* https://github.com/divnix/digga
|
||||||
|
*
|
||||||
Licensed under the MIT license
|
* Licensed under the MIT license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
{ lib, inputs }:
|
{ lib, inputs }:
|
||||||
let
|
let
|
||||||
getFqdn =
|
# https://github.com/serokell/deploy-rs#overall-usage
|
||||||
c:
|
system = "x86_64-linux";
|
||||||
|
pkgs = import inputs.nixpkgs { inherit system; };
|
||||||
|
deployPkgs = import inputs.nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = [
|
||||||
|
inputs.deploy-rs.overlay
|
||||||
|
(self: super: { deploy-rs = { inherit (pkgs) deploy-rs; lib = super.deploy-rs.lib; }; })
|
||||||
|
];
|
||||||
|
};
|
||||||
|
getFqdn = c:
|
||||||
let
|
let
|
||||||
net = c.config.networking;
|
net = c.config.networking;
|
||||||
fqdn =
|
fqdn =
|
||||||
if (net ? domain) && (net.domain != null) then "${net.hostName}.${net.domain}" else net.hostName;
|
if (net ? domain) && (net.domain != null)
|
||||||
|
then "${net.hostName}.${net.domain}"
|
||||||
|
else net.hostName;
|
||||||
in
|
in
|
||||||
fqdn;
|
fqdn;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
mkDeployNodes =
|
mkDeployNodes = systemConfigurations: extraConfig:
|
||||||
systemConfigurations: extraConfig:
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
Synopsis: mkNodes _systemConfigurations_ _extraConfig_
|
Synopsis: mkNodes _systemConfigurations_ _extraConfig_
|
||||||
|
|
||||||
Generate the `nodes` attribute expected by deploy-rs
|
Generate the `nodes` attribute expected by deploy-rs
|
||||||
where _systemConfigurations_ are `nodes`.
|
where _systemConfigurations_ are `nodes`.
|
||||||
|
|
||||||
_systemConfigurations_ should take the form of a flake's
|
_systemConfigurations_ should take the form of a flake's
|
||||||
_nixosConfigurations_. Note that deploy-rs does not currently support
|
_nixosConfigurations_. Note that deploy-rs does not currently support
|
||||||
deploying to darwin hosts.
|
deploying to darwin hosts.
|
||||||
|
|
||||||
_extraConfig_, if specified, will be merged into each of the
|
_extraConfig_, if specified, will be merged into each of the
|
||||||
nodes' configurations.
|
nodes' configurations.
|
||||||
|
|
||||||
Example _systemConfigurations_ input:
|
Example _systemConfigurations_ input:
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
hostname-1 = {
|
hostname-1 = {
|
||||||
fastConnection = true;
|
fastConnection = true;
|
||||||
sshOpts = [ "-p" "25" ];
|
sshOpts = [ "-p" "25" ];
|
||||||
};
|
};
|
||||||
hostname-2 = {
|
hostname-2 = {
|
||||||
sshOpts = [ "-p" "19999" ];
|
sshOpts = [ "-p" "19999" ];
|
||||||
sshUser = "root";
|
sshUser = "root";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
lib.recursiveUpdate (lib.mapAttrs (_: c: {
|
lib.recursiveUpdate
|
||||||
hostname = getFqdn c;
|
(lib.mapAttrs
|
||||||
profiles.system =
|
(
|
||||||
let
|
_: c: {
|
||||||
system = c.pkgs.system;
|
hostname = getFqdn c;
|
||||||
|
profiles.system = {
|
||||||
# Unmodified nixpkgs
|
user = "root";
|
||||||
pkgs = import inputs.nixpkgs { inherit system; };
|
path = deployPkgs.deploy-rs.lib.activate.nixos c;
|
||||||
|
};
|
||||||
# nixpkgs with deploy-rs overlay but force the nixpkgs package
|
}
|
||||||
deployPkgs = import inputs.nixpkgs {
|
)
|
||||||
inherit system;
|
systemConfigurations)
|
||||||
overlays = [
|
extraConfig;
|
||||||
inputs.deploy-rs.overlay # or deploy-rs.overlays.default
|
|
||||||
(self: super: {
|
|
||||||
deploy-rs = {
|
|
||||||
inherit (pkgs) deploy-rs;
|
|
||||||
lib = super.deploy-rs.lib;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
user = "root";
|
|
||||||
path = deployPkgs.deploy-rs.lib.activate.nixos c;
|
|
||||||
};
|
|
||||||
}) systemConfigurations) extraConfig;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,7 @@
|
||||||
{
|
{
|
||||||
# tuxnix
|
# tuxnix
|
||||||
publicKey = "fTvULvdsc92binFaBV+uWwFi33bi8InShcaPnoxUZEA=";
|
publicKey = "fTvULvdsc92binFaBV+uWwFi33bi8InShcaPnoxUZEA=";
|
||||||
allowedIPs = [
|
allowedIPs = [ "10.7.6.203/32" "fd00:fae:fae:fae:fae:203::/96" ];
|
||||||
"10.7.6.203/32"
|
|
||||||
"fd00:fae:fae:fae:fae:203::/96"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -30,29 +27,9 @@
|
||||||
} // sshPubKeys;
|
} // sshPubKeys;
|
||||||
|
|
||||||
wireguardDevices = [
|
wireguardDevices = [
|
||||||
{
|
{ # stroopwafel
|
||||||
# stroopwafel
|
|
||||||
publicKey = "NNb7T8Jmn+V2dTZ8T6Fcq7hGomHGDckKoV3kK2oAhSE=";
|
publicKey = "NNb7T8Jmn+V2dTZ8T6Fcq7hGomHGDckKoV3kK2oAhSE=";
|
||||||
allowedIPs = [
|
allowedIPs = [ "10.7.6.200/32" "fd00:fae:fae:fae:fae:200::/96" ];
|
||||||
"10.7.6.200/32"
|
|
||||||
"fd00:fae:fae:fae:fae:200::/96"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# chocolatebar
|
|
||||||
publicKey = "AS9w0zDUFLcH6IiF6T1vsyZPWPJ3p5fKsjIsM2AoZz8=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.205/32"
|
|
||||||
"fd00:fae:fae:fae:fae:205::/96"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
# biolimo
|
|
||||||
publicKey = "gnLq6KikFVVGxLxPW+3ZnreokEKLDoso+cUepPOZsBA=";
|
|
||||||
allowedIPs = [
|
|
||||||
"10.7.6.206/32"
|
|
||||||
"fd00:fae:fae:fae:fae:206::/96"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -65,13 +42,9 @@
|
||||||
|
|
||||||
secretEncryptionKeys = sshPubKeys;
|
secretEncryptionKeys = sshPubKeys;
|
||||||
wireguardDevices = [
|
wireguardDevices = [
|
||||||
{
|
{ # judy
|
||||||
# judy
|
|
||||||
publicKey = "I+gN7v1VXkAGoSir6L8aebtLbguvy5nAx1QVDTzdckk=";
|
publicKey = "I+gN7v1VXkAGoSir6L8aebtLbguvy5nAx1QVDTzdckk=";
|
||||||
allowedIPs = [
|
allowedIPs = [ "10.7.6.202/32" "fd00:fae:fae:fae:fae:202::/96" ];
|
||||||
"10.7.6.202/32"
|
|
||||||
"fd00:fae:fae:fae:fae:202::/96"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -79,30 +52,20 @@
|
||||||
teutat3s = {
|
teutat3s = {
|
||||||
sshPubKeys = {
|
sshPubKeys = {
|
||||||
teutat3s-1 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFro/k4Mgqyh8yV/7Zwjc0dv60ZM7bROBU9JNd99P/4co6fxPt1pJiU/pEz2Dax/HODxgcO+jFZfvPEuLMCeAl0= YubiKey #10593996 PIV Slot 9a";
|
teutat3s-1 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFro/k4Mgqyh8yV/7Zwjc0dv60ZM7bROBU9JNd99P/4co6fxPt1pJiU/pEz2Dax/HODxgcO+jFZfvPEuLMCeAl0= YubiKey #10593996 PIV Slot 9a";
|
||||||
teutat3s-2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHcU6KPy4b1MQXd6EJhcYwbJu7E+0IrBZF/IP6T7gbMf teutat3s@dumpyourvms";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
secretEncryptionKeys = {
|
secretEncryptionKeys = {
|
||||||
teutat3s-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHcU6KPy4b1MQXd6EJhcYwbJu7E+0IrBZF/IP6T7gbMf teutat3s@dumpyourvms";
|
teutat3s-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHcU6KPy4b1MQXd6EJhcYwbJu7E+0IrBZF/IP6T7gbMf teutat3s@dumpyourvms";
|
||||||
teutat3s-2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPAsRdVYK0077cdtavmrRr6akrI68T1EDY4Hfv4+W86J teutat3s@ryzensun";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
wireguardDevices = [
|
wireguardDevices = [
|
||||||
{
|
{ # dumpyourvms
|
||||||
# dumpyourvms
|
|
||||||
publicKey = "3UrVLQrwXnPAVXPiTAd7eM3fZYxnFSYgKAGpNMUwnUk=";
|
publicKey = "3UrVLQrwXnPAVXPiTAd7eM3fZYxnFSYgKAGpNMUwnUk=";
|
||||||
allowedIPs = [
|
allowedIPs = [ "10.7.6.201/32" "fd00:fae:fae:fae:fae:201::/96" ];
|
||||||
"10.7.6.201/32"
|
|
||||||
"fd00:fae:fae:fae:fae:201::/96"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
{
|
{ # ryzensun
|
||||||
# ryzensun
|
|
||||||
publicKey = "oVF2/s7eIxyVjtG0MhKPx5SZ1JllZg+ZFVF2eVYtPGo=";
|
publicKey = "oVF2/s7eIxyVjtG0MhKPx5SZ1JllZg+ZFVF2eVYtPGo=";
|
||||||
allowedIPs = [
|
allowedIPs = [ "10.7.6.204/32" "fd00:fae:fae:fae:fae:204::/96" ];
|
||||||
"10.7.6.204/32"
|
|
||||||
"fd00:fae:fae:fae:fae:204::/96"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,21 +1,13 @@
|
||||||
{ lib, ... }:
|
{ lib, ... }: let
|
||||||
let
|
|
||||||
admins = import ./admins.nix;
|
admins = import ./admins.nix;
|
||||||
robots = import ./robots.nix;
|
robots = import ./robots.nix;
|
||||||
in
|
in {
|
||||||
{
|
|
||||||
flake = {
|
flake = {
|
||||||
logins = {
|
logins = {
|
||||||
admins = admins;
|
admins = lib.lists.foldl (logins: adminConfig: {
|
||||||
wireguardDevices = lib.lists.foldl (
|
sshPubKeys = logins.sshPubKeys ++ (lib.attrsets.attrValues adminConfig.sshPubKeys);
|
||||||
wireguardDevices: adminConfig:
|
wireguardDevices = logins.wireguardDevices ++ (if adminConfig ? "wireguardDevices" then adminConfig.wireguardDevices else []);
|
||||||
wireguardDevices ++ (if adminConfig ? "wireguardDevices" then adminConfig.wireguardDevices else [ ])
|
}) { sshPubKeys = []; wireguardDevices = []; } (lib.attrsets.attrValues admins);
|
||||||
) [ ] (lib.attrsets.attrValues admins);
|
|
||||||
sshPubKeys = lib.lists.foldl (
|
|
||||||
sshPubKeys: adminConfig:
|
|
||||||
sshPubKeys
|
|
||||||
++ (if adminConfig ? "sshPubKeys" then lib.attrsets.attrValues adminConfig.sshPubKeys else [ ])
|
|
||||||
) [ ] (lib.attrsets.attrValues admins);
|
|
||||||
robots.sshPubKeys = lib.attrsets.attrValues robots;
|
robots.sshPubKeys = lib.attrsets.attrValues robots;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
{
|
{
|
||||||
# Used for restic backups to droppie, a server run by @b12f
|
# Used for restic backups to droppie, a server run by @b12f
|
||||||
"root@droppie" =
|
"root@droppie" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBZQSephFJU0NMbVbhwvVJ2/m6jcPYo1IsWCsoarqKin root@droppie";
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBZQSephFJU0NMbVbhwvVJ2/m6jcPYo1IsWCsoarqKin root@droppie";
|
|
||||||
|
|
||||||
"hakkonaut" =
|
# robot user on flora-6
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGP5MvCwNRtCcP1pSDrn0XZTNlpOqYnjHDm9/OI4hECW hakkonaut";
|
"hakkonaut@flora-6" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGP5MvCwNRtCcP1pSDrn0XZTNlpOqYnjHDm9/OI4hECW hakkonaut@flora-6";
|
||||||
}
|
}
|
||||||
|
|
32
modules/apps/prometheus/nginx-prometheus-exporters.nix
Normal file
32
modules/apps/prometheus/nginx-prometheus-exporters.nix
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{ config, flake, lib, ... }:
|
||||||
|
let
|
||||||
|
# Find element in list config.services.matrix-synapse.settings.listeners
|
||||||
|
# that sets type = "metrics"
|
||||||
|
listenerWithMetrics = lib.findFirst
|
||||||
|
(listener:
|
||||||
|
listener.type == "metrics")
|
||||||
|
(throw "Found no matrix-synapse.settings.listeners.*.type containing string metrics")
|
||||||
|
config.services.matrix-synapse.settings.listeners
|
||||||
|
;
|
||||||
|
synapseMetricsPort = "${toString listenerWithMetrics.port}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
age.secrets.nachtigall-metrics-nginx-basic-auth = {
|
||||||
|
file = "${flake.self}/secrets/nachtigall-metrics-nginx-basic-auth.age";
|
||||||
|
mode = "600";
|
||||||
|
owner = "nginx";
|
||||||
|
};
|
||||||
|
services.nginx.virtualHosts = {
|
||||||
|
"nachtigall.pub.solar" = {
|
||||||
|
enableACME = true;
|
||||||
|
addSSL = true;
|
||||||
|
basicAuthFile = "${config.age.secrets.nachtigall-metrics-nginx-basic-auth.path}";
|
||||||
|
locations."/metrics" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString(config.services.prometheus.exporters.node.port)}";
|
||||||
|
};
|
||||||
|
locations."/_synapse/metrics" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${synapseMetricsPort}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
13
modules/apps/prometheus/prometheus-exporters.nix
Normal file
13
modules/apps/prometheus/prometheus-exporters.nix
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{ config
|
||||||
|
, ...
|
||||||
|
}: {
|
||||||
|
services.prometheus = {
|
||||||
|
exporters = {
|
||||||
|
node = {
|
||||||
|
enable = true;
|
||||||
|
enabledCollectors = [ "systemd" ];
|
||||||
|
port = 9002;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
69
modules/apps/prometheus/prometheus.nix
Normal file
69
modules/apps/prometheus/prometheus.nix
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, flake
|
||||||
|
, ...
|
||||||
|
}: {
|
||||||
|
age.secrets.nachtigall-metrics-prometheus-basic-auth-password = {
|
||||||
|
file = "${flake.self}/secrets/nachtigall-metrics-prometheus-basic-auth-password.age";
|
||||||
|
mode = "600";
|
||||||
|
owner = "prometheus";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.prometheus = {
|
||||||
|
enable = true;
|
||||||
|
port = 9001;
|
||||||
|
exporters = {
|
||||||
|
node = {
|
||||||
|
enable = true;
|
||||||
|
enabledCollectors = [ "systemd" ];
|
||||||
|
port = 9002;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
globalConfig = {
|
||||||
|
scrape_interval = "10s";
|
||||||
|
scrape_timeout = "9s";
|
||||||
|
};
|
||||||
|
scrapeConfigs = [
|
||||||
|
{
|
||||||
|
job_name = "node-exporter-http";
|
||||||
|
static_configs = [{
|
||||||
|
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ];
|
||||||
|
labels = {
|
||||||
|
instance = "flora-6";
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
job_name = "node-exporter-https";
|
||||||
|
scheme = "https";
|
||||||
|
metrics_path = "/metrics";
|
||||||
|
basic_auth = {
|
||||||
|
username = "hakkonaut";
|
||||||
|
password_file = "${config.age.secrets.nachtigall-metrics-prometheus-basic-auth-password.path}";
|
||||||
|
};
|
||||||
|
static_configs = [{
|
||||||
|
targets = [ "nachtigall.pub.solar" ];
|
||||||
|
labels = {
|
||||||
|
instance = "nachtigall";
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
job_name = "matrix-synapse";
|
||||||
|
scheme = "https";
|
||||||
|
metrics_path = "/_synapse/metrics";
|
||||||
|
basic_auth = {
|
||||||
|
username = "hakkonaut";
|
||||||
|
password_file = "${config.age.secrets.nachtigall-metrics-prometheus-basic-auth-password.path}";
|
||||||
|
};
|
||||||
|
static_configs = [{
|
||||||
|
targets = [ "nachtigall.pub.solar" ];
|
||||||
|
labels = {
|
||||||
|
instance = "nachtigall";
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,292 +0,0 @@
|
||||||
{
|
|
||||||
flake,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
utils = import "${flake.inputs.nixpkgs}/nixos/lib/utils.nix" {
|
|
||||||
inherit lib;
|
|
||||||
inherit config;
|
|
||||||
inherit pkgs;
|
|
||||||
};
|
|
||||||
# Type for a valid systemd unit option. Needed for correctly passing "timerConfig" to "systemd.timers"
|
|
||||||
inherit (utils.systemdUtils.unitOptions) unitOption;
|
|
||||||
inherit (lib)
|
|
||||||
literalExpression
|
|
||||||
mkOption
|
|
||||||
mkPackageOption
|
|
||||||
types
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.pub-solar-os.backups = {
|
|
||||||
repos = mkOption {
|
|
||||||
description = ''
|
|
||||||
Configuration of Restic repositories.
|
|
||||||
'';
|
|
||||||
type = types.attrsOf (
|
|
||||||
types.submodule (
|
|
||||||
{ name, ... }:
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
passwordFile = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
Read the repository password from a file.
|
|
||||||
'';
|
|
||||||
example = "/etc/nixos/restic-password";
|
|
||||||
};
|
|
||||||
|
|
||||||
environmentFile = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Read repository secrets as environment variables from a file.
|
|
||||||
'';
|
|
||||||
example = "/etc/nixos/restic-env";
|
|
||||||
};
|
|
||||||
|
|
||||||
repository = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
repository to backup to.
|
|
||||||
'';
|
|
||||||
example = "sftp:backup@192.168.1.100:/backups/${name}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
default = { };
|
|
||||||
example = {
|
|
||||||
remotebackup = {
|
|
||||||
repository = "sftp:backup@host:/backups/home";
|
|
||||||
passwordFile = "/etc/nixos/secrets/restic-password";
|
|
||||||
environmentFile = "/etc/nixos/secrets/restic-env";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
restic = mkOption {
|
|
||||||
description = ''
|
|
||||||
Periodic backups to create with Restic.
|
|
||||||
'';
|
|
||||||
type = types.attrsOf (
|
|
||||||
types.submodule (
|
|
||||||
{ name, ... }:
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
paths = mkOption {
|
|
||||||
# This is nullable for legacy reasons only. We should consider making it a pure listOf
|
|
||||||
# after some time has passed since this comment was added.
|
|
||||||
type = types.nullOr (types.listOf types.str);
|
|
||||||
default = [ ];
|
|
||||||
description = ''
|
|
||||||
Which paths to backup, in addition to ones specified via
|
|
||||||
`dynamicFilesFrom`. If null or an empty array and
|
|
||||||
`dynamicFilesFrom` is also null, no backup command will be run.
|
|
||||||
This can be used to create a prune-only job.
|
|
||||||
'';
|
|
||||||
example = [
|
|
||||||
"/var/lib/postgresql"
|
|
||||||
"/home/user/backup"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
exclude = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = ''
|
|
||||||
Patterns to exclude when backing up. See
|
|
||||||
https://restic.readthedocs.io/en/latest/040_backup.html#excluding-files for
|
|
||||||
details on syntax.
|
|
||||||
'';
|
|
||||||
example = [
|
|
||||||
"/var/cache"
|
|
||||||
"/home/*/.cache"
|
|
||||||
".git"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
timerConfig = mkOption {
|
|
||||||
type = types.nullOr (types.attrsOf unitOption);
|
|
||||||
default = {
|
|
||||||
OnCalendar = "daily";
|
|
||||||
Persistent = true;
|
|
||||||
};
|
|
||||||
description = ''
|
|
||||||
When to run the backup. See {manpage}`systemd.timer(5)` for
|
|
||||||
details. If null no timer is created and the backup will only
|
|
||||||
run when explicitly started.
|
|
||||||
'';
|
|
||||||
example = {
|
|
||||||
OnCalendar = "00:05";
|
|
||||||
RandomizedDelaySec = "5h";
|
|
||||||
Persistent = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "root";
|
|
||||||
description = ''
|
|
||||||
As which user the backup should run.
|
|
||||||
'';
|
|
||||||
example = "postgresql";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraBackupArgs = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = ''
|
|
||||||
Extra arguments passed to restic backup.
|
|
||||||
'';
|
|
||||||
example = [ "--exclude-file=/etc/nixos/restic-ignore" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
extraOptions = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = ''
|
|
||||||
Extra extended options to be passed to the restic --option flag.
|
|
||||||
'';
|
|
||||||
example = [ "sftp.command='ssh backup@192.168.1.100 -i /home/user/.ssh/id_rsa -s sftp'" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
initialize = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Create the repository if it doesn't exist.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
pruneOpts = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = ''
|
|
||||||
A list of options (--keep-\* et al.) for 'restic forget
|
|
||||||
--prune', to automatically prune old snapshots. The
|
|
||||||
'forget' command is run *after* the 'backup' command, so
|
|
||||||
keep that in mind when constructing the --keep-\* options.
|
|
||||||
'';
|
|
||||||
example = [
|
|
||||||
"--keep-daily 7"
|
|
||||||
"--keep-weekly 5"
|
|
||||||
"--keep-monthly 12"
|
|
||||||
"--keep-yearly 75"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
runCheck = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = (builtins.length config.pub-solar-os.backups.restic.${name}.checkOpts > 0);
|
|
||||||
defaultText = literalExpression ''builtins.length config.services.backups.${name}.checkOpts > 0'';
|
|
||||||
description = "Whether to run the `check` command with the provided `checkOpts` options.";
|
|
||||||
example = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
checkOpts = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = ''
|
|
||||||
A list of options for 'restic check'.
|
|
||||||
'';
|
|
||||||
example = [ "--with-cache" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
dynamicFilesFrom = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
A script that produces a list of files to back up. The
|
|
||||||
results of this command are given to the '--files-from'
|
|
||||||
option. The result is merged with paths specified via `paths`.
|
|
||||||
'';
|
|
||||||
example = "find /home/matt/git -type d -name .git";
|
|
||||||
};
|
|
||||||
|
|
||||||
backupPrepareCommand = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
A script that must run before starting the backup process.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
backupCleanupCommand = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
A script that must run after finishing the backup process.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
package = mkPackageOption pkgs "restic" { };
|
|
||||||
|
|
||||||
createWrapper = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Whether to generate and add a script to the system path, that has the same environment variables set
|
|
||||||
as the systemd service. This can be used to e.g. mount snapshots or perform other opterations, without
|
|
||||||
having to manually specify most options.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
default = { };
|
|
||||||
example = {
|
|
||||||
localbackup = {
|
|
||||||
paths = [ "/home" ];
|
|
||||||
exclude = [ "/home/*/.cache" ];
|
|
||||||
initialize = true;
|
|
||||||
};
|
|
||||||
remotebackup = {
|
|
||||||
paths = [ "/home" ];
|
|
||||||
extraOptions = [
|
|
||||||
"sftp.command='ssh backup@host -i /etc/nixos/secrets/backup-private-key -s sftp'"
|
|
||||||
];
|
|
||||||
timerConfig = {
|
|
||||||
OnCalendar = "00:05";
|
|
||||||
RandomizedDelaySec = "5h";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
services.restic.backups =
|
|
||||||
let
|
|
||||||
repos = config.pub-solar-os.backups.repos;
|
|
||||||
restic = config.pub-solar-os.backups.restic;
|
|
||||||
|
|
||||||
repoNames = builtins.attrNames repos;
|
|
||||||
backupNames = builtins.attrNames restic;
|
|
||||||
|
|
||||||
createBackups =
|
|
||||||
backupName:
|
|
||||||
map (repoName: {
|
|
||||||
name = "${backupName}-${repoName}";
|
|
||||||
value = repos."${repoName}" // restic."${backupName}";
|
|
||||||
}) repoNames;
|
|
||||||
|
|
||||||
in
|
|
||||||
builtins.listToAttrs (lib.lists.flatten (map createBackups backupNames));
|
|
||||||
|
|
||||||
# Used for pub-solar-os.backups.repos.storagebox
|
|
||||||
programs.ssh.knownHosts = {
|
|
||||||
"u377325.your-storagebox.de".publicKey =
|
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5EB5p/5Hp3hGW1oHok+PIOH9Pbn7cnUiGmUEBrCVjnAw+HrKyN8bYVV0dIGllswYXwkG/+bgiBlE6IVIBAq+JwVWu1Sss3KarHY3OvFJUXZoZyRRg/Gc/+LRCE7lyKpwWQ70dbelGRyyJFH36eNv6ySXoUYtGkwlU5IVaHPApOxe4LHPZa/qhSRbPo2hwoh0orCtgejRebNtW5nlx00DNFgsvn8Svz2cIYLxsPVzKgUxs8Zxsxgn+Q/UvR7uq4AbAhyBMLxv7DjJ1pc7PJocuTno2Rw9uMZi1gkjbnmiOh6TTXIEWbnroyIhwc8555uto9melEUmWNQ+C+PwAK+MPw==";
|
|
||||||
"[u377325.your-storagebox.de]:23".publicKey =
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,11 +1,14 @@
|
||||||
{
|
{ config
|
||||||
config,
|
, lib
|
||||||
lib,
|
, pkgs
|
||||||
pkgs,
|
, flake
|
||||||
flake,
|
, ...
|
||||||
...
|
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d '/data/srv/www/os/download/' 0750 ${config.pub-solar-os.authentication.robot.username} ${config.pub-solar-os.authentication.robot.username} - -"
|
||||||
|
];
|
||||||
|
|
||||||
services.caddy = {
|
services.caddy = {
|
||||||
enable = lib.mkForce true;
|
enable = lib.mkForce true;
|
||||||
group = config.pub-solar-os.authentication.robot.username;
|
group = config.pub-solar-os.authentication.robot.username;
|
||||||
|
@ -14,9 +17,27 @@
|
||||||
globalConfig = lib.mkForce ''
|
globalConfig = lib.mkForce ''
|
||||||
grace_period 60s
|
grace_period 60s
|
||||||
'';
|
'';
|
||||||
|
virtualHosts = {
|
||||||
|
"flora-6.pub.solar" = {
|
||||||
|
logFormat = lib.mkForce ''
|
||||||
|
output discard
|
||||||
|
'';
|
||||||
|
extraConfig = ''
|
||||||
|
basicauth * {
|
||||||
|
${config.pub-solar-os.authentication.robot.username} $2a$14$mmIAy/Ezm6YGohUtXa2mWeW6Bcw1MQXPhrRbz14jAD2iUu3oob/t.
|
||||||
|
}
|
||||||
|
reverse_proxy :${toString config.services.loki.configuration.server.http_listen_port}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"obs-portal.pub.solar" = {
|
||||||
|
logFormat = lib.mkForce ''
|
||||||
|
output discard
|
||||||
|
'';
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy obs-portal.svc.e5756d08-36fd-424b-f8bc-acdb92ca7b82.lev-1.int.greenbaum.zone:3000
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
networking.firewall.allowedTCPPorts = [
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
80
|
|
||||||
443
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
{
|
{ config
|
||||||
config,
|
, lib
|
||||||
lib,
|
, pkgs
|
||||||
pkgs,
|
, self
|
||||||
self,
|
, ...
|
||||||
...
|
}: {
|
||||||
}:
|
services.nginx.virtualHosts."collabora.pub.solar" = {
|
||||||
{
|
|
||||||
services.nginx.virtualHosts."collabora.${config.pub-solar-os.networking.domain}" = {
|
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
|
|
||||||
|
@ -26,14 +24,16 @@
|
||||||
containers."collabora" = {
|
containers."collabora" = {
|
||||||
image = "collabora/code";
|
image = "collabora/code";
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
ports = [ "127.0.0.1:9980:9980" ];
|
ports = [
|
||||||
|
"127.0.0.1:9980:9980"
|
||||||
|
];
|
||||||
extraOptions = [
|
extraOptions = [
|
||||||
"--cap-add=MKNOD"
|
"--cap-add=MKNOD"
|
||||||
"--pull=always"
|
"--pull=always"
|
||||||
];
|
];
|
||||||
environment = {
|
environment = {
|
||||||
server_name = "collabora.${config.pub-solar-os.networking.domain}";
|
server_name = "collabora.pub.solar";
|
||||||
aliasgroup1 = "https://cloud.${config.pub-solar-os.networking.domain}:443";
|
aliasgroup1 = "https://cloud.pub.solar:443";
|
||||||
DONT_GEN_SSL_CERT = "1";
|
DONT_GEN_SSL_CERT = "1";
|
||||||
extra_params = "--o:ssl.enable=false --o:ssl.termination=true";
|
extra_params = "--o:ssl.enable=false --o:ssl.termination=true";
|
||||||
SLEEPFORDEBUGGER = "0";
|
SLEEPFORDEBUGGER = "0";
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
{
|
{ pkgs, config, flake, lib, ... }: {
|
||||||
pkgs,
|
|
||||||
config,
|
|
||||||
flake,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
imports = [
|
imports = [
|
||||||
./nix.nix
|
./nix.nix
|
||||||
./networking.nix
|
./networking.nix
|
||||||
|
@ -13,38 +6,18 @@
|
||||||
./users.nix
|
./users.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
options.pub-solar-os =
|
options.pub-solar-os = with lib; {
|
||||||
let
|
adminEmail = mkOption {
|
||||||
inherit (lib) mkOption types;
|
description = "Email address to use for administrative stuff like ACME";
|
||||||
in
|
type = types.str;
|
||||||
{
|
default = "admins@pub.solar";
|
||||||
adminEmail = mkOption {
|
|
||||||
description = "Email address to use for administrative stuff like ACME";
|
|
||||||
type = types.str;
|
|
||||||
default = "admins@pub.solar";
|
|
||||||
};
|
|
||||||
|
|
||||||
privacyPolicyUrl = mkOption {
|
|
||||||
description = "URL of the privacy policy. Used to link there from applications";
|
|
||||||
type = types.str;
|
|
||||||
default = "https://pub.solar/privacy";
|
|
||||||
};
|
|
||||||
|
|
||||||
imprintUrl = mkOption {
|
|
||||||
description = "URL of the imprint. Used to link there from applications";
|
|
||||||
type = types.str;
|
|
||||||
default = "https://pub.solar/about";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
environment = {
|
environment = {
|
||||||
# Just a couple of global packages to make our lives easier
|
# Just a couple of global packages to make our lives easier
|
||||||
systemPackages = with pkgs; [
|
systemPackages = with pkgs; [ git vim wget ];
|
||||||
git
|
|
||||||
vim
|
|
||||||
wget
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Select internationalization properties
|
# Select internationalization properties
|
||||||
|
@ -54,5 +27,9 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
time.timeZone = "Etc/UTC";
|
time.timeZone = "Etc/UTC";
|
||||||
|
|
||||||
|
home-manager.users.${config.pub-solar-os.authentication.username} = {
|
||||||
|
home.stateVersion = "23.05";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,45 +3,28 @@
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
...
|
...
|
||||||
}:
|
}: {
|
||||||
{
|
options.pub-solar-os.networking = with lib; {
|
||||||
options.pub-solar-os.networking =
|
domain = mkOption {
|
||||||
let
|
description = "domain on which all services should run. This defaults to pub.solar";
|
||||||
inherit (lib) mkOption types;
|
type = types.str;
|
||||||
in
|
default = "pub.solar";
|
||||||
{
|
|
||||||
domain = mkOption {
|
|
||||||
description = "domain on which all services should run. This defaults to pub.solar";
|
|
||||||
type = types.str;
|
|
||||||
default = "pub.solar";
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultInterface = mkOption {
|
|
||||||
description = "Network interface which should be used as the default internet-connected one";
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
defaultInterface = mkOption {
|
||||||
|
description = "Network interface which should be used as the default internet-connected one";
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
|
||||||
# Don't expose SSH via public interfaces
|
# Don't expose SSH via public interfaces
|
||||||
networking.firewall.interfaces.wg-ssh.allowedTCPPorts = [ 22 ];
|
networking.firewall.interfaces.wg-ssh.allowedTCPPorts = [ 22 ];
|
||||||
|
|
||||||
networking.domain = config.pub-solar-os.networking.domain;
|
|
||||||
|
|
||||||
networking.hosts = {
|
networking.hosts = {
|
||||||
"10.7.6.1" = [ "nachtigall.wg.${config.pub-solar-os.networking.domain}" ];
|
"10.7.6.1" = ["nachtigall.${config.pub-solar-os.networking.domain}"];
|
||||||
"10.7.6.3" = [ "metronom.wg.${config.pub-solar-os.networking.domain}" ];
|
"10.7.6.2" = ["flora-6.${config.pub-solar-os.networking.domain}"];
|
||||||
"10.7.6.4" = [ "tankstelle.wg.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
"10.7.6.5" = [ "trinkgenossin.wg.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
"10.7.6.6" = [ "delite.wg.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
"10.7.6.7" = [ "blue-shell.wg.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
"fd00:fae:fae:fae:fae:1::" = [ "nachtigall.wg.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
"fd00:fae:fae:fae:fae:3::" = [ "metronom.wg.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
"fd00:fae:fae:fae:fae:4::" = [ "tankstelle.wg.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
"fd00:fae:fae:fae:fae:5::" = [ "trinkgenossin.wg.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
"fd00:fae:fae:fae:fae:6::" = [ "delite.wg.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
"fd00:fae:fae:fae:fae:7::" = [ "blue-shell.wg.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
|
@ -57,7 +40,7 @@
|
||||||
# This breaks compatibilty with clients that do not offer these MACs. For
|
# This breaks compatibilty with clients that do not offer these MACs. For
|
||||||
# compatibility reasons, we add back the old defaults.
|
# compatibility reasons, we add back the old defaults.
|
||||||
# See: https://github.com/NixOS/nixpkgs/pull/231165
|
# See: https://github.com/NixOS/nixpkgs/pull/231165
|
||||||
#
|
#
|
||||||
# https://blog.stribik.technology/2015/01/04/secure-secure-shell.html
|
# https://blog.stribik.technology/2015/01/04/secure-secure-shell.html
|
||||||
# https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67
|
# https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67
|
||||||
Macs = [
|
Macs = [
|
||||||
|
|
|
@ -1,26 +1,11 @@
|
||||||
{
|
{ config
|
||||||
config,
|
, pkgs
|
||||||
pkgs,
|
, lib
|
||||||
lib,
|
, flake
|
||||||
flake,
|
, ...
|
||||||
...
|
}: {
|
||||||
}:
|
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
||||||
{
|
];
|
||||||
nixpkgs.config = lib.mkDefault {
|
|
||||||
allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ ];
|
|
||||||
permittedInsecurePackages = [ "olm-3.2.16" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
system.activationScripts.diff-closures = {
|
|
||||||
text = ''
|
|
||||||
if [[ -e /run/current-system ]]; then
|
|
||||||
${config.nix.package}/bin/nix store diff-closures \
|
|
||||||
/run/current-system "$systemConfig" \
|
|
||||||
--extra-experimental-features nix-command
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
supportsDryActivation = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
nix = {
|
nix = {
|
||||||
# Use default version alias for nix package
|
# Use default version alias for nix package
|
||||||
|
@ -40,10 +25,7 @@
|
||||||
# Prevents impurities in builds
|
# Prevents impurities in builds
|
||||||
sandbox = true;
|
sandbox = true;
|
||||||
# Give root and @wheel special privileges with nix
|
# Give root and @wheel special privileges with nix
|
||||||
trusted-users = [
|
trusted-users = [ "root" "@wheel" ];
|
||||||
"root"
|
|
||||||
"@wheel"
|
|
||||||
];
|
|
||||||
# Allow only group wheel to connect to the nix daemon
|
# Allow only group wheel to connect to the nix daemon
|
||||||
allowed-users = [ "@wheel" ];
|
allowed-users = [ "@wheel" ];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,33 +1,18 @@
|
||||||
{ flake, lib, ... }:
|
{ flake, config, ... }: {
|
||||||
{
|
home-manager.users.${config.pub-solar-os.authentication.username} = {
|
||||||
home-manager.users = (
|
programs.git.enable = true;
|
||||||
lib.attrsets.foldlAttrs (
|
programs.starship.enable = true;
|
||||||
acc: name: value:
|
programs.bash.enable = true;
|
||||||
acc
|
programs.neovim = {
|
||||||
// {
|
enable = true;
|
||||||
${name} = {
|
vimAlias = true;
|
||||||
programs.git.enable = true;
|
viAlias = true;
|
||||||
programs.starship.enable = true;
|
defaultEditor = true;
|
||||||
programs.bash = {
|
# configure = {
|
||||||
enable = true;
|
# packages.myVimPackages = with pkgs.vimPlugins; {
|
||||||
historyControl = [
|
# start = [vim-nix vim-surrund rainbow];
|
||||||
"ignoredups"
|
# };
|
||||||
"ignorespace"
|
# };
|
||||||
];
|
};
|
||||||
};
|
};
|
||||||
programs.neovim = {
|
|
||||||
enable = true;
|
|
||||||
vimAlias = true;
|
|
||||||
viAlias = true;
|
|
||||||
defaultEditor = true;
|
|
||||||
# configure = {
|
|
||||||
# packages.myVimPackages = with pkgs.vimPlugins; {
|
|
||||||
# start = [vim-nix vim-surrund rainbow];
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) { } flake.self.logins.admins
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,87 +4,66 @@
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
...
|
...
|
||||||
}:
|
}: {
|
||||||
{
|
options.pub-solar-os.authentication = with lib; {
|
||||||
options.pub-solar-os.authentication =
|
username = mkOption {
|
||||||
let
|
description = "Username for the adminstrative user";
|
||||||
inherit (lib) mkOption types;
|
type = types.str;
|
||||||
in
|
default = flake.self.username;
|
||||||
{
|
|
||||||
root.initialHashedPassword = mkOption {
|
|
||||||
description = "Hashed password of the root account";
|
|
||||||
type = types.str;
|
|
||||||
default = "$y$j9T$bIN6GjQkmPMllOcQsq52K0$q0Z5B5.KW/uxXK9fItB8H6HO79RYAcI/ZZdB0Djke32";
|
|
||||||
};
|
|
||||||
|
|
||||||
robot.username = mkOption {
|
|
||||||
description = "username for the robot user";
|
|
||||||
type = types.str;
|
|
||||||
default = "hakkonaut";
|
|
||||||
};
|
|
||||||
|
|
||||||
robot.sshPubKeys = mkOption {
|
|
||||||
description = "SSH Keys to use for the robot user";
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = flake.self.logins.robots.sshPubKeys;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sshPubKeys = mkOption {
|
||||||
|
description = "SSH Keys that should have administrative root access";
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = flake.self.logins.admins.sshPubKeys;
|
||||||
|
};
|
||||||
|
|
||||||
|
root.initialHashedPassword = mkOption {
|
||||||
|
description = "Hashed password of the root account";
|
||||||
|
type = types.str;
|
||||||
|
default = "$y$j9T$bIN6GjQkmPMllOcQsq52K0$q0Z5B5.KW/uxXK9fItB8H6HO79RYAcI/ZZdB0Djke32";
|
||||||
|
};
|
||||||
|
|
||||||
|
robot.username = mkOption {
|
||||||
|
description = "username for the robot user";
|
||||||
|
type = types.str;
|
||||||
|
default = "hakkonaut";
|
||||||
|
};
|
||||||
|
|
||||||
|
robot.sshPubKeys = mkOption {
|
||||||
|
description = "SSH Keys to use for the robot user";
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = flake.self.logins.robots.sshPubKeys;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
users.users =
|
users.users.${config.pub-solar-os.authentication.username} = {
|
||||||
(lib.attrsets.foldlAttrs (
|
name = config.pub-solar-os.authentication.username;
|
||||||
acc: name: value:
|
group = config.pub-solar-os.authentication.username;
|
||||||
acc
|
extraGroups = [ "wheel" "docker" ];
|
||||||
// {
|
isNormalUser = true;
|
||||||
${name} = {
|
openssh.authorizedKeys.keys = config.pub-solar-os.authentication.sshPubKeys;
|
||||||
name = name;
|
};
|
||||||
group = name;
|
users.groups.${config.pub-solar-os.authentication.username} = { };
|
||||||
extraGroups = [
|
|
||||||
"wheel"
|
|
||||||
"docker"
|
|
||||||
];
|
|
||||||
isNormalUser = true;
|
|
||||||
openssh.authorizedKeys.keys = lib.attrsets.attrValues value.sshPubKeys;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) { } flake.self.logins.admins)
|
|
||||||
// {
|
|
||||||
# TODO: Remove when we stop locking ourselves out.
|
|
||||||
root.openssh.authorizedKeys.keys = flake.self.logins.sshPubKeys;
|
|
||||||
root.initialHashedPassword = config.pub-solar-os.authentication.root.initialHashedPassword;
|
|
||||||
|
|
||||||
${config.pub-solar-os.authentication.robot.username} = {
|
# TODO: Remove when we stop locking ourselves out.
|
||||||
description = "CI and automation user";
|
users.users.root.openssh.authorizedKeys.keys = config.pub-solar-os.authentication.sshPubKeys;
|
||||||
home = "/home/${config.pub-solar-os.authentication.robot.username}";
|
|
||||||
createHome = true;
|
|
||||||
useDefaultShell = true;
|
|
||||||
uid = 998;
|
|
||||||
group = "${config.pub-solar-os.authentication.robot.username}";
|
|
||||||
isSystemUser = true;
|
|
||||||
openssh.authorizedKeys.keys = config.pub-solar-os.authentication.robot.sshPubKeys;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
home-manager.users = (
|
users.users.${config.pub-solar-os.authentication.robot.username} = {
|
||||||
lib.attrsets.foldlAttrs (
|
description = "CI and automation user";
|
||||||
acc: name: value:
|
home = "/home/${config.pub-solar-os.authentication.robot.username}";
|
||||||
acc
|
createHome = true;
|
||||||
// {
|
useDefaultShell = true;
|
||||||
${name} = {
|
uid = 998;
|
||||||
home.stateVersion = "23.05";
|
group = "${config.pub-solar-os.authentication.robot.username}";
|
||||||
};
|
isSystemUser = true;
|
||||||
}
|
openssh.authorizedKeys.keys = config.pub-solar-os.authentication.robot.sshPubKeys;
|
||||||
) { } flake.self.logins.admins
|
};
|
||||||
);
|
|
||||||
|
|
||||||
users.groups =
|
users.groups.${config.pub-solar-os.authentication.robot.username} = { };
|
||||||
(lib.attrsets.foldlAttrs (
|
|
||||||
acc: name: value:
|
users.users.root.initialHashedPassword = config.pub-solar-os.authentication.root.initialHashedPassword;
|
||||||
acc // { "${name}" = { }; }
|
|
||||||
) { } flake.self.logins.admins)
|
|
||||||
// {
|
|
||||||
${config.pub-solar-os.authentication.robot.username} = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
security.sudo.wheelNeedsPassword = false;
|
security.sudo.wheelNeedsPassword = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ flake, config, lib, ... }:
|
||||||
flake,
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
{
|
||||||
age.secrets."coturn-static-auth-secret" = {
|
age.secrets."coturn-static-auth-secret" = {
|
||||||
file = "${flake.self}/secrets/coturn-static-auth-secret.age";
|
file = "${flake.self}/secrets/coturn-static-auth-secret.age";
|
||||||
|
@ -18,18 +13,14 @@
|
||||||
min-port = 49000;
|
min-port = 49000;
|
||||||
max-port = 50000;
|
max-port = 50000;
|
||||||
use-auth-secret = true;
|
use-auth-secret = true;
|
||||||
static-auth-secret-file = config.age.secrets."coturn-static-auth-secret".path;
|
static-auth-secret-file = "/run/agenix/coturn-static-auth-secret";
|
||||||
realm = "turn.${config.pub-solar-os.networking.domain}";
|
realm = "turn.pub.solar";
|
||||||
cert = "${config.security.acme.certs.${realm}.directory}/full.pem";
|
cert = "${config.security.acme.certs.${realm}.directory}/full.pem";
|
||||||
pkey = "${config.security.acme.certs.${realm}.directory}/key.pem";
|
pkey = "${config.security.acme.certs.${realm}.directory}/key.pem";
|
||||||
extraConfig =
|
extraConfig =
|
||||||
let
|
let
|
||||||
externalIPv4s = lib.strings.concatMapStringsSep "\n" (
|
externalIPv4s = lib.strings.concatMapStringsSep "\n" ({ address, ... }: "external-ip=${address}") config.networking.interfaces.enp35s0.ipv4.addresses;
|
||||||
{ address, ... }: "external-ip=${address}"
|
externalIPv6s = lib.strings.concatMapStringsSep "\n" ({ address, ... }: "external-ip=${address}") config.networking.interfaces.enp35s0.ipv6.addresses;
|
||||||
) config.networking.interfaces.enp35s0.ipv4.addresses;
|
|
||||||
externalIPv6s = lib.strings.concatMapStringsSep "\n" (
|
|
||||||
{ address, ... }: "external-ip=${address}"
|
|
||||||
) config.networking.interfaces.enp35s0.ipv6.addresses;
|
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
${externalIPv4s}
|
${externalIPv4s}
|
||||||
|
@ -70,42 +61,35 @@
|
||||||
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||||
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||||
'';
|
'';
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
interfaces.enp35s0 =
|
interfaces.enp35s0 =
|
||||||
let
|
let
|
||||||
range = with config.services.coturn; [
|
range = with config.services.coturn; [{
|
||||||
{
|
from = min-port;
|
||||||
from = min-port;
|
to = max-port;
|
||||||
to = max-port;
|
}];
|
||||||
}
|
|
||||||
];
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
allowedUDPPortRanges = range;
|
allowedUDPPortRanges = range;
|
||||||
allowedUDPPorts = [
|
allowedUDPPorts = [ 3478 5349 ];
|
||||||
3478
|
|
||||||
5349
|
|
||||||
];
|
|
||||||
allowedTCPPortRanges = [ ];
|
allowedTCPPortRanges = [ ];
|
||||||
allowedTCPPorts = [
|
allowedTCPPorts = [ 3478 5349 ];
|
||||||
3478
|
|
||||||
5349
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# get a certificate
|
# get a certificate
|
||||||
security.acme.certs.${config.services.coturn.realm} = {
|
security.acme.certs.${config.services.coturn.realm} = {
|
||||||
# insert here the right configuration to obtain a certificate
|
/* insert here the right configuration to obtain a certificate */
|
||||||
postRun = "systemctl restart coturn.service";
|
postRun = "systemctl restart coturn.service";
|
||||||
group = "turnserver";
|
group = "turnserver";
|
||||||
};
|
};
|
||||||
services.nginx.virtualHosts.${config.services.coturn.realm} = {
|
services.nginx.virtualHosts.${config.services.coturn.realm} = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
addSSL = true;
|
addSSL = true;
|
||||||
globalRedirect = "${config.pub-solar-os.networking.domain}";
|
globalRedirect = "pub.solar";
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.nginx.extraGroups = [ "turnserver" ];
|
users.users.nginx.extraGroups = [ "turnserver" ];
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }: {
|
||||||
{
|
|
||||||
virtualisation.docker = {
|
virtualisation.docker = {
|
||||||
enable = true;
|
enable = true;
|
||||||
extraOptions = ''
|
extraOptions = ''
|
||||||
|
|
128
modules/drone/default.nix
Normal file
128
modules/drone/default.nix
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, flake
|
||||||
|
, ...
|
||||||
|
}: {
|
||||||
|
age.secrets.drone-secrets = {
|
||||||
|
file = "${flake.self}/secrets/drone-secrets.age";
|
||||||
|
mode = "600";
|
||||||
|
owner = "drone";
|
||||||
|
};
|
||||||
|
age.secrets.drone-db-secrets = {
|
||||||
|
file = "${flake.self}/secrets/drone-db-secrets.age";
|
||||||
|
mode = "600";
|
||||||
|
owner = "drone";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.drone = {
|
||||||
|
description = "Drone Service";
|
||||||
|
home = "/var/lib/drone";
|
||||||
|
useDefaultShell = true;
|
||||||
|
uid = 994;
|
||||||
|
group = "drone";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.drone = { };
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d '/var/lib/drone-db' 0750 drone drone - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.caddy.virtualHosts."ci.pub.solar" = {
|
||||||
|
logFormat = lib.mkForce ''
|
||||||
|
output discard
|
||||||
|
'';
|
||||||
|
extraConfig = ''
|
||||||
|
reverse_proxy :4000
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."docker-network-drone" =
|
||||||
|
let
|
||||||
|
docker = config.virtualisation.oci-containers.backend;
|
||||||
|
dockerBin = "${pkgs.${docker}}/bin/${docker}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
before = [ "docker-drone-server.service" ];
|
||||||
|
script = ''
|
||||||
|
${dockerBin} network inspect drone-net >/dev/null 2>&1 || ${dockerBin} network create drone-net --subnet 172.20.0.0/24
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation = {
|
||||||
|
docker = {
|
||||||
|
enable = true; # sadly podman is not supported rightnow
|
||||||
|
extraOptions = ''
|
||||||
|
--data-root /data/docker
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
oci-containers = {
|
||||||
|
backend = "docker";
|
||||||
|
containers."drone-db" = {
|
||||||
|
image = "postgres:14";
|
||||||
|
autoStart = true;
|
||||||
|
user = "994";
|
||||||
|
volumes = [
|
||||||
|
"/var/lib/drone-db:/var/lib/postgresql/data"
|
||||||
|
];
|
||||||
|
extraOptions = [
|
||||||
|
"--network=drone-net"
|
||||||
|
];
|
||||||
|
environmentFiles = [
|
||||||
|
config.age.secrets.drone-db-secrets.path
|
||||||
|
];
|
||||||
|
};
|
||||||
|
containers."drone-server" = {
|
||||||
|
image = "drone/drone:2";
|
||||||
|
autoStart = true;
|
||||||
|
user = "994";
|
||||||
|
ports = [
|
||||||
|
"127.0.0.1:4000:80"
|
||||||
|
];
|
||||||
|
dependsOn = [ "drone-db" ];
|
||||||
|
extraOptions = [
|
||||||
|
"--network=drone-net"
|
||||||
|
"--pull=always"
|
||||||
|
"--add-host=nachtigall.pub.solar:10.7.6.1"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
DRONE_GITEA_SERVER = "https://git.pub.solar";
|
||||||
|
DRONE_SERVER_HOST = "ci.pub.solar";
|
||||||
|
DRONE_SERVER_PROTO = "https";
|
||||||
|
DRONE_DATABASE_DRIVER = "postgres";
|
||||||
|
};
|
||||||
|
environmentFiles = [
|
||||||
|
config.age.secrets.drone-secrets.path
|
||||||
|
];
|
||||||
|
};
|
||||||
|
containers."drone-docker-runner" = {
|
||||||
|
image = "drone/drone-runner-docker:1";
|
||||||
|
autoStart = true;
|
||||||
|
# needs to run as root
|
||||||
|
#user = "994";
|
||||||
|
volumes = [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
|
];
|
||||||
|
dependsOn = [ "drone-db" ];
|
||||||
|
extraOptions = [
|
||||||
|
"--network=drone-net"
|
||||||
|
"--pull=always"
|
||||||
|
"--add-host=nachtigall.pub.solar:10.7.6.1"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
DRONE_RPC_HOST = "ci.pub.solar";
|
||||||
|
DRONE_RPC_PROTO = "https";
|
||||||
|
DRONE_RUNNER_CAPACITY = "2";
|
||||||
|
DRONE_RUNNER_NAME = "flora-6-docker-runner";
|
||||||
|
};
|
||||||
|
environmentFiles = [
|
||||||
|
config.age.secrets.drone-secrets.path
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
65
modules/forgejo-actions-runner/default.nix
Normal file
65
modules/forgejo-actions-runner/default.nix
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
{ config
|
||||||
|
, lib
|
||||||
|
, pkgs
|
||||||
|
, flake
|
||||||
|
, ...
|
||||||
|
}: {
|
||||||
|
age.secrets.forgejo-actions-runner-token = {
|
||||||
|
file = "${flake.self}/secrets/forgejo-actions-runner-token.age";
|
||||||
|
mode = "644";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Trust docker bridge interface traffic
|
||||||
|
# Needed for the docker runner to communicate with the act_runner cache
|
||||||
|
networking.firewall.trustedInterfaces = [ "br-+" ];
|
||||||
|
|
||||||
|
users.users.gitea-runner = {
|
||||||
|
home = "/var/lib/gitea-runner/flora-6";
|
||||||
|
useDefaultShell = true;
|
||||||
|
group = "gitea-runner";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.gitea-runner = {};
|
||||||
|
|
||||||
|
systemd.services."gitea-runner-flora\\x2d6".serviceConfig = {
|
||||||
|
DynamicUser = lib.mkForce false;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d '/data/gitea-actions-runner' 0750 gitea-runner gitea-runner - -"
|
||||||
|
"d '/var/lib/gitea-runner' 0750 gitea-runner gitea-runner - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
# forgejo actions runner
|
||||||
|
# https://forgejo.org/docs/latest/admin/actions/
|
||||||
|
# https://docs.gitea.com/usage/actions/quickstart
|
||||||
|
services.gitea-actions-runner = {
|
||||||
|
package = pkgs.forgejo-runner;
|
||||||
|
instances."flora-6" = {
|
||||||
|
enable = true;
|
||||||
|
name = config.networking.hostName;
|
||||||
|
url = "https://git.pub.solar";
|
||||||
|
tokenFile = config.age.secrets.forgejo-actions-runner-token.path;
|
||||||
|
settings = {
|
||||||
|
cache = {
|
||||||
|
enabled = true;
|
||||||
|
dir = "/data/gitea-actions-runner/actcache";
|
||||||
|
host = "";
|
||||||
|
port = 0;
|
||||||
|
external_server = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
labels = [
|
||||||
|
# provide a debian 12 bookworm base with Node.js for actions
|
||||||
|
"debian-latest:docker://git.pub.solar/pub-solar/actions-base-image:20-bookworm"
|
||||||
|
# fake the ubuntu name, commonly used in actions examples
|
||||||
|
"ubuntu-latest:docker://git.pub.solar/pub-solar/actions-base-image:20-bookworm"
|
||||||
|
# alpine with Node.js
|
||||||
|
"alpine-latest:docker://node:20-alpine"
|
||||||
|
# nix flakes enabled image with Node.js
|
||||||
|
"nix-flakes:docker://git.pub.solar/pub-solar/nix-flakes-node:latest"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,11 +1,9 @@
|
||||||
{
|
{ config
|
||||||
config,
|
, lib
|
||||||
lib,
|
, pkgs
|
||||||
pkgs,
|
, flake
|
||||||
flake,
|
, ...
|
||||||
...
|
}: {
|
||||||
}:
|
|
||||||
{
|
|
||||||
age.secrets.forgejo-database-password = {
|
age.secrets.forgejo-database-password = {
|
||||||
file = "${flake.self}/secrets/forgejo-database-password.age";
|
file = "${flake.self}/secrets/forgejo-database-password.age";
|
||||||
mode = "600";
|
mode = "600";
|
||||||
|
@ -31,7 +29,7 @@
|
||||||
user = "gitea";
|
user = "gitea";
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.virtualHosts."git.${config.pub-solar-os.networking.domain}" = {
|
services.nginx.virtualHosts."git.pub.solar" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
|
|
||||||
|
@ -54,7 +52,7 @@
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups.gitea = { };
|
users.groups.gitea = {};
|
||||||
|
|
||||||
# Expose SSH port only for forgejo SSH
|
# Expose SSH port only for forgejo SSH
|
||||||
networking.firewall.interfaces.enp35s0.allowedTCPPorts = [ 2223 ];
|
networking.firewall.interfaces.enp35s0.allowedTCPPorts = [ 2223 ];
|
||||||
|
@ -80,8 +78,8 @@
|
||||||
DEFAULT.APP_NAME = "pub.solar git server";
|
DEFAULT.APP_NAME = "pub.solar git server";
|
||||||
|
|
||||||
server = {
|
server = {
|
||||||
ROOT_URL = "https://git.${config.pub-solar-os.networking.domain}";
|
ROOT_URL = "https://git.pub.solar";
|
||||||
DOMAIN = "git.${config.pub-solar-os.networking.domain}";
|
DOMAIN = "git.pub.solar";
|
||||||
HTTP_ADDR = "127.0.0.1";
|
HTTP_ADDR = "127.0.0.1";
|
||||||
HTTP_PORT = 3000;
|
HTTP_PORT = 3000;
|
||||||
START_SSH_SERVER = true;
|
START_SSH_SERVER = true;
|
||||||
|
@ -94,7 +92,7 @@
|
||||||
mailer = {
|
mailer = {
|
||||||
ENABLED = true;
|
ENABLED = true;
|
||||||
PROTOCOL = "smtps";
|
PROTOCOL = "smtps";
|
||||||
SMTP_ADDR = "mail.pub.solar";
|
SMTP_ADDR = "mail.greenbaum.zone";
|
||||||
SMTP_PORT = 465;
|
SMTP_PORT = 465;
|
||||||
FROM = ''"pub.solar git server" <forgejo@pub.solar>'';
|
FROM = ''"pub.solar git server" <forgejo@pub.solar>'';
|
||||||
USER = "admins@pub.solar";
|
USER = "admins@pub.solar";
|
||||||
|
@ -125,7 +123,7 @@
|
||||||
|
|
||||||
# https://forgejo.org/docs/latest/admin/config-cheat-sheet/#webhook-webhook
|
# https://forgejo.org/docs/latest/admin/config-cheat-sheet/#webhook-webhook
|
||||||
webhook = {
|
webhook = {
|
||||||
ALLOWED_HOST_LIST = "loopback,external,*.${config.pub-solar-os.networking.domain}";
|
ALLOWED_HOST_LIST = "loopback,external,*.pub.solar";
|
||||||
};
|
};
|
||||||
|
|
||||||
# See https://forgejo.org/docs/latest/admin/actions/
|
# See https://forgejo.org/docs/latest/admin/actions/
|
||||||
|
@ -141,12 +139,6 @@
|
||||||
LOGIN_REMEMBER_DAYS = 365;
|
LOGIN_REMEMBER_DAYS = 365;
|
||||||
};
|
};
|
||||||
|
|
||||||
# See https://docs.gitea.com/administration/config-cheat-sheet#migrations-migrations
|
|
||||||
migrations = {
|
|
||||||
# This allows migrations from the same forgejo instance
|
|
||||||
ALLOW_LOCALNETWORKS = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# https://forgejo.org/docs/next/admin/config-cheat-sheet/#indexer-indexer
|
# https://forgejo.org/docs/next/admin/config-cheat-sheet/#indexer-indexer
|
||||||
indexer = {
|
indexer = {
|
||||||
REPO_INDEXER_ENABLED = true;
|
REPO_INDEXER_ENABLED = true;
|
||||||
|
@ -169,7 +161,7 @@
|
||||||
# gitea gitconfig
|
# gitea gitconfig
|
||||||
programs.gnupg.agent = {
|
programs.gnupg.agent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
pinentryPackage = pkgs.pinentry-curses;
|
pinentryFlavor = "curses";
|
||||||
};
|
};
|
||||||
# Required to make gpg work without a graphical environment?
|
# Required to make gpg work without a graphical environment?
|
||||||
# otherwise generating a new gpg key fails with this error:
|
# otherwise generating a new gpg key fails with this error:
|
||||||
|
@ -179,16 +171,42 @@
|
||||||
GPG_TTY = "$(tty)";
|
GPG_TTY = "$(tty)";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.restic.backups.forgejo-droppie = {
|
||||||
|
paths = [
|
||||||
|
"/var/lib/forgejo"
|
||||||
|
"/tmp/forgejo-backup.sql"
|
||||||
|
];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "*-*-* 02:00:00 Etc/UTC";
|
||||||
|
# droppie will be offline if nachtigall misses the timer
|
||||||
|
Persistent = false;
|
||||||
|
};
|
||||||
|
initialize = true;
|
||||||
|
passwordFile = config.age.secrets."restic-repo-droppie".path;
|
||||||
|
repository = "sftp:yule@droppie.b12f.io:/media/internal/pub.solar";
|
||||||
|
backupPrepareCommand = ''
|
||||||
|
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d gitea > /tmp/forgejo-backup.sql
|
||||||
|
'';
|
||||||
|
backupCleanupCommand = ''
|
||||||
|
rm /tmp/forgejo-backup.sql
|
||||||
|
'';
|
||||||
|
pruneOpts = [
|
||||||
|
"--keep-daily 7"
|
||||||
|
"--keep-weekly 4"
|
||||||
|
"--keep-monthly 3"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
services.restic.backups.forgejo-storagebox = {
|
services.restic.backups.forgejo-storagebox = {
|
||||||
paths = [
|
paths = [
|
||||||
"/var/lib/forgejo"
|
"/var/lib/forgejo"
|
||||||
"/tmp/forgejo-backup.sql"
|
"/tmp/forgejo-backup.sql"
|
||||||
];
|
];
|
||||||
timerConfig = {
|
timerConfig = {
|
||||||
OnCalendar = "*-*-* 00:00:00 Etc/UTC";
|
OnCalendar = "*-*-* 04:20:00 Etc/UTC";
|
||||||
};
|
};
|
||||||
initialize = true;
|
initialize = true;
|
||||||
passwordFile = config.age.secrets."restic-repo-storagebox-nachtigall".path;
|
passwordFile = config.age.secrets."restic-repo-storagebox".path;
|
||||||
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
|
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
|
||||||
backupPrepareCommand = ''
|
backupPrepareCommand = ''
|
||||||
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d gitea > /tmp/forgejo-backup.sql
|
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d gitea > /tmp/forgejo-backup.sql
|
||||||
|
|
|
@ -1,142 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
flake,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
age.secrets."garage-rpc-secret" = {
|
|
||||||
file = "${flake.self}/secrets/garage-rpc-secret.age";
|
|
||||||
mode = "400";
|
|
||||||
};
|
|
||||||
|
|
||||||
age.secrets."garage-admin-token" = {
|
|
||||||
file = "${flake.self}/secrets/garage-admin-token.age";
|
|
||||||
mode = "400";
|
|
||||||
};
|
|
||||||
|
|
||||||
age.secrets."acme-namecheap-env" = {
|
|
||||||
file = "${flake.self}/secrets/acme-namecheap-env.age";
|
|
||||||
mode = "400";
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
|
||||||
3900
|
|
||||||
3901
|
|
||||||
3902
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.firewall.interfaces.wg-ssh.allowedTCPPorts = [ 3903 ];
|
|
||||||
|
|
||||||
security.acme = {
|
|
||||||
defaults = {
|
|
||||||
# LEGO_DISABLE_CNAME_SUPPORT=true set here to fix issues with CNAME
|
|
||||||
# detection, as we use wildcard DNS for garage
|
|
||||||
environmentFile = config.age.secrets.acme-namecheap-env.path;
|
|
||||||
};
|
|
||||||
certs = {
|
|
||||||
# Wildcard certificate gets created automatically
|
|
||||||
"buckets.${config.pub-solar-os.networking.domain}" = {
|
|
||||||
# disable http challenge
|
|
||||||
webroot = null;
|
|
||||||
# enable dns challenge
|
|
||||||
dnsProvider = "namecheap";
|
|
||||||
};
|
|
||||||
# Wildcard certificate gets created automatically
|
|
||||||
"web.${config.pub-solar-os.networking.domain}" = {
|
|
||||||
# disable http challenge
|
|
||||||
webroot = null;
|
|
||||||
# enable dns challenge
|
|
||||||
dnsProvider = "namecheap";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx = {
|
|
||||||
upstreams.s3_backend.servers = {
|
|
||||||
"[::1]:3900" = { };
|
|
||||||
};
|
|
||||||
upstreams.web_backend.servers = {
|
|
||||||
"[::1]:3902" = { };
|
|
||||||
};
|
|
||||||
virtualHosts."buckets.${config.pub-solar-os.networking.domain}" = {
|
|
||||||
serverAliases = [ "*.buckets.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://s3_backend";
|
|
||||||
extraConfig = ''
|
|
||||||
client_max_body_size 64m;
|
|
||||||
proxy_max_temp_file_size 0;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
virtualHosts."web.${config.pub-solar-os.networking.domain}" = {
|
|
||||||
serverAliases = [ "*.web.${config.pub-solar-os.networking.domain}" ];
|
|
||||||
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://web_backend";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.garage = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.garage_1_0_1;
|
|
||||||
settings = {
|
|
||||||
data_dir = "/var/lib/garage/data";
|
|
||||||
metadata_dir = "/var/lib/garage/meta";
|
|
||||||
db_engine = "lmdb";
|
|
||||||
replication_factor = 3;
|
|
||||||
compression_level = 2;
|
|
||||||
rpc_bind_addr = "[::]:3901";
|
|
||||||
s3_api = {
|
|
||||||
s3_region = "eu-central";
|
|
||||||
api_bind_addr = "[::]:3900";
|
|
||||||
root_domain = ".buckets.${config.pub-solar-os.networking.domain}";
|
|
||||||
};
|
|
||||||
s3_web = {
|
|
||||||
bind_addr = "[::]:3902";
|
|
||||||
root_domain = ".web.${config.pub-solar-os.networking.domain}";
|
|
||||||
index = "index.html";
|
|
||||||
};
|
|
||||||
admin = {
|
|
||||||
api_bind_addr = "[::]:3903";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users.garage = {
|
|
||||||
isSystemUser = true;
|
|
||||||
home = "/var/lib/garage";
|
|
||||||
group = "garage";
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups.garage = { };
|
|
||||||
|
|
||||||
# Adapted from https://git.clan.lol/clan/clan-core/src/commit/23a9e35c665ff531fe1193dcc47056432fbbeacf/clanModules/garage/default.nix
|
|
||||||
# Disabled DynamicUser https://github.com/NixOS/nixpkgs/blob/nixos-24.05/nixos/modules/services/web-servers/garage.nix
|
|
||||||
# for mounts + permissions to work
|
|
||||||
systemd.services.garage = {
|
|
||||||
serviceConfig = {
|
|
||||||
user = "garage";
|
|
||||||
group = "garage";
|
|
||||||
DynamicUser = false;
|
|
||||||
LoadCredential = [
|
|
||||||
"rpc_secret_path:${config.age.secrets.garage-rpc-secret.path}"
|
|
||||||
"admin_token_path:${config.age.secrets.garage-admin-token.path}"
|
|
||||||
];
|
|
||||||
Environment = [
|
|
||||||
"GARAGE_ALLOW_WORLD_READABLE_SECRETS=true"
|
|
||||||
"GARAGE_RPC_SECRET_FILE=%d/rpc_secret_path"
|
|
||||||
"GARAGE_ADMIN_TOKEN_FILE=%d/admin_token_path"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue