forked from Fediversity/Fediversity
properly pass repo dir for prod, be it with hard-coded TF init
This commit is contained in:
parent
ecc41a7dfd
commit
2365d9a044
137 changed files with 8682 additions and 29 deletions
flake.nix
launch
.gitignore
.terraform/modules
mastodon.deploymodules.json
peertube.deploy
CONTRIBUTING.mdLICENSEREADME.md
docs
INDEX.mdSUMMARY.mdbook.tomlcli.mdflake-module.nixhowtos.md
flake.lockflake.nixhowtos
INDEX.mdcustom-kexec.mddisko-modes.mdextra-files.mdipv6.mdlimited-ram.mdnix-path.mdno-os.mdsecrets.mdterraform.mduse-without-flakes.md
logo.pnglogo.svgquickstart.mdreference.mdrequirements.mdscripts
src
terraform
README.mdall-in-one.md
all-in-one
install.mdinstall
nix-build.mdnix-build
nixos-rebuild.mdnixos-rebuild
update-docs.shtests
flake-module.nixfrom-nixos-build-on-remote.nixfrom-nixos-generate-config.nixfrom-nixos-separated-phases.nixfrom-nixos-with-sudo.nixfrom-nixos.nix
lib
modules
treefmt
pixelfed.deploy
CONTRIBUTING.mdLICENSEREADME.md
docs
INDEX.mdSUMMARY.mdbook.tomlcli.mdflake-module.nixhowtos.md
flake.lockflake.nixhowtos
INDEX.mdcustom-kexec.mddisko-modes.mdextra-files.mdipv6.mdlimited-ram.mdnix-path.mdno-os.mdsecrets.mdterraform.mduse-without-flakes.md
logo.pnglogo.svgquickstart.mdreference.mdrequirements.mdscripts
src
terraform
|
@ -43,7 +43,10 @@
|
|||
pre-commit.settings.hooks =
|
||||
let
|
||||
## Add a directory here if pre-commit hooks shouldn't apply to it.
|
||||
optout = [ "npins" ];
|
||||
optout = [
|
||||
"npins"
|
||||
"launch/.terraform"
|
||||
];
|
||||
excludes = map (dir: "^${dir}/") optout;
|
||||
addExcludes = lib.mapAttrs (_: c: c // { inherit excludes; });
|
||||
in
|
||||
|
|
2
launch/.gitignore
vendored
2
launch/.gitignore
vendored
|
@ -1,3 +1,3 @@
|
|||
.terraform/
|
||||
# .terraform/
|
||||
.terraform.tfstate.lock.info
|
||||
terraform.tfstate*
|
||||
|
|
1
launch/.terraform/modules/mastodon.deploy
Symbolic link
1
launch/.terraform/modules/mastodon.deploy
Symbolic link
|
@ -0,0 +1 @@
|
|||
/nix/store/y5ripxky2azz90fzpsj6383f1vljrxkg-source
|
1
launch/.terraform/modules/modules.json
Normal file
1
launch/.terraform/modules/modules.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"mastodon","Source":"./vm","Dir":"vm"},{"Key":"mastodon.deploy","Source":"file:///nix/store/y5ripxky2azz90fzpsj6383f1vljrxkg-source//terraform/all-in-one","Dir":".terraform/modules/mastodon.deploy/terraform/all-in-one"},{"Key":"mastodon.deploy.install","Source":"../install","Dir":"/nix/store/y5ripxky2azz90fzpsj6383f1vljrxkg-source/terraform/install"},{"Key":"mastodon.deploy.nixos-rebuild","Source":"../nixos-rebuild","Dir":"/nix/store/y5ripxky2azz90fzpsj6383f1vljrxkg-source/terraform/nixos-rebuild"},{"Key":"mastodon.deploy.partitioner-build","Source":"../nix-build","Dir":"/nix/store/y5ripxky2azz90fzpsj6383f1vljrxkg-source/terraform/nix-build"},{"Key":"mastodon.deploy.system-build","Source":"../nix-build","Dir":"/nix/store/y5ripxky2azz90fzpsj6383f1vljrxkg-source/terraform/nix-build"},{"Key":"peertube","Source":"./vm","Dir":"vm"},{"Key":"peertube.deploy","Source":"file:///nix/store/y5ripxky2azz90fzpsj6383f1vljrxkg-source//terraform/all-in-one","Dir":".terraform/modules/peertube.deploy/terraform/all-in-one"},{"Key":"peertube.deploy.install","Source":"../install","Dir":".terraform/modules/peertube.deploy/terraform/install"},{"Key":"peertube.deploy.nixos-rebuild","Source":"../nixos-rebuild","Dir":".terraform/modules/peertube.deploy/terraform/nixos-rebuild"},{"Key":"peertube.deploy.partitioner-build","Source":"../nix-build","Dir":".terraform/modules/peertube.deploy/terraform/nix-build"},{"Key":"peertube.deploy.system-build","Source":"../nix-build","Dir":".terraform/modules/peertube.deploy/terraform/nix-build"},{"Key":"pixelfed","Source":"./vm","Dir":"vm"},{"Key":"pixelfed.deploy","Source":"file:///nix/store/y5ripxky2azz90fzpsj6383f1vljrxkg-source//terraform/all-in-one","Dir":".terraform/modules/pixelfed.deploy/terraform/all-in-one"},{"Key":"pixelfed.deploy.install","Source":"../install","Dir":".terraform/modules/pixelfed.deploy/terraform/install"},{"Key":"pixelfed.deploy.nixos-rebuild","Source":"../nixos-rebuild","Dir":".terraform/modules/pixelfed.deploy/terraform/nixos-rebuild"},{"Key":"pixelfed.deploy.partitioner-build","Source":"../nix-build","Dir":".terraform/modules/pixelfed.deploy/terraform/nix-build"},{"Key":"pixelfed.deploy.system-build","Source":"../nix-build","Dir":".terraform/modules/pixelfed.deploy/terraform/nix-build"}]}
|
23
launch/.terraform/modules/peertube.deploy/CONTRIBUTING.md
Normal file
23
launch/.terraform/modules/peertube.deploy/CONTRIBUTING.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
To run `nixos-anywhere` from the repo:
|
||||
|
||||
```console
|
||||
nix run . -- --help
|
||||
```
|
||||
|
||||
To format the code:
|
||||
|
||||
```console
|
||||
nix fmt
|
||||
```
|
||||
|
||||
To run all tests:
|
||||
|
||||
```console
|
||||
nix flake check -vL
|
||||
```
|
||||
|
||||
To run an individual test:
|
||||
|
||||
```
|
||||
nix build .#checks.x86_64-linux.from-nixos -vL
|
||||
```
|
21
launch/.terraform/modules/peertube.deploy/LICENSE
Normal file
21
launch/.terraform/modules/peertube.deploy/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 Numtide
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
123
launch/.terraform/modules/peertube.deploy/README.md
Normal file
123
launch/.terraform/modules/peertube.deploy/README.md
Normal file
|
@ -0,0 +1,123 @@
|
|||
# nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" width="150" height="150">
|
||||
|
||||
[Documentation Index](docs/INDEX.md)
|
||||
|
||||
## README
|
||||
|
||||
Setting up a new machine is time-consuming, and becomes complicated when it
|
||||
needs to be done remotely. If you're installing NixOS, the **nixos-anywhere**
|
||||
tool allows you to pre-configure the whole process including:
|
||||
|
||||
- Disk partitioning and formatting
|
||||
- Configuring and installing NixOS
|
||||
- Installing additional files and software
|
||||
|
||||
You can then initiate an unattended installation with a single CLI command.
|
||||
Since **nixos-anywhere** can access the new machine using SSH, it's ideal for
|
||||
remote installations.
|
||||
|
||||
Once you have initiated the command, there is no need to 'babysit' the
|
||||
installation. It all happens automatically.
|
||||
|
||||
You can use the stored configuration to repeat the same installation if you need
|
||||
to.
|
||||
|
||||
## Overview
|
||||
|
||||
If you have machines on a mix of platforms, you'll need a common installation
|
||||
solution that works anywhere. **nixos-anywhere** is ideal in this situation.
|
||||
|
||||
**nixos-anywhere** can be used equally well for cloud servers, bare metal
|
||||
servers such as Hetzner, and local servers accessible via a LAN. You can create
|
||||
standard configurations, and use the same configuration to create identical
|
||||
servers anywhere.
|
||||
|
||||
You first create Nix configurations to specify partitioning, formatting and
|
||||
NixOS configurations. Further options can be controlled by a flake and by
|
||||
run-time switches.
|
||||
|
||||
Once the configuration has been created, a single command will:
|
||||
|
||||
- Connect to the remote server via SSH
|
||||
- Detect whether a NixOS installer is present; if not, it will use the Linux
|
||||
`kexec` tool to boot into a Nixos installer.
|
||||
- Use the [disko](https://github.com/nix-community/disko) tool to partition and
|
||||
format the hard drive
|
||||
- Install NixOS
|
||||
- Optionally install any Nix packages and other software required.
|
||||
- Optionally copy additional files to the new machine
|
||||
|
||||
It's also possible to use **nixos-anywhere** to simplify the installation on a
|
||||
machine that has no current operating system, first booting from a NixOS
|
||||
installer image. This feature is described in the
|
||||
[how-to guide](./docs/howtos/no-os.md#installing-on-a-machine-with-no-operating-system).
|
||||
It's useful because you can pre-configure your required software and
|
||||
preferences, and build the new machine with a single command.
|
||||
|
||||
**Important Note:** Never use a production server as the target. It will be
|
||||
completely overwritten and all data lost. This tool should only be used for
|
||||
commissioning a new computer or repurposing an old machine once all important
|
||||
data has been migrated.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Source Machine:
|
||||
|
||||
- Can be any machine with Nix installed, e.g. a NixOS machine.
|
||||
|
||||
- Target Machine:
|
||||
|
||||
- Unless you're using the option to boot from a NixOS installer image, or
|
||||
providing your own `kexec` image, it must be running x86-64 Linux with kexec
|
||||
support. Most `x86_64` Linux systems do have kexec support. By providing
|
||||
your own [image](./docs/howtos/custom-kexec.md#using-your-own-kexec-image)
|
||||
you can also perform kexec for other architectures eg aarch64
|
||||
- The machine must be reachable over the public internet or local network.
|
||||
Nixos-anywhere does not support wifi networks. If a VPN is needed, define a
|
||||
custom installer via the --kexec flag which connects to your VPN.
|
||||
- When `kexec` is used the target must have at least 1 GB of RAM, excluding
|
||||
swap.
|
||||
|
||||
## How to use nixos-anywhere
|
||||
|
||||
The [Quickstart Guide](./docs/quickstart.md) gives more information on how to
|
||||
run **nixos-anywhere** in its simplest form. For more specific instructions to
|
||||
suit individual requirements, see the [How To Guide](./docs/howtos/INDEX.md).
|
||||
|
||||
## Related Tools
|
||||
|
||||
**nixos-anywhere** makes use of the
|
||||
[disko](https://github.com/nix-community/disko) tool to handle the partitioning
|
||||
and formatting of the disks.
|
||||
|
||||
## Contact
|
||||
|
||||
For questions, come join us in the
|
||||
[nixos-anywhere](https://matrix.to/#/#nixos-anywhere:nixos.org) matrix room.
|
||||
|
||||
## Licensing and Contribution details
|
||||
|
||||
This software is provided free under the
|
||||
[MIT License](https://opensource.org/licenses/MIT).
|
||||
|
||||
---
|
||||
|
||||
This project is supported by [Numtide](https://numtide.com/).
|
||||

|
||||
|
||||
We are a team of independent freelancers that love open source. We help our
|
||||
customers make their project lifecycles more efficient by:
|
||||
|
||||
- Providing and supporting useful tools such as this one
|
||||
- Building and deploying infrastructure, and offering dedicated DevOps support
|
||||
- Building their in-house Nix skills, and integrating Nix with their workflows
|
||||
- Developing additional features and tools
|
||||
- Carrying out custom research and development.
|
||||
|
||||
[Contact us](https://numtide.com/contact) if you have a project in mind, or if
|
||||
you need help with any of our supported tools, including this one. We'd love to
|
||||
hear from you.
|
11
launch/.terraform/modules/peertube.deploy/docs/INDEX.md
Normal file
11
launch/.terraform/modules/peertube.deploy/docs/INDEX.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Table of Content: - nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img title="" src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" alt="" width="149">
|
||||
|
||||
- [README](../README.md)
|
||||
- [Quickstart](./quickstart.md)
|
||||
- [System Requirements](./requirements.md)
|
||||
- [How to Guide](./howtos/INDEX.md)
|
||||
- [Reference](./reference.md)
|
26
launch/.terraform/modules/peertube.deploy/docs/SUMMARY.md
Normal file
26
launch/.terraform/modules/peertube.deploy/docs/SUMMARY.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Summary: - nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img title="" src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" alt="" width="149">
|
||||
|
||||
The **nixos-anywhere** tool allows you to pre-configure the whole process of
|
||||
installing NixOS, and run the install remotely with a single CLI command.
|
||||
|
||||
Refer to the following documentation for more information.
|
||||
|
||||
[System Requirements](./requirements.md): CPU and memory requirements
|
||||
|
||||
[Quickstart](./quickstart.md): Instructions for a typical installation
|
||||
|
||||
[How to Guide](./howtos/INDEX.md): Instructions for non-typical use cases
|
||||
|
||||
- [Installing on a machine with no operating system](./howtos/no-os.md)
|
||||
- [Using your own kexec image](./howtos/custom-kexec.md)
|
||||
- [Secrets and full disk encryption](./howtos/secrets.md)
|
||||
- [Use without flakes](./howtos/use-without-flakes.md)
|
||||
- [Terraform](./howtos/terraform.md)
|
||||
- [Nix-channels / `NIX_PATH`](./howtos/nix-path.md)
|
||||
- [IPv6-only targets](./howtos/ipv6.md)
|
||||
|
||||
[Reference](./reference.md): Reference Guide
|
6
launch/.terraform/modules/peertube.deploy/docs/book.toml
Normal file
6
launch/.terraform/modules/peertube.deploy/docs/book.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[book]
|
||||
authors = [ ]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "."
|
||||
title = "nixos-anywhere - install NixOS everywhere"
|
63
launch/.terraform/modules/peertube.deploy/docs/cli.md
Normal file
63
launch/.terraform/modules/peertube.deploy/docs/cli.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
# CLI
|
||||
|
||||
```
|
||||
Usage: nixos-anywhere [options] [<ssh-host>]
|
||||
|
||||
Options:
|
||||
|
||||
* -f, --flake <flake_uri>
|
||||
set the flake to install the system from.
|
||||
* --target-host <ssh-host>
|
||||
specified the SSH target host to deploy onto.
|
||||
* -i <identity_file>
|
||||
selects which SSH private key file to use.
|
||||
* -p, --ssh-port <ssh_port>
|
||||
set the ssh port to connect with
|
||||
* --ssh-option <ssh_option>
|
||||
set an ssh option
|
||||
* -L, --print-build-logs
|
||||
print full build logs
|
||||
* --env-password
|
||||
set a password used by ssh-copy-id, the password should be set by
|
||||
the environment variable SSHPASS
|
||||
* -s, --store-paths <disko-script> <nixos-system>
|
||||
set the store paths to the disko-script and nixos-system directly
|
||||
if this is given, flake is not needed
|
||||
* --no-reboot
|
||||
do not reboot after installation, allowing further customization of the target installation.
|
||||
* --kexec <path>
|
||||
use another kexec tarball to bootstrap NixOS
|
||||
* --kexec-extra-flags
|
||||
extra flags to add into the call to kexec, e.g. "--no-sync"
|
||||
* --ssh-store-setting <key> <value>
|
||||
ssh store settings appended to the store URI, e.g. "compress true". <value> needs to be URI encoded.
|
||||
* --post-kexec-ssh-port <ssh_port>
|
||||
after kexec is executed, use a custom ssh port to connect. Defaults to 22
|
||||
* --copy-host-keys
|
||||
copy over existing /etc/ssh/ssh_host_* host keys to the installation
|
||||
* --stop-after-disko
|
||||
exit after disko formatting, you can then proceed to install manually or some other way
|
||||
* --extra-files <path>
|
||||
contents of local <path> are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten
|
||||
Copied files will be owned by root. See documentation for details.
|
||||
* --disk-encryption-keys <remote_path> <local_path>
|
||||
copy the contents of the file or pipe in local_path to remote_path in the installer environment,
|
||||
after kexec but before installation. Can be repeated.
|
||||
* --no-substitute-on-destination
|
||||
disable passing --substitute-on-destination to nix-copy
|
||||
* --debug
|
||||
enable debug output
|
||||
* --option <key> <value>
|
||||
nix option to pass to every nix related command
|
||||
* --from <store-uri>
|
||||
URL of the source Nix store to copy the nixos and disko closure from
|
||||
* --build-on-remote
|
||||
build the closure on the remote machine instead of locally and copy-closuring it
|
||||
* --vm-test
|
||||
build the system and test the disk configuration inside a VM without installing it to the target.
|
||||
* --build-on auto|remote|local
|
||||
sets the build on settings to auto, remote or local. Default is auto.
|
||||
auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build
|
||||
local: will build on the local host
|
||||
remote: will build on the remote host
|
||||
```
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
perSystem =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
packages.docs =
|
||||
pkgs.runCommand "nixos-anywhere-docs"
|
||||
{
|
||||
passthru.serve = pkgs.writeShellScriptBin "serve" ''
|
||||
set -euo pipefail
|
||||
cd docs
|
||||
workdir=$(${pkgs.coreutils}/bin/mktemp -d)
|
||||
trap 'rm -rf "$workdir"' EXIT
|
||||
${pkgs.mdbook}/bin/mdbook serve --dest-dir "$workdir"
|
||||
'';
|
||||
}
|
||||
''
|
||||
cp -r ${lib.cleanSource ./.}/* .
|
||||
${pkgs.mdbook}/bin/mdbook build --dest-dir "$out"
|
||||
'';
|
||||
};
|
||||
}
|
1
launch/.terraform/modules/peertube.deploy/docs/howtos.md
Normal file
1
launch/.terraform/modules/peertube.deploy/docs/howtos.md
Normal file
|
@ -0,0 +1 @@
|
|||
# How to Guide
|
|
@ -0,0 +1,29 @@
|
|||
# How To Guide: nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img title="" src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" alt="" width="129">
|
||||
|
||||
[Documentation Index](./INDEX.md)
|
||||
|
||||
## Contents
|
||||
|
||||
[Installing on a machine with no operating system](./no-os.md)
|
||||
|
||||
[Kexec on systems with limited RAM](./limited-ram.md)
|
||||
|
||||
[Copying files to the new installation](./extra-files.md)
|
||||
|
||||
[Using your own kexec image](./custom-kexec.md)
|
||||
|
||||
[Repair installations without wiping data](./disko-modes.md)
|
||||
|
||||
[Secrets and full disk encryption](./secrets.md)
|
||||
|
||||
[Use without flakes](./use-without-flakes.md)
|
||||
|
||||
[Terraform](./terraform.md)
|
||||
|
||||
[Nix-channels / `NIX_PATH`](./nix-path.md)
|
||||
|
||||
[IPv6-only targets](./ipv6.md)
|
|
@ -0,0 +1,40 @@
|
|||
# Using your own kexec image
|
||||
|
||||
By default, `nixos-anywhere` downloads the kexec image from the
|
||||
[NixOS images repository](https://github.com/nix-community/nixos-images#kexec-tarballs).
|
||||
|
||||
However, you can provide your own `kexec` image file if you need to use a
|
||||
different one. This is particularly useful for architectures other than `x86_64`
|
||||
and `aarch64`, since they don't have a pre-build image.
|
||||
|
||||
To do this, use the `--kexec` command line switch followed by the path to your
|
||||
image file. The image will be uploaded prior to execution.
|
||||
|
||||
Here's an example command that demonstrates how to use a custom kexec image with
|
||||
`nixos-anywhere`:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- \
|
||||
--kexec "$(nix build --print-out-paths github:nix-community/nixos-images#packages.aarch64-linux.kexec-installer-nixos-unstable-noninteractive)/nixos-kexec-installer-noninteractive-aarch64-linux.tar.gz" \
|
||||
--flake 'github:your-user/your-repo#your-system' \
|
||||
root@yourip
|
||||
```
|
||||
|
||||
Make sure to replace `github:your-user/your-repo#your-system` with the
|
||||
appropriate Flake URL representing your NixOS configuration.
|
||||
|
||||
The example above assumes that your local machine can build for aarch64 in one
|
||||
of the following ways:
|
||||
|
||||
- Natively
|
||||
|
||||
- Through a remote builder
|
||||
|
||||
- By emulating the architecture with qemu using the following NixOS
|
||||
configuration:
|
||||
|
||||
```nix
|
||||
{
|
||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
||||
}
|
||||
```
|
|
@ -0,0 +1,19 @@
|
|||
# Repair installations without wiping data
|
||||
|
||||
By default, nixos-anywhere will reformat all configured disks before running the
|
||||
installation. However it is also possible to mount the filesystems of an
|
||||
existing installation and run `nixos-install`. This is useful to recover from a
|
||||
misconfigured NixOS installation by first booting into a NixOS installer or
|
||||
recovery system.
|
||||
|
||||
To only mount existing filesystems, add `--disko-mode mount` to
|
||||
`nixos-anywhere`:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --disko-mode mount --flake <path to configuration>#<configuration name> --target-host root@<ip address>
|
||||
```
|
||||
|
||||
1. This will first boot into a nixos-installer
|
||||
2. Mounts disks with disko
|
||||
3. Runs nixos-install based on the provided flake
|
||||
4. Reboots the machine.
|
|
@ -0,0 +1,114 @@
|
|||
# Copying files to the new installation
|
||||
|
||||
The `--extra-files <path>` option allows copying files to the target host after
|
||||
installation.
|
||||
|
||||
The contents of the `<path>` is recursively copied and overwrites the targets
|
||||
root (/). The contents _must_ be in a structure and permissioned as it should be
|
||||
on the target.
|
||||
|
||||
In this way, there is no need to repeatedly pass arguments (eg: a fictional
|
||||
argument: `--copy <source> <dest>`) to `nixos-anywhere` to complete the intended
|
||||
outcome.
|
||||
|
||||
The path and directory structure passed to `--extra-files` should be prepared
|
||||
beforehand.
|
||||
|
||||
This allows a simple programmatic invocation of `nixos-anywhere` for multiple
|
||||
hosts.
|
||||
|
||||
## Simple Example
|
||||
|
||||
You want `/etc/ssh/ssh_host_*` and `/persist` from the local system on the
|
||||
target. The `<path>` contents will look like this:
|
||||
|
||||
```console
|
||||
$ cd /tmp
|
||||
$ root=$(mktemp -d)
|
||||
$ sudo cp --verbose --archive --parents /etc/ssh/ssh_host_* ${root}
|
||||
$ cp --verbose --archive --link /persist ${root}
|
||||
```
|
||||
|
||||
The directory structure would look like this:
|
||||
|
||||
```console
|
||||
drwx------ myuser1 users 20 tmp.d6nx5QUwPN
|
||||
drwxr-xr-x root root 6 ├── etc
|
||||
drwx------ myuser1 users 160 │ └── ssh
|
||||
.rw------- root root 399 │ ├── ssh_host_ed25519_key
|
||||
.rw-r--r-- root root 91 │ ├── ssh_host_ed25519_key.pub
|
||||
drwxr-xr-x myuser1 users 22 └── persist
|
||||
drwxr-xr-x myuser1 users 14 ├── all
|
||||
drwxr-xr-x myuser1 users 22 │ ├── my
|
||||
.rw-r--r-- myuser1 users 6 │ │ ├── test3
|
||||
drwxr-xr-x myuser1 users 10 │ │ └── things
|
||||
.rw-r--r-- myuser1 users 6 │ │ └── test4
|
||||
.rw-r--r-- myuser1 users 6 │ └── test2
|
||||
drwxr-xr-x myuser1 users 0 ├── blah
|
||||
.rw-r--r-- myuser1 users 6 └── test
|
||||
```
|
||||
|
||||
**NOTE**: Permissions will be copied, but ownership on the target will be root.
|
||||
|
||||
Then pass $root like:
|
||||
|
||||
> nixos-anywhere --flake ".#" --extra-files $root --target-host root@newhost
|
||||
|
||||
## Programmatic Example
|
||||
|
||||
```sh
|
||||
for host in host1 host2 host3; do
|
||||
root="target/${host}"
|
||||
install -d -m755 ${root}/etc/ssh
|
||||
ssh-keygen -A -C root@${host} -f ${root}
|
||||
nixos-anywhere --extra-files "${root}" --flake ".#${host}" --target-host "root@${host}"
|
||||
done
|
||||
```
|
||||
|
||||
## Considerations
|
||||
|
||||
### Ownership
|
||||
|
||||
The new system may have differing UNIX user and group id's for users created
|
||||
during installation.
|
||||
|
||||
When the files are extracted on the remote the copied data will be owned by
|
||||
root.
|
||||
|
||||
If you wish to change the ownership after the files are copied onto the system,
|
||||
you can use the `--chown` option.
|
||||
|
||||
For example, if you did `--chown /home/myuser/.ssh 1000:100`, this would equate
|
||||
to running `chown -R /home/myuser/.ssh 1000:100` where the uid is 1000 and the
|
||||
gid is 100. **Only do this when you can _guarantee_ what the uid and gid will
|
||||
be.**
|
||||
|
||||
### Symbolic Links
|
||||
|
||||
Do not create symbolic links to reference data to copy.
|
||||
|
||||
GNU `tar` is used to do the copy over ssh. It is an archival tool used to
|
||||
re/store directory structures as is. Thus `tar` copies symbolic links created
|
||||
with `ln -s` by default. It does not follow them to copy the underlying file.
|
||||
|
||||
### Hard links
|
||||
|
||||
**NOTE**: hard links can only be created on the same filesystem.
|
||||
|
||||
If you have larger persistent data to copy to the target. GNU `tar` will copy
|
||||
data referenced by hard links created with `ln`. A hard link does not create
|
||||
another copy the data.
|
||||
|
||||
To copy a directory tree to the new target you can use the `cp` command with the
|
||||
`--link` option which creates hard links.
|
||||
|
||||
#### Example
|
||||
|
||||
```sh
|
||||
cd /tmp
|
||||
root=$(mktemp -d)
|
||||
cp --verbose --archive --link --parents /persist/home/myuser ${root}
|
||||
```
|
||||
|
||||
`--parents` will create the directory structure of the source at the
|
||||
destination.
|
|
@ -0,0 +1,23 @@
|
|||
# NixOS-anywhere on IPv6-only targets
|
||||
|
||||
As GitHub engineers still haven't enabled the IPv6 switch, the kexec image
|
||||
hosted on GitHub, cannot be used unfortunately on IPv6-only hosts. However it is
|
||||
possible to use an IPv6 proxy for GitHub content like that:
|
||||
|
||||
```
|
||||
nixos-anywhere \
|
||||
--kexec https://gh-v6.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \
|
||||
...
|
||||
```
|
||||
|
||||
This proxy is hosted by [numtide](https://numtide.com/). It also works for IPv4.
|
||||
|
||||
Alternatively it is also possible to reference a local file:
|
||||
|
||||
```
|
||||
nixos-anywhere \
|
||||
--kexec ./nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \
|
||||
...
|
||||
```
|
||||
|
||||
This tarball will be then uploaded via sftp to the target.
|
|
@ -0,0 +1,29 @@
|
|||
# Kexec on Systems with Limited RAM
|
||||
|
||||
When working with nixos-anywhere on systems with limited RAM (around 1GB), you
|
||||
can use the `--no-disko-deps` option to reduce memory usage during installation.
|
||||
|
||||
## How it works
|
||||
|
||||
The `--no-disko-deps` option uploads only the disko partitioning script without
|
||||
including its dependencies. This significantly reduces memory usage because:
|
||||
|
||||
1. The installer normally stores all dependencies in memory
|
||||
2. Partitioning tools can be quite large when bundled with their dependencies
|
||||
|
||||
## Usage example
|
||||
|
||||
```bash
|
||||
nix run github:nix-community/nixos-anywhere -- --no-disko-deps --flake <path to configuration>#<configuration name> --target-host root@<ip address>
|
||||
```
|
||||
|
||||
## Trade-off
|
||||
|
||||
While this approach saves memory, it means the partitioning tools will be
|
||||
whatever versions are available on the target system, rather than the specific
|
||||
versions defined in your NixOS configuration. This could potentially lead to
|
||||
version inconsistencies between the partitioning tools and the NixOS system
|
||||
being installed.
|
||||
|
||||
This trade-off is usually acceptable for memory-constrained environments where
|
||||
installation would otherwise fail due to insufficient RAM.
|
|
@ -0,0 +1,57 @@
|
|||
# Nix-channels / `NIX_PATH`
|
||||
|
||||
nixos-anywhere does not install channels onto the new system by default to save
|
||||
time and disk space. This for example results in errors like:
|
||||
|
||||
```
|
||||
(stack trace truncated; use '--show-trace' to show the full trace)
|
||||
|
||||
error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)
|
||||
|
||||
at «none»:0: (source not available)
|
||||
```
|
||||
|
||||
when using tools like nix-shell/nix-env that rely on `NIX_PATH` being set.
|
||||
|
||||
# Solution 1: Set the `NIX_PATH` via nixos configuration (recommended)
|
||||
|
||||
Instead of stateful channels, one can also populate the `NIX_PATH` using nixos
|
||||
configuration instead:
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
# ... other inputs
|
||||
|
||||
outputs = inputs@{ nixpkgs, ... }:
|
||||
{
|
||||
nixosConfigurations.yoursystem = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux"; # adapt to your actual system
|
||||
modules = [
|
||||
# This line will populate NIX_PATH
|
||||
{ nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; }
|
||||
# ... other modules and your configuration.nix
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Advantage: This solution will be automatically kept up-to-date every time the
|
||||
flake is updated.
|
||||
|
||||
In your shell you will see something in your `$NIX_PATH`:
|
||||
|
||||
```shellSession
|
||||
$ echo $NIX_PATH
|
||||
/root/.nix-defexpr/channels:nixpkgs=/nix/store/8b61j28rpy11dg8hanbs2x710d8w3v0d-source
|
||||
```
|
||||
|
||||
# Solution 2: Manually add the channel
|
||||
|
||||
On the installed machine, run:
|
||||
|
||||
```shellSession
|
||||
$ nix-channel --add https://nixos.org/channels/nixos-unstable nixos
|
||||
$ nix-channel --update
|
||||
```
|
|
@ -0,0 +1,71 @@
|
|||
# Installing on a machine with no operating system
|
||||
|
||||
If your machine doesn't currently have an operating system installed, you can
|
||||
still run `nixos-anywhere` remotely to automate the install. To do this, you
|
||||
would first need to boot the target machine from the standard NixOS installer.
|
||||
You can either boot from a USB or use `netboot`.
|
||||
|
||||
The
|
||||
[NixOS installation guide](https://nixos.org/manual/nixos/stable/index.html#sec-booting-from-usb)
|
||||
has detailed instructions on how to boot the installer.
|
||||
|
||||
When you run `nixos-anywhere`, it will determine whether a NixOS installer is
|
||||
present by checking whether the `/etc/os-release` file contains the identifier
|
||||
`VARIANT_ID=installer`. This identifier is available on releases NixOS 23.05 or
|
||||
later.
|
||||
|
||||
If an installer is detected, `nixos-anywhere` will not attempt to `kexec` into
|
||||
its own image. This is particularly useful for targets that don't have enough
|
||||
RAM for `kexec` or don't support `kexec`.
|
||||
|
||||
NixOS starts an SSH server on the installer by default, but you need to set a
|
||||
password in order to access it. To set a password for the `nixos` user, run the
|
||||
following command in a terminal on the NixOS machine:
|
||||
|
||||
```
|
||||
passwd
|
||||
```
|
||||
|
||||
If you don't know the IP address of the installer on your network, you can find
|
||||
it by running the following command:
|
||||
|
||||
```
|
||||
$ ip addr
|
||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
|
||||
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
||||
inet 127.0.0.1/8 scope host lo
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 ::1/128 scope host
|
||||
valid_lft forever preferred_lft forever
|
||||
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
||||
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
|
||||
altname enp0s3
|
||||
altname ens3
|
||||
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0
|
||||
valid_lft 86385sec preferred_lft 75585sec
|
||||
inet6 fec0::5054:ff:fe12:3456/64 scope site dynamic mngtmpaddr noprefixroute
|
||||
valid_lft 86385sec preferred_lft 14385sec
|
||||
inet6 fe80::5054:ff:fe12:3456/64 scope link
|
||||
valid_lft forever preferred_lft forever
|
||||
```
|
||||
|
||||
This will display the IP addresses assigned to your network interface(s),
|
||||
including the IP address of the installer. In the example output below, the
|
||||
installer's IP addresses are `10.0.2.15`, `fec0::5054:ff:fe12:3456`, and
|
||||
`fe80::5054:ff:fe12:3456%eth0`:
|
||||
|
||||
To test if you can connect and your password works, you can use the following
|
||||
SSH command (replace the IP address with your own):
|
||||
|
||||
```
|
||||
ssh -v nixos@fec0::5054:ff:fe12:3456
|
||||
```
|
||||
|
||||
You can then use the IP address to run `nixos-anywhere` like this:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --flake '.#myconfig' --target-host nixos@fec0::5054:ff:fe12:3456
|
||||
```
|
||||
|
||||
This example assumes a flake in the current directory containing a configuration
|
||||
named `myconfig`.
|
|
@ -0,0 +1,76 @@
|
|||
# Secrets and full disk encryption
|
||||
|
||||
The `nixos-anywhere` utility offers the capability to install secrets onto a
|
||||
target machine. This feature is particularly beneficial when you want to
|
||||
bootstrap secrets management tools such as
|
||||
[sops-nix](https://github.com/Mic92/sops-nix) or
|
||||
[agenix](https://github.com/ryantm/agenix), which rely on machine-specific
|
||||
secrets to decrypt other uploaded secrets.
|
||||
|
||||
## Example: Decrypting an OpenSSH Host Key with pass
|
||||
|
||||
In this example, we demonstrate how to use a script to decrypt an OpenSSH host
|
||||
key from the `pass` password manager and subsequently pass it to
|
||||
`nixos-anywhere` during the installation process:
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Create a temporary directory
|
||||
temp=$(mktemp -d)
|
||||
|
||||
# Function to cleanup temporary directory on exit
|
||||
cleanup() {
|
||||
rm -rf "$temp"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Create the directory where sshd expects to find the host keys
|
||||
install -d -m755 "$temp/etc/ssh"
|
||||
|
||||
# Decrypt your private key from the password store and copy it to the temporary directory
|
||||
pass ssh_host_ed25519_key > "$temp/etc/ssh/ssh_host_ed25519_key"
|
||||
|
||||
# Set the correct permissions so sshd will accept the key
|
||||
chmod 600 "$temp/etc/ssh/ssh_host_ed25519_key"
|
||||
|
||||
# Install NixOS to the host system with our secrets
|
||||
nixos-anywhere --extra-files "$temp" --flake '.#your-host' --target-host root@yourip
|
||||
```
|
||||
|
||||
## Example: Uploading Disk Encryption Secrets
|
||||
|
||||
In a similar vein, `nixos-anywhere` can upload disk encryption secrets, which
|
||||
are necessary during formatting with disko. Here's an example that demonstrates
|
||||
how to provide your disk encryption password as a file or via the `pass` utility
|
||||
to `nixos-anywhere`:
|
||||
|
||||
```bash
|
||||
# Write your disk encryption password to a file
|
||||
echo "my-super-safe-password" > /tmp/disk-1.key
|
||||
|
||||
# Call nixos-anywhere with disk encryption keys
|
||||
nixos-anywhere \
|
||||
--disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \
|
||||
--disk-encryption-keys /tmp/disk-2.key <(pass my-disk-encryption-password) \
|
||||
--flake '.#your-host' \
|
||||
root@yourip
|
||||
```
|
||||
|
||||
In the above example, replace `"my-super-safe-password"` with your actual
|
||||
encryption password, and `my-disk-encryption-password` with the relevant entry
|
||||
in your pass password store. Also, ensure to replace `'.#your-host'` and
|
||||
`root@yourip` with your actual flake and IP address, respectively.
|
||||
|
||||
## Example: Using existing SSH host keys
|
||||
|
||||
If the system contains existing trusted `/etc/ssh/ssh_host_*` SSH host keys and
|
||||
certificates, `nixos-anywhere` can copy them in case they are necessary during
|
||||
installation and system activation.
|
||||
|
||||
```
|
||||
nixos-anywhere --copy-host-keys --flake '.#your-host' root@yourip
|
||||
```
|
||||
|
||||
This would copy `/etc/ssh/ssh_host_*` to `/mnt` after kexec but before
|
||||
installation, ignoring files that already exist in destination.
|
|
@ -0,0 +1,23 @@
|
|||
# Terraform
|
||||
|
||||
The nixos-anywhere terraform modules allow you to use Terraform for installing
|
||||
and updating NixOS. It simplifies the deployment process by integrating
|
||||
nixos-anywhere functionality.
|
||||
|
||||
Our terraform module requires the
|
||||
[null](https://registry.terraform.io/providers/hashicorp/null/latest) and
|
||||
[external](https://registry.terraform.io/providers/hashicorp/external/latest)
|
||||
provider.
|
||||
|
||||
You can get these by from nixpkgs like this:
|
||||
|
||||
```nix
|
||||
nix-shell -p '(pkgs.terraform.withPlugins (p: [ p.null p.external ]))'
|
||||
```
|
||||
|
||||
You can add this expression the `packages` list in your devshell in flake.nix or
|
||||
in shell.nix.
|
||||
|
||||
Checkout out the
|
||||
[module reference](https://github.com/nix-community/nixos-anywhere/tree/main/terraform)
|
||||
for examples and module parameter on how to use the modules.
|
|
@ -0,0 +1,82 @@
|
|||
# Use without flakes
|
||||
|
||||
First,
|
||||
[import the disko NixOS module](https://github.com/nix-community/disko/blob/master/docs/HowTo.md#installing-nixos-module)
|
||||
in your NixOS configuration and define disko devices as described in the
|
||||
[examples](https://github.com/nix-community/disko/tree/master/example).
|
||||
|
||||
Let's assume that your NixOS configuration lives in `configuration.nix` and your
|
||||
target machine is called `machine`:
|
||||
|
||||
## 1. Download your favourite disk layout:
|
||||
|
||||
See https://github.com/nix-community/disko-templates/ for more examples:
|
||||
|
||||
The example below will work with both UEFI and BIOS-based systems.
|
||||
|
||||
```bash
|
||||
curl https://raw.githubusercontent.com/nix-community/disko-templates/main/single-disk-ext4/disko-config.nix > ./disko-config.nix
|
||||
```
|
||||
|
||||
## 2. Get a hardware-configuration.nix from on the target machine
|
||||
|
||||
- **Option 1**: If NixOS is not installed, boot into an installer without first
|
||||
installing NixOS.
|
||||
- **Option 2**: Use the kexec tarball method, as described
|
||||
[here](https://github.com/nix-community/nixos-images#kexec-tarballs).
|
||||
|
||||
- **Generate Configuration**: Run the following command on the target machine:
|
||||
|
||||
```bash
|
||||
nixos-generate-config --no-filesystems --dir /tmp/config
|
||||
```
|
||||
|
||||
This creates the necessary configuration files under `/tmp/config/`. Copy
|
||||
`/tmp/config/nixos/hardware-configuration.nix` to your local machine into the
|
||||
same directory as `disko-config.nix`.
|
||||
|
||||
## 3. Set NixOS version to use
|
||||
|
||||
```nix
|
||||
# default.nix
|
||||
let
|
||||
# replace nixos-24.11 with your preferred nixos version or revision from here: https://status.nixos.org/
|
||||
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-24.11.tar.gz";
|
||||
in
|
||||
import (nixpkgs + "/nixos/lib/eval-config.nix") {
|
||||
modules = [ ./configuration.nix ];
|
||||
}
|
||||
```
|
||||
|
||||
## 4. Write a NixOS configuration
|
||||
|
||||
```nix
|
||||
# configuration.nix
|
||||
{
|
||||
imports = [
|
||||
"${fetchTarball "https://github.com/nix-community/disko/tarball/master"}/module.nix"
|
||||
./disko-config.nix
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
# Replace this with the system of the installation target you want to install!!!
|
||||
disko.devices.disk.main.device = "/dev/sda";
|
||||
|
||||
# Set this to the NixOS version that you have set in the previous step.
|
||||
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
||||
system.stateVersion = "24.11";
|
||||
}
|
||||
```
|
||||
|
||||
## 5. Build and deploy with nixos-anywhere
|
||||
|
||||
Your current directory now should contain the following files from the previous
|
||||
step:
|
||||
|
||||
- `configuration.nix`, `default.nix`, `disko-config.nix` and
|
||||
`hardware-configuration.nix`
|
||||
|
||||
Run `nixos-anywhere` as follows:
|
||||
|
||||
```bash
|
||||
nixos-anywhere --store-paths $(nix-build -A config.system.build.formatScript -A config.system.build.toplevel --no-out-link) root@machine
|
||||
```
|
BIN
launch/.terraform/modules/peertube.deploy/docs/logo.png
Normal file
BIN
launch/.terraform/modules/peertube.deploy/docs/logo.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 29 KiB |
133
launch/.terraform/modules/peertube.deploy/docs/logo.svg
Normal file
133
launch/.terraform/modules/peertube.deploy/docs/logo.svg
Normal file
|
@ -0,0 +1,133 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
width="512"
|
||||
height="512"
|
||||
id="svg322"
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
inkscape:export-filename="logo.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#">
|
||||
<defs
|
||||
id="defs326">
|
||||
<marker
|
||||
markerWidth="512"
|
||||
markerHeight="512"
|
||||
refX="256"
|
||||
refY="256"
|
||||
orient="auto"
|
||||
id="marker11007">
|
||||
<path
|
||||
d="M 0,0 H 512 V 512 H 0 Z"
|
||||
fill="#fbfdfc"
|
||||
id="path246" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview324"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.2304247"
|
||||
inkscape:cx="32.280848"
|
||||
inkscape:cy="129.79591"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2090"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg322" />
|
||||
<path
|
||||
d="M0,0 L4,2 L18,10 L27,18 L30,26 L30,34 L27,46 L23,60 L17,73 L8,94 L3,105 L3,116 L7,119 L13,121 L39,126 L55,131 L64,137 L68,142 L70,146 L70,154 L66,162 L57,170 L45,176 L37,179 L20,182 L11,183 L-17,184 L-24,192 L-34,206 L-47,221 L-59,232 L-73,241 L-85,246 L-93,248 L-113,248 L-127,245 L-132,243 L-132,241 L-123,235 L-113,226 L-105,218 L-96,205 L-88,189 L-82,168 L-80,136 L-72,125 L-54,98 L-38,71 L-23,44 L-13,25 L-5,9 Z "
|
||||
fill="#517ED0"
|
||||
transform="translate(435,104)"
|
||||
id="path248" />
|
||||
<path
|
||||
d="M0,0 L10,1 L19,6 L31,17 L40,26 L49,37 L57,48 L67,62 L75,74 L91,75 L107,78 L127,85 L141,93 L153,105 L160,115 L167,130 L170,139 L171,149 L162,146 L155,143 L138,139 L110,139 L93,143 L87,146 L80,146 L71,144 L57,142 L22,140 L-23,140 L-45,141 L-65,143 L-74,143 L-81,135 L-83,129 L-83,117 L-79,109 L-73,102 L-63,95 L-46,87 L-28,82 L-11,79 L14,79 L11,71 L-2,48 L-10,34 L-14,23 L-14,13 L-11,7 L-5,2 Z "
|
||||
fill="#517DD0"
|
||||
transform="translate(132,13)"
|
||||
id="path250" />
|
||||
<path
|
||||
d="M0,0 L11,2 L20,5 L29,7 L55,7 L72,4 L80,2 L104,7 L126,9 L142,10 L234,10 L240,14 L245,20 L246,24 L246,33 L241,43 L234,50 L221,58 L205,65 L183,70 L162,73 L151,73 L159,87 L174,112 L179,122 L180,125 L180,136 L175,145 L167,150 L153,150 L143,143 L130,130 L117,113 L107,99 L95,80 L90,76 L71,74 L50,69 L34,62 L23,54 L15,46 L8,34 L2,17 L0,7 Z "
|
||||
fill="#4DB0CE"
|
||||
transform="translate(213,350)"
|
||||
id="path252" />
|
||||
<path
|
||||
d="M0,0 L2,0 L7,17 L12,30 L21,45 L31,57 L39,64 L46,71 L47,73 L49,89 L54,107 L60,122 L72,147 L83,167 L99,191 L113,212 L117,220 L117,234 L114,240 L111,243 L80,243 L63,231 L50,219 L38,207 L31,199 L30,196 L27,196 L25,200 L11,215 L2,224 L-9,230 L-13,231 L-21,231 L-27,227 L-32,221 L-36,210 L-36,203 L-28,186 L-22,174 L-17,159 L-13,141 L-12,131 L-12,99 L-16,64 L-18,49 L-18,34 L-15,24 L-8,11 Z "
|
||||
fill="#517ED0"
|
||||
transform="translate(158,269)"
|
||||
id="path256" />
|
||||
<path
|
||||
d="M0,0 L12,1 L28,8 L40,16 L50,24 L65,37 L75,48 L77,51 L79,51 L89,37 L98,27 L107,18 L117,14 L126,14 L134,19 L139,25 L142,32 L142,40 L137,54 L128,74 L123,88 L118,109 L117,117 L117,147 L121,169 L124,181 L124,200 L120,211 L111,225 L106,229 L100,214 L92,199 L80,183 L70,173 L64,168 L62,153 L57,139 L49,123 L34,97 L21,75 L6,53 L-6,36 L-12,26 L-13,23 L-13,11 L-9,5 L-4,1 Z "
|
||||
fill="#4EB0CF"
|
||||
transform="translate(246,0)"
|
||||
id="path258" />
|
||||
<path
|
||||
d="M0,0 L6,0 L6,2 L11,1 L22,1 L32,6 L41,8 L53,8 L60,16 L62,17 L61,22 L56,28 L54,33 L54,43 L58,45 L58,48 L52,47 L46,42 L46,40 L30,45 L24,53 L24,61 L25,62 L31,62 L35,58 L39,59 L41,62 L43,71 L44,72 L50,72 L53,80 L53,82 L61,80 L65,78 L70,78 L72,80 L82,79 L92,84 L103,95 L106,98 L108,99 L117,100 L123,105 L123,114 L118,128 L110,142 L99,156 L88,165 L77,173 L60,180 L55,180 L56,176 L65,170 L67,166 L67,151 L72,144 L73,141 L73,134 L69,129 L65,127 L55,126 L47,116 L45,112 L45,102 L49,97 L55,94 L55,87 L49,83 L44,78 L34,72 L18,64 L11,58 L4,42 L0,35 L1,26 L2,19 L-2,16 L-8,13 L-9,12 L-9,6 L-6,2 Z "
|
||||
fill="#4D99CF"
|
||||
transform="translate(223,166)"
|
||||
id="path260" />
|
||||
<path
|
||||
d="M0,0 L9,0 L20,8 L36,14 L44,17 L46,20 L46,27 L42,33 L42,44 L47,49 L46,52 L39,52 L25,46 L15,37 L6,27 L0,17 L-3,10 L-2,2 Z "
|
||||
fill="#4FABD1"
|
||||
transform="translate(176,284)"
|
||||
id="path262"
|
||||
style="fill:#4d99cf;fill-opacity:1" />
|
||||
<path
|
||||
d="M0,0 L14,0 L23,1 L29,5 L30,6 L30,11 L25,10 L24,9 L24,4 L-1,4 Z "
|
||||
fill="#438ED7"
|
||||
transform="translate(247,157)"
|
||||
id="path266" />
|
||||
<path
|
||||
id="path268"
|
||||
transform="translate(203,179)"
|
||||
d="m 0,0 3,1 1,8 h 8 v 4 l -2,1 H 2 L -2,9 V 2 Z"
|
||||
style="fill:#4d99cf;fill-opacity:1" />
|
||||
<path
|
||||
id="path288"
|
||||
transform="translate(278,222)"
|
||||
d="M 0,0 6,1 7,4 9,5 H 2 L -1,3 Z m 0,0 6,1 6,2 8,1 V 7 H 7 L 0,4 Z"
|
||||
style="fill:#4d99cf;fill-opacity:1" />
|
||||
<path
|
||||
d="M0,0 L3,1 L-7,8 L-9,8 L-9,6 L-5,5 L-4,2 Z "
|
||||
fill="#6184C5"
|
||||
transform="translate(371,336)"
|
||||
id="path304"
|
||||
style="fill:#517ed0;fill-opacity:1" />
|
||||
<path
|
||||
id="path314"
|
||||
style="fill:#4eb0cf;fill-opacity:1"
|
||||
transform="translate(113,201)"
|
||||
d="M 0,0 H 2 L 0,4 -2.8602037,5.4301018 -4,6 V 8 L -6,7 Z m 48,-40 h 25 l 14,3 4,2 -1,3 -10,8 -10,11 -9,14 -7,14 -5,17 -2,11 -1,15 -8,10 -12,21 -11,19 -6,10 -11,19 -12,22 -11,21 -9,20 -5,1 -10,-5 -8,-4 -4,-6 -1,-3 v -18 l 6,-26 5,-13 5,-12 6,-13 2,-5 v -6 l -5,-3 -29,-4 -18,-6 -10,-6 -5,-5 -2,-4 V 50 l 7,-8 10,-7 18,-6 10,-2 10,-1 18.016033,-0.600534 L -22,25 l 5,-5 8,-9 7,-9 8,-10 9,-10 9,-9 10,-7 8,-4 z" />
|
||||
<metadata
|
||||
id="metadata148">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
After (image error) Size: 6.4 KiB |
334
launch/.terraform/modules/peertube.deploy/docs/quickstart.md
Normal file
334
launch/.terraform/modules/peertube.deploy/docs/quickstart.md
Normal file
|
@ -0,0 +1,334 @@
|
|||
# Quickstart Guide: nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" width="150" height="150">
|
||||
|
||||
[Documentation Index](./INDEX.md)
|
||||
|
||||
## Introduction
|
||||
|
||||
This guide documents a simple installation of NixOS using **nixos-anywhere** on
|
||||
a target machine running x86_64 Linux with
|
||||
[kexec](https://man7.org/linux/man-pages/man8/kexec.8.html) support. The example
|
||||
used in this guide installs NixOS on a Hetzner cloud machine. The configuration
|
||||
may be different for some other instances. We will be including further examples
|
||||
in the [How To Guide](./howtos/INDEX.md) as and when they are available.
|
||||
|
||||
You will need:
|
||||
|
||||
- A [flake](https://wiki.nixos.org/wiki/Flakes) that controls the actions to be
|
||||
performed
|
||||
- A disk configuration containing details of the file system that will be
|
||||
created on the new server.
|
||||
- A target machine that is reachable via SSH, either using keys or a password,
|
||||
and the privilege to either log in directly as root or a user with
|
||||
password-less sudo.
|
||||
|
||||
**nixos-anywhere** doesn’t need to be installed. You can run it directly from
|
||||
[the Github repository.](https://github.com/nix-community/nixos-anywhere)
|
||||
|
||||
Details of the flake, the disk configuration and the CLI command are discussed
|
||||
below.
|
||||
|
||||
## Steps required to run nixos-anywhere
|
||||
|
||||
### 1. Enable Flakes
|
||||
|
||||
Check if your nix has flakes enabled by running `nix flake`. It will tell you if
|
||||
it's not. To enable flakes, refer to the
|
||||
[NixOS Wiki](https://wiki.nixos.org/wiki/Flakes#enable-flakes).
|
||||
|
||||
### 2. Initialize a Flake
|
||||
|
||||
The easiest way to start is to copy our
|
||||
[example flake.nix](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix)
|
||||
into a new directory. This example is tailored for a virtual machine setup
|
||||
similar to one on [Hetzner Cloud](https://www.hetzner.com/cloud), so you might
|
||||
need to adapt it for your setup.
|
||||
|
||||
If you already have a flake, you can use it by adding
|
||||
[disko configuration](https://github.com/nix-community/disko?tab=readme-ov-file#how-to-use-disko)
|
||||
to it.
|
||||
|
||||
### 3. Configure your SSH key
|
||||
|
||||
If you cloned
|
||||
[our nixos-anywhere-example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/configuration.nix)
|
||||
you will also replace the SSH key like this: In your configuration, locate the
|
||||
line that reads:
|
||||
|
||||
```bash
|
||||
# change this to your ssh key
|
||||
"CHANGE"
|
||||
```
|
||||
|
||||
Replace the text `CHANGE` with your own SSH key. This is crucial, as you will
|
||||
not be able to log into the target machine post-installation without it. If you
|
||||
have a .pem file you can run
|
||||
|
||||
```bash
|
||||
ssh-keygen -y -f /path/to/your/key.pem
|
||||
```
|
||||
|
||||
then paste the result in between the quotes like "ssh-rsa AAA..."
|
||||
|
||||
### 4. Configure Storage
|
||||
|
||||
In the same directory, create a file called `disk-config.nix`. This file will
|
||||
define the disk layout for the
|
||||
[disko](https://github.com/nix-community/disko/blob/master/docs/INDEX.md) tool,
|
||||
which is used by nixos-anywhere to partition, format, and mount the disks.
|
||||
|
||||
For a basic installation, you can copy the contents from the example provided
|
||||
[here](https://github.com/nix-community/nixos-anywhere-examples/blob/main/disk-config.nix).
|
||||
This configuration sets up a standard GPT (GUID Partition Table) that is
|
||||
compatible with both EFI and BIOS systems and mounts the disk as `/dev/sda`. You
|
||||
may need to adjust `/dev/sda` to match the correct disk on your machine. To
|
||||
identify the disk, run the `lsblk` command and replace `sda` with the actual
|
||||
disk name.
|
||||
|
||||
For example, on this machine, we would select `/dev/nvme0n1` as the disk:
|
||||
|
||||
```
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
||||
nvme0n1 259:0 0 1.8T 0 disk
|
||||
```
|
||||
|
||||
If this setup does not match your requirements, you can choose an example that
|
||||
better suits your disk layout from the
|
||||
[disko examples](https://github.com/nix-community/disko/tree/master/example).
|
||||
For more detailed information, refer to the
|
||||
[disko documentation](https://github.com/nix-community/disko).
|
||||
|
||||
### 5. Lock your Flake
|
||||
|
||||
```
|
||||
nix flake lock
|
||||
```
|
||||
|
||||
This will download your flake dependencies and make a `flake.lock` file that
|
||||
describes how to reproducibly build your system.
|
||||
|
||||
Optionally, you can commit these files to a repo such as Github, or you can
|
||||
simply reference your local directory when you run **nixos-anywhere**. This
|
||||
example uses a local directory on the source machine.
|
||||
|
||||
### 6. Connectivity to the Target Machine
|
||||
|
||||
**nixos-anywhere** will create a temporary SSH key to use for the installation.
|
||||
If your SSH key is not found, you will be asked for your password. If you are
|
||||
using a non-root user, you must have access to sudo without a password. To avoid
|
||||
SSH password prompts, set the `SSHPASS` environment variable to your password
|
||||
and add `--env-password` to the `nixos-anywhere` command. If providing a
|
||||
specific SSH key through `-i` (identity_file), this key will then be used for
|
||||
the installation and no temporary SSH key will be created.
|
||||
|
||||
### 7. (Optional) Test your NixOS and Disko configuration
|
||||
|
||||
Skip this step and continue with Step 8, if you don't have a hardware
|
||||
configuration (hardware-configuration.nix or facter.json) generated yet or make
|
||||
sure you don't import non-existing hardware-configuration.nix or facter.json
|
||||
during running the vm test.
|
||||
|
||||
The following command will automatically test your nixos configuration and run
|
||||
disko inside a virtual machine, where
|
||||
|
||||
- `<path to configuration>` is the path to the directory or repository
|
||||
containing `flake.nix` and `disk-config.nix`
|
||||
|
||||
- `<configuration name>` must match the name that immediately follows the text
|
||||
`nixosConfigurations.` in the flake, as indicated by the comment in the
|
||||
[example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix).
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --flake <path to configuration>#<configuration name> --vm-test
|
||||
```
|
||||
|
||||
### 8. Prepare Hardware Configuration
|
||||
|
||||
If you're not using a virtual machine, it's recommended to allow
|
||||
`nixos-anywhere` to generate a hardware configuration during installation. This
|
||||
ensures that essential drivers, such as those required for disk detection, are
|
||||
properly configured.
|
||||
|
||||
To enable `nixos-anywhere` to integrate its generated configuration into your
|
||||
NixOS setup, you need to include an import for the hardware configuration
|
||||
beforehand.
|
||||
|
||||
Here’s an example:
|
||||
|
||||
```diff
|
||||
nixosConfigurations.generic = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
disko.nixosModules.disko
|
||||
./configuration.nix
|
||||
+ ./hardware-configuration.nix
|
||||
];
|
||||
};
|
||||
```
|
||||
|
||||
When running `nixos-anywhere`, this file is automatically generated by including
|
||||
the following flags in your command:
|
||||
`--generate-hardware-config nixos-generate-config ./hardware-configuration.nix`.
|
||||
The second flag, `./hardware-configuration.nix`, specifies where
|
||||
`nixos-generate-config` will store the configuration. Adjust this path to
|
||||
reflect the location where you want the `hardware-configuration.nix` for this
|
||||
machine to be saved.
|
||||
|
||||
#### 8.1 nixos-facter
|
||||
|
||||
As an alternative to `nixos-generate-config`, you can use the experimental
|
||||
[nixos-facter](https://github.com/numtide/nixos-facter) command, which offers
|
||||
more comprehensive hardware reports and advanced configuration options.
|
||||
|
||||
To use `nixos-facter`, add the following to your flake inputs:
|
||||
|
||||
```diff
|
||||
{
|
||||
+ inputs.nixos-facter-modules.url = "github:numtide/nixos-facter-modules";
|
||||
}
|
||||
```
|
||||
|
||||
Next, import the module into your configuration and specify `facter.json` as the
|
||||
path where the hardware report will be saved:
|
||||
|
||||
```diff
|
||||
nixosConfigurations.generic-nixos-facter = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
disko.nixosModules.disko
|
||||
./configuration.nix
|
||||
+ nixos-facter-modules.nixosModules.facter
|
||||
+ { config.facter.reportPath = ./facter.json }
|
||||
];
|
||||
};
|
||||
```
|
||||
|
||||
To generate the configuration for `nixos-facter` with `nixos-anywhere`, use the
|
||||
following flags: `--generate-hardware-config nixos-facter ./facter.json`. The
|
||||
second flag, `./facter.json`, specifies where `nixos-generate-config` will store
|
||||
the hardware report. Adjust this path to suit the location where you want the
|
||||
`facter.json` to be saved.
|
||||
|
||||
### 9. Run it
|
||||
|
||||
You can now run **nixos-anywhere** from the command line as shown below, where:
|
||||
|
||||
- `<path to configuration>` is the path to the directory or repository
|
||||
containing `flake.nix` and `disk-config.nix`
|
||||
|
||||
- `<configuration name>` must match the name that immediately follows the text
|
||||
`nixosConfigurations.` in the flake, as indicated by the comment in the
|
||||
[example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix).
|
||||
|
||||
- `<ip address>` is the IP address of the target machine.
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --flake <path to configuration>#<configuration name> --target-host root@<ip address>
|
||||
```
|
||||
|
||||
The command would look like this if you had created your files in a directory
|
||||
named `/home/mydir/test` and the IP address of your target machine is
|
||||
`37.27.18.135`:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --flake /home/mydir/test#hetzner-cloud --target-host root@37.27.18.135
|
||||
```
|
||||
|
||||
If you also need to generate hardware configuration amend flags for
|
||||
nixos-generate-config:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-generate-config ./hardware-configuration.nix --flake <path to configuration>#<configuration name> --target-host root@<ip address>
|
||||
```
|
||||
|
||||
Or these flags if you are using nixos-facter instead:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-facter ./facter.json --flake <path to configuration>#<configuration name> --target-host root@<ip address>
|
||||
```
|
||||
|
||||
Adjust the location of `./hardware-configuration.nix` and `./facter.json`
|
||||
accordingly.
|
||||
|
||||
**nixos-anywhere** will then run, showing various output messages at each stage.
|
||||
It may take some time to complete, depending on Internet speeds. It should
|
||||
finish by showing the messages below before returning to the command prompt.
|
||||
|
||||
```
|
||||
Installation finished. No error reported.
|
||||
Warning: Permanently added '<ip-address>' (ED25519) to the list of known hosts
|
||||
```
|
||||
|
||||
When this happens, the target server will have been overwritten with a new
|
||||
installation of NixOS. Note that the server's public SSH key will have changed.
|
||||
|
||||
If you have previously accessed this server using SSH, you may see the following
|
||||
message the next time you try to log in to the target.
|
||||
|
||||
```
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
|
||||
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
|
||||
It is also possible that a host key has just been changed.
|
||||
The fingerprint for the ED25519 key sent by the remote host is
|
||||
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
|
||||
Please contact your system administrator.
|
||||
Add correct host key in ~/.ssh/known_hosts to get rid of this message.
|
||||
Offending ECDSA key in ~/.ssh/known_hosts:6
|
||||
remove with:
|
||||
ssh-keygen -f ~/.ssh/known_hosts" -R "<ip address>"
|
||||
Host key for <ip_address> has changed and you have requested strict checking.
|
||||
Host key verification failed.
|
||||
```
|
||||
|
||||
This is because the `known_hosts` file in the `.ssh` directory now contains a
|
||||
mismatch, since the server has been overwritten. To solve this, use a text
|
||||
editor to remove the old entry from the `known_hosts` file (or use the command
|
||||
`ssh-keygen -R <ip_address>`). The next connection attempt will then treat this
|
||||
as a new server.
|
||||
|
||||
The error message line `Offending ECDSA key in ~/.ssh/known_hosts:6` gives the
|
||||
line number that needs to be removed from the `known_hosts` file (line 6 in this
|
||||
example).
|
||||
|
||||
# Finished!
|
||||
|
||||
**nixos-anywhere**'s job is now done, as it is a tool to install NixOS onto the
|
||||
target machine.
|
||||
|
||||
Any future changes to the configuration should be made to your flake. You would
|
||||
reference this flake when using the NixOS `nixos-rebuild` command or a separate
|
||||
3rd party deployment tool of your choice i.e.
|
||||
[deploy-rs](https://github.com/serokell/deploy-rs),
|
||||
[colmena](https://github.com/zhaofengli/colmena),
|
||||
[nixinate](https://github.com/MatthewCroughan/nixinate),
|
||||
[clan](https://clan.lol/) (author's choice).
|
||||
|
||||
To update on the machine locally (replace `<URL to your flake>` with your flake
|
||||
i.e. `.#` if your flake is in the current directory):
|
||||
|
||||
```
|
||||
nixos-rebuild switch --flake <URL to your flake>
|
||||
```
|
||||
|
||||
To update remotely you will need to have configured an
|
||||
[ssh server](https://search.nixos.org/options?show=services.sshd.enable) and
|
||||
your ssh key for the
|
||||
[root user](https://search.nixos.org/options?show=users.users.%3Cname%3E.openssh.authorizedKeys.keys):
|
||||
|
||||
```
|
||||
nixos-rebuild switch --flake <URL to your flake> --target-host "root@<ip address>"
|
||||
```
|
||||
|
||||
See the Nix documentation for use of the flake
|
||||
[URL-like syntax](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake#url-like-syntax).
|
||||
|
||||
For more information on different use cases of **nixos-anywhere** please refer
|
||||
to the [How to Guide](./howtos/INDEX.md), and for more technical information and
|
||||
explanation of known error messages, refer to the
|
||||
[Reference Manual](./reference.md).
|
137
launch/.terraform/modules/peertube.deploy/docs/reference.md
Normal file
137
launch/.terraform/modules/peertube.deploy/docs/reference.md
Normal file
|
@ -0,0 +1,137 @@
|
|||
# Reference Manual: nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img title="" src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" alt="" width="141">
|
||||
|
||||
[Documentation Index](./INDEX.md)
|
||||
|
||||
TODO: Populate this guide properly
|
||||
|
||||
## Contents
|
||||
|
||||
[Command Line Usage](#command-line-usage)
|
||||
|
||||
[Explanation of known error messages](#explanation-of-known-error-messages)
|
||||
|
||||
## Command Line Usage
|
||||
|
||||
<!-- `$ bash ./src/nixos-anywhere.sh --help` -->
|
||||
|
||||
```
|
||||
Usage: nixos-anywhere [options] [<ssh-host>]
|
||||
|
||||
Options:
|
||||
|
||||
* -f, --flake <flake_uri>
|
||||
set the flake to install the system from. i.e.
|
||||
nixos-anywhere --flake .#mymachine
|
||||
Also supports variants:
|
||||
nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant
|
||||
* --target-host <ssh-host>
|
||||
set the SSH target host to deploy onto.
|
||||
* -i <identity_file>
|
||||
selects which SSH private key file to use.
|
||||
* -p, --ssh-port <ssh_port>
|
||||
set the ssh port to connect with
|
||||
* --ssh-option <ssh_option>
|
||||
set an ssh option
|
||||
* -L, --print-build-logs
|
||||
print full build logs
|
||||
* --env-password
|
||||
set a password used by ssh-copy-id, the password should be set by
|
||||
the environment variable SSHPASS
|
||||
* -s, --store-paths <disko-script> <nixos-system>
|
||||
set the store paths to the disko-script and nixos-system directly
|
||||
if this is given, flake is not needed
|
||||
* --kexec <path>
|
||||
use another kexec tarball to bootstrap NixOS
|
||||
* --kexec-extra-flags
|
||||
extra flags to add into the call to kexec, e.g. "--no-sync"
|
||||
* --ssh-store-setting <key> <value>
|
||||
ssh store settings appended to the store URI, e.g. "compress true". <value> needs to be URI encoded.
|
||||
* --post-kexec-ssh-port <ssh_port>
|
||||
after kexec is executed, use a custom ssh port to connect. Defaults to 22
|
||||
* --copy-host-keys
|
||||
copy over existing /etc/ssh/ssh_host_* host keys to the installation
|
||||
* --extra-files <path>
|
||||
contents of local <path> are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten
|
||||
Copied files will be owned by root unless specified by --chown option. See documentation for details.
|
||||
* --chown <path> <ownership>
|
||||
change ownership of <path> recursively. Recommended to use uid:gid as opposed to username:groupname for ownership.
|
||||
Option can be specified more than once.
|
||||
* --disk-encryption-keys <remote_path> <local_path>
|
||||
copy the contents of the file or pipe in local_path to remote_path in the installer environment,
|
||||
after kexec but before installation. Can be repeated.
|
||||
* --no-substitute-on-destination
|
||||
disable passing --substitute-on-destination to nix-copy
|
||||
* --debug
|
||||
enable debug output
|
||||
* --show-trace
|
||||
show nix build traces
|
||||
* --option <key> <value>
|
||||
nix option to pass to every nix related command
|
||||
* --from <store-uri>
|
||||
URL of the source Nix store to copy the nixos and disko closure from
|
||||
* --build-on-remote
|
||||
build the closure on the remote machine instead of locally and copy-closuring it
|
||||
* --vm-test
|
||||
build the system and test the disk configuration inside a VM without installing it to the target.
|
||||
* --generate-hardware-config nixos-facter|nixos-generate-config <path>
|
||||
generate a hardware-configuration.nix file using the specified backend and write it to the specified path.
|
||||
The backend can be either 'nixos-facter' or 'nixos-generate-config'.
|
||||
* --phases
|
||||
comma separated list of phases to run. Default is: kexec,disko,install,reboot
|
||||
kexec: kexec into the nixos installer
|
||||
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
|
||||
install: install the system
|
||||
reboot: unmount the filesystems, export any ZFS pools and reboot the machine
|
||||
* --disko-mode disko|mount|format
|
||||
set the disko mode to format, mount or destroy. Default is disko.
|
||||
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
|
||||
* --no-disko-deps
|
||||
This will only upload the disko script and not the partitioning tools dependencies.
|
||||
Installers usually have dependencies available.
|
||||
Use this option if your target machine has not enough RAM to store the dependencies in memory.
|
||||
* --build-on auto|remote|local
|
||||
sets the build on settings to auto, remote or local. Default is auto.
|
||||
auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build
|
||||
local: will build on the local host
|
||||
remote: will build on the remote host
|
||||
```
|
||||
|
||||
## Explanation of known error messages
|
||||
|
||||
TODO: Add additional error messages and meanings. Fill in missing explanations
|
||||
|
||||
This section lists known error messages and their explanations. Some
|
||||
explanations may refer to the following CLI syntax:
|
||||
|
||||
`nix run github:nix-community/nixos-anywhere -- --flake <path to configuration>#<configuration name> root@<ip address>`
|
||||
|
||||
This list is not comprehensive. It's possible you may encounter errors that
|
||||
originate from the underlying operating system. These should be documented in
|
||||
the relevant operating system manual.
|
||||
|
||||
| Id | Message | Explanation |
|
||||
| -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| 1 | Failure unpacking initrd | You don't have enough RAM to hold `kexec` |
|
||||
| 2 | Flake <flake_url> does not provide attribute | The configuration name you specified in your flake URI is not defined as a NixOS configuration in your flake eg if your URI was mydir#myconfig, then myconfig should be included in the flake as `nixosConfigurations.myconfig` |
|
||||
| 3 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | As for error #2 |
|
||||
| | For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri | |
|
||||
| 4 | Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already | TODO: Explain |
|
||||
| 5 | ssh-host must be set | <ip_address> has not been supplied |
|
||||
| 6 | <disko_script> and <nixos_system> must be existing store-paths | This occurs if the -s switch has been used to specify the disko script and store path correctly, and the scripts cannot be found at the given URI |
|
||||
| 7 | flake must be set | This occurs if both the -flake option (use a flake) and the -s option (specify paths directly) have been omitted. Either one or the other must be specified. |
|
||||
| 8 | no tar command found, but required to unpack kexec tarball | The destination machine does not have a `tar` command available. This is needed to unpack the `kexec`. |
|
||||
| 9 | no setsid command found, but required to run the kexec script under a new session | The destination machine does not have the `setsid` command available |
|
||||
| 10 | This script requires Linux as the operating system, but got <operating system> | The destination machine is not running Linux |
|
||||
| 11 | The default kexec image only support x86_64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information. | By default, `nixos-anywhere` uses its own `kexec` image, which will only run on x86_64 CPUs. For other CPU types, you can use your own `kexec` image instead. Refer to the [How To Guide](./howtos#using-your-own-kexec-image) for instructions. |
|
||||
| 12 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | This is a `disko` error. As for Error #2 |
|
||||
| | For example, to use the output diskoConfigurations.foo from the flake.nix, append \"#foo\" to the flake-uri. | |
|
||||
| 13 | mode must be either create, mount or zap_create_mount | This is a `disko` error. The `disko` switches have not been used correctly. This could happen if you supplied your own `disko` script using the -s option |
|
||||
| 14 | disko config must be an existing file or flake must be set | This is a `disko` error. This will happen if the `disko.devices` entry in your flake doesn't match the name of a file in the same location as your flake. |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
|
@ -0,0 +1,39 @@
|
|||
# System Requirements: nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" width="150" height="150">
|
||||
|
||||
[Documentation Index](./INDEX.md)
|
||||
|
||||
## Requirements
|
||||
|
||||
### Source Machine
|
||||
|
||||
1. **Supported Systems:**
|
||||
- Linux or macOS computers with Nix installed.
|
||||
- NixOS
|
||||
- Windows systems using WSL2.
|
||||
|
||||
2. **Nix Installation:** If Nix is not yet installed on your system, refer to
|
||||
the [nix installation page](https://nixos.org/download#download-nix).
|
||||
|
||||
### Destination Machine
|
||||
|
||||
The machine must be reachable over the public internet or local network.
|
||||
Nixos-anywhere does not support wifi networks. If a VPN is needed, define a
|
||||
custom installer via the --kexec flag which connects to your VPN.
|
||||
|
||||
1. **Direct Boot Option:**
|
||||
- Must be already running a NixOS installer.
|
||||
|
||||
2. **Alternative Boot Options:** If not booting directly from a NixOS installer
|
||||
image:
|
||||
- **Architecture & Support:** Must be operating on:
|
||||
- x86-64 or aarch64 Linux systems with kexec support. Note: While most
|
||||
x86-64 Linux systems support kexec, if you're using an architecture other
|
||||
than those mentioned, you may need to specify a
|
||||
[different kexec image](./howtos/INDEX.md#using-your-own-kexec-image)
|
||||
manually.
|
||||
- **Memory Requirements:**
|
||||
- At least 1 GB of RAM (excluding swap space).
|
132
launch/.terraform/modules/peertube.deploy/flake.lock
generated
Normal file
132
launch/.terraform/modules/peertube.deploy/flake.lock
generated
Normal file
|
@ -0,0 +1,132 @@
|
|||
{
|
||||
"nodes": {
|
||||
"disko": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1741786315,
|
||||
"narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"ref": "master",
|
||||
"repo": "disko",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1741352980,
|
||||
"narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-images": {
|
||||
"inputs": {
|
||||
"nixos-stable": [
|
||||
"nixos-stable"
|
||||
],
|
||||
"nixos-unstable": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1741866599,
|
||||
"narHash": "sha256-Re/T1Cjmiis0tdphj/Wjqt+c2RlMw/il7LBWzvwQPz0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-images",
|
||||
"rev": "63285ff93fc1daa2caac9f86e2302ae4edc5e84f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-images",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1741862977,
|
||||
"narHash": "sha256-prZ0M8vE/ghRGGZcflvxCu40ObKaB+ikn74/xQoNrGQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "cdd2ef009676ac92b715ff26630164bb88fec4e0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1742051767,
|
||||
"narHash": "sha256-JpyjnalnIqJ7cvP8HzaoJN9/i2bDx83dToodHHjGuNg=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ec886d10b507760c90ed01e2eac7f0679d0a47ae",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"disko": "disko",
|
||||
"flake-parts": "flake-parts",
|
||||
"nixos-images": "nixos-images",
|
||||
"nixos-stable": "nixos-stable",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1739829690,
|
||||
"narHash": "sha256-mL1szCeIsjh6Khn3nH2cYtwO5YXG6gBiTw1A30iGeDU=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "3d0579f5cc93436052d94b73925b48973a104204",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
55
launch/.terraform/modules/peertube.deploy/flake.nix
Normal file
55
launch/.terraform/modules/peertube.deploy/flake.nix
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
description = "A universal nixos installer, just needs ssh access to the target system";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small";
|
||||
flake-parts = {
|
||||
url = "github:hercules-ci/flake-parts";
|
||||
inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# used for testing
|
||||
disko = {
|
||||
url = "github:nix-community/disko/master";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
nixos-stable.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||
nixos-images.url = "github:nix-community/nixos-images";
|
||||
nixos-images.inputs.nixos-unstable.follows = "nixpkgs";
|
||||
nixos-images.inputs.nixos-stable.follows = "nixos-stable";
|
||||
|
||||
# used for development
|
||||
treefmt-nix = {
|
||||
url = "github:numtide/treefmt-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
inputs:
|
||||
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"x86_64-darwin"
|
||||
"aarch64-linux"
|
||||
"aarch64-darwin"
|
||||
];
|
||||
imports = [
|
||||
./src/flake-module.nix
|
||||
./tests/flake-module.nix
|
||||
./docs/flake-module.nix
|
||||
# allow to disable treefmt in downstream flakes
|
||||
] ++ inputs.nixpkgs.lib.optional (inputs.treefmt-nix ? flakeModule) ./treefmt/flake-module.nix;
|
||||
|
||||
perSystem =
|
||||
{ self', lib, ... }:
|
||||
{
|
||||
checks =
|
||||
let
|
||||
packages = lib.mapAttrs' (n: lib.nameValuePair "package-${n}") self'.packages;
|
||||
devShells = lib.mapAttrs' (n: lib.nameValuePair "devShell-${n}") self'.devShells;
|
||||
in
|
||||
packages // devShells;
|
||||
};
|
||||
};
|
||||
}
|
38
launch/.terraform/modules/peertube.deploy/scripts/create-release.sh
Executable file
38
launch/.terraform/modules/peertube.deploy/scripts/create-release.sh
Executable file
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env nix
|
||||
#! nix shell nixpkgs#bash nixpkgs#gnused --command bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$SCRIPT_DIR/.."
|
||||
|
||||
version=${1:-}
|
||||
if [[ -z $version ]]; then
|
||||
echo "USAGE: $0 version" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$(git symbolic-ref --short HEAD)" != "main" ]]; then
|
||||
echo "must be on main branch" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ensure we are up-to-date
|
||||
uncommitted_changes=$(git diff --compact-summary)
|
||||
if [[ -n $uncommitted_changes ]]; then
|
||||
echo -e "There are uncommitted changes, exiting:\n${uncommitted_changes}" >&2
|
||||
exit 1
|
||||
fi
|
||||
git pull git@github.com:nix-community/nixos-anywhere main
|
||||
unpushed_commits=$(git log --format=oneline origin/main..main)
|
||||
if [[ $unpushed_commits != "" ]]; then
|
||||
echo -e "\nThere are unpushed changes, exiting:\n$unpushed_commits" >&2
|
||||
exit 1
|
||||
fi
|
||||
sed -i -e "s!version = \".*\";!version = \"${version}\";!" src/default.nix
|
||||
git add src/default.nix
|
||||
nix-shell -p nix-fast-build --command "nix-fast-build --eval-workers 2"
|
||||
git commit -m "bump version ${version}"
|
||||
git tag "${version}"
|
||||
|
||||
echo "now run 'git push --tags origin main'"
|
63
launch/.terraform/modules/peertube.deploy/src/default.nix
Normal file
63
launch/.terraform/modules/peertube.deploy/src/default.nix
Normal file
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
stdenv,
|
||||
openssh,
|
||||
gitMinimal,
|
||||
nixVersions,
|
||||
nix,
|
||||
coreutils,
|
||||
curl,
|
||||
gnugrep,
|
||||
gnutar,
|
||||
gawk,
|
||||
findutils,
|
||||
gnused,
|
||||
sshpass,
|
||||
terraform-docs,
|
||||
lib,
|
||||
makeWrapper,
|
||||
mkShellNoCC,
|
||||
}:
|
||||
let
|
||||
runtimeDeps = [
|
||||
gitMinimal # for git flakes
|
||||
# pinned because nix-copy-closure hangs if ControlPath provided for SSH: https://github.com/NixOS/nix/issues/8480
|
||||
(if lib.versionAtLeast nix.version "2.16" then nix else nixVersions.nix_2_16)
|
||||
coreutils
|
||||
curl # when uploading tarballs
|
||||
gnugrep
|
||||
gawk
|
||||
findutils
|
||||
gnused # needed by ssh-copy-id
|
||||
sshpass # used to provide password for ssh-copy-id
|
||||
gnutar # used to upload extra-files
|
||||
];
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
pname = "nixos-anywhere";
|
||||
version = "1.8.0";
|
||||
src = ./..;
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
installPhase = ''
|
||||
install -D --target-directory=$out/libexec/nixos-anywhere/ -m 0755 src/*.sh
|
||||
|
||||
# We prefer the system's openssh over our own, since it might come with features not present in ours:
|
||||
# https://github.com/nix-community/nixos-anywhere/issues/62
|
||||
makeShellWrapper $out/libexec/nixos-anywhere/nixos-anywhere.sh $out/bin/nixos-anywhere \
|
||||
--prefix PATH : ${lib.makeBinPath runtimeDeps} --suffix PATH : ${lib.makeBinPath [ openssh ]}
|
||||
'';
|
||||
|
||||
# Dependencies for our devshell
|
||||
passthru.devShell = mkShellNoCC {
|
||||
packages = runtimeDeps ++ [
|
||||
openssh
|
||||
terraform-docs
|
||||
];
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "Install nixos everywhere via ssh";
|
||||
homepage = "https://github.com/nix-community/nixos-anywhere";
|
||||
license = licenses.mit;
|
||||
platforms = platforms.all;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
perSystem =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
packages = {
|
||||
nixos-anywhere = pkgs.callPackage ./. { };
|
||||
default = config.packages.nixos-anywhere;
|
||||
};
|
||||
devShells.default = config.packages.nixos-anywhere.devShell;
|
||||
};
|
||||
}
|
23
launch/.terraform/modules/peertube.deploy/src/get-facts.sh
Executable file
23
launch/.terraform/modules/peertube.deploy/src/get-facts.sh
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
set -efu "${enableDebug:-}"
|
||||
has() {
|
||||
command -v "$1" >/dev/null && echo "y" || echo "n"
|
||||
}
|
||||
isNixos=$(if test -f /etc/os-release && grep -Eq 'ID(_LIKE)?="?nixos"?' /etc/os-release; then echo "y"; else echo "n"; fi)
|
||||
cat <<FACTS
|
||||
isOs=$(uname)
|
||||
isArch=$(uname -m)
|
||||
isKexec=$(if test -f /etc/is_kexec; then echo "y"; else echo "n"; fi)
|
||||
isNixos=$isNixos
|
||||
isInstaller=$(if [ "$isNixos" = "y" ] && grep -Eq 'VARIANT_ID="?installer"?' /etc/os-release; then echo "y"; else echo "n"; fi)
|
||||
isContainer=$(if [ "$(has systemd-detect-virt)" = "y" ]; then systemd-detect-virt --container; else echo "none"; fi)
|
||||
hasIpv6Only=$(if [ "$(has ip)" = "n" ] || ip r g 1 >/dev/null 2>/dev/null || ! ip -6 r g :: >/dev/null 2>/dev/null; then echo "n"; else echo "y"; fi)
|
||||
hasTar=$(has tar)
|
||||
hasCpio=$(has cpio)
|
||||
hasSudo=$(has sudo)
|
||||
hasDoas=$(has doas)
|
||||
hasWget=$(has wget)
|
||||
hasCurl=$(has curl)
|
||||
hasSetsid=$(has setsid)
|
||||
hasNixOSFacter=$(command -v nixos-facter >/dev/null && echo "y" || echo "n")
|
||||
FACTS
|
880
launch/.terraform/modules/peertube.deploy/src/nixos-anywhere.sh
Executable file
880
launch/.terraform/modules/peertube.deploy/src/nixos-anywhere.sh
Executable file
|
@ -0,0 +1,880 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
here=$(dirname "${BASH_SOURCE[0]}")
|
||||
flake=""
|
||||
flakeAttr=""
|
||||
kexecUrl=""
|
||||
kexecExtraFlags=""
|
||||
sshStoreSettings=""
|
||||
enableDebug=""
|
||||
nixBuildFlags=()
|
||||
diskoAttr=""
|
||||
diskoScript=""
|
||||
diskoMode="disko"
|
||||
diskoDeps=y
|
||||
nixosSystem=""
|
||||
extraFiles=""
|
||||
vmTest="n"
|
||||
nixOptions=(
|
||||
--extra-experimental-features 'nix-command flakes'
|
||||
"--no-write-lock-file"
|
||||
)
|
||||
SSH_PRIVATE_KEY=${SSH_PRIVATE_KEY-}
|
||||
|
||||
declare -A phases
|
||||
phases[kexec]=1
|
||||
phases[disko]=1
|
||||
phases[install]=1
|
||||
phases[reboot]=1
|
||||
|
||||
hardwareConfigBackend=none
|
||||
hardwareConfigPath=
|
||||
sshPrivateKeyFile=
|
||||
if [ -t 0 ]; then # stdin is a tty, we allow interactive input to ssh i.e. passwords
|
||||
sshTtyParam="-t"
|
||||
else
|
||||
sshTtyParam="-T"
|
||||
fi
|
||||
sshConnection=
|
||||
postKexecSshPort=22
|
||||
buildOnRemote=n
|
||||
buildOn=auto
|
||||
envPassword=n
|
||||
|
||||
# Facts set by get-facts.sh
|
||||
isOs=
|
||||
isArch=
|
||||
isKexec=
|
||||
isInstaller=
|
||||
isContainer=
|
||||
hasIpv6Only=
|
||||
hasTar=
|
||||
hasCpio=
|
||||
hasSudo=
|
||||
hasDoas=
|
||||
hasWget=
|
||||
hasCurl=
|
||||
hasSetsid=
|
||||
hasNixOSFacter=
|
||||
|
||||
sshKeyDir=$(mktemp -d)
|
||||
trap 'rm -rf "$sshKeyDir"' EXIT
|
||||
mkdir -p "$sshKeyDir"
|
||||
|
||||
declare -A diskEncryptionKeys=()
|
||||
declare -A extraFilesOwnership=()
|
||||
declare -a nixCopyOptions=()
|
||||
declare -a sshArgs=()
|
||||
|
||||
showUsage() {
|
||||
cat <<USAGE
|
||||
Usage: nixos-anywhere [options] [<ssh-host>]
|
||||
|
||||
Options:
|
||||
|
||||
* -f, --flake <flake_uri>
|
||||
set the flake to install the system from. i.e.
|
||||
nixos-anywhere --flake .#mymachine
|
||||
Also supports variants:
|
||||
nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant
|
||||
* --target-host <ssh-host>
|
||||
set the SSH target host to deploy onto.
|
||||
* -i <identity_file>
|
||||
selects which SSH private key file to use.
|
||||
* -p, --ssh-port <ssh_port>
|
||||
set the ssh port to connect with
|
||||
* --ssh-option <ssh_option>
|
||||
set an ssh option
|
||||
* -L, --print-build-logs
|
||||
print full build logs
|
||||
* --env-password
|
||||
set a password used by ssh-copy-id, the password should be set by
|
||||
the environment variable SSHPASS
|
||||
* -s, --store-paths <disko-script> <nixos-system>
|
||||
set the store paths to the disko-script and nixos-system directly
|
||||
if this is given, flake is not needed
|
||||
* --kexec <path>
|
||||
use another kexec tarball to bootstrap NixOS
|
||||
* --kexec-extra-flags
|
||||
extra flags to add into the call to kexec, e.g. "--no-sync"
|
||||
* --ssh-store-setting <key> <value>
|
||||
ssh store settings appended to the store URI, e.g. "compress true". <value> needs to be URI encoded.
|
||||
* --post-kexec-ssh-port <ssh_port>
|
||||
after kexec is executed, use a custom ssh port to connect. Defaults to 22
|
||||
* --copy-host-keys
|
||||
copy over existing /etc/ssh/ssh_host_* host keys to the installation
|
||||
* --extra-files <path>
|
||||
contents of local <path> are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten
|
||||
Copied files will be owned by root unless specified by --chown option. See documentation for details.
|
||||
* --chown <path> <ownership>
|
||||
change ownership of <path> recursively. Recommended to use uid:gid as opposed to username:groupname for ownership.
|
||||
Option can be specified more than once.
|
||||
* --disk-encryption-keys <remote_path> <local_path>
|
||||
copy the contents of the file or pipe in local_path to remote_path in the installer environment,
|
||||
after kexec but before installation. Can be repeated.
|
||||
* --no-substitute-on-destination
|
||||
disable passing --substitute-on-destination to nix-copy
|
||||
* --debug
|
||||
enable debug output
|
||||
* --show-trace
|
||||
show nix build traces
|
||||
* --option <key> <value>
|
||||
nix option to pass to every nix related command
|
||||
* --from <store-uri>
|
||||
URL of the source Nix store to copy the nixos and disko closure from
|
||||
* --build-on-remote
|
||||
build the closure on the remote machine instead of locally and copy-closuring it
|
||||
* --vm-test
|
||||
build the system and test the disk configuration inside a VM without installing it to the target.
|
||||
* --generate-hardware-config nixos-facter|nixos-generate-config <path>
|
||||
generate a hardware-configuration.nix file using the specified backend and write it to the specified path.
|
||||
The backend can be either 'nixos-facter' or 'nixos-generate-config'.
|
||||
* --phases
|
||||
comma separated list of phases to run. Default is: kexec,disko,install,reboot
|
||||
kexec: kexec into the nixos installer
|
||||
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
|
||||
install: install the system
|
||||
reboot: unmount the filesystems, export any ZFS pools and reboot the machine
|
||||
* --disko-mode disko|mount|format
|
||||
set the disko mode to format, mount or destroy. Default is disko.
|
||||
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
|
||||
* --no-disko-deps
|
||||
This will only upload the disko script and not the partitioning tools dependencies.
|
||||
Installers usually have dependencies available.
|
||||
Use this option if your target machine has not enough RAM to store the dependencies in memory.
|
||||
* --build-on auto|remote|local
|
||||
sets the build on settings to auto, remote or local. Default is auto.
|
||||
auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build
|
||||
local: will build on the local host
|
||||
remote: will build on the remote host
|
||||
USAGE
|
||||
}
|
||||
|
||||
abort() {
|
||||
echo "aborted: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
step() {
|
||||
echo "### $* ###"
|
||||
}
|
||||
|
||||
parseArgs() {
|
||||
local substituteOnDestination=y
|
||||
local printBuildLogs=n
|
||||
local buildOnRemote=n
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-f | --flake)
|
||||
flake=$2
|
||||
shift
|
||||
;;
|
||||
--target-host)
|
||||
sshConnection=$2
|
||||
shift
|
||||
;;
|
||||
-i)
|
||||
sshPrivateKeyFile=$2
|
||||
shift
|
||||
;;
|
||||
-p | --ssh-port)
|
||||
sshArgs+=("-p" "$2")
|
||||
shift
|
||||
;;
|
||||
--ssh-option)
|
||||
sshArgs+=("-o" "$2")
|
||||
shift
|
||||
;;
|
||||
-L | --print-build-logs)
|
||||
printBuildLogs=y
|
||||
;;
|
||||
-s | --store-paths)
|
||||
diskoScript=$(readlink -f "$2")
|
||||
nixosSystem=$(readlink -f "$3")
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--generate-hardware-config)
|
||||
if [[ $# -lt 3 ]]; then
|
||||
abort "Missing arguments for --generate-hardware-config <backend> <path>"
|
||||
fi
|
||||
case "$2" in
|
||||
nixos-facter | nixos-generate-config)
|
||||
hardwareConfigBackend=$2
|
||||
;;
|
||||
*)
|
||||
abort "Unknown hardware config backend: $2"
|
||||
;;
|
||||
esac
|
||||
hardwareConfigPath=$3
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-t | --tty)
|
||||
echo "the '$1' flag is deprecated, a tty is now detected automatically" >&2
|
||||
;;
|
||||
--help)
|
||||
showUsage
|
||||
exit 0
|
||||
;;
|
||||
--kexec)
|
||||
kexecUrl=$2
|
||||
shift
|
||||
;;
|
||||
--kexec-extra-flags)
|
||||
kexecExtraFlags=$2
|
||||
shift
|
||||
;;
|
||||
--ssh-store-setting)
|
||||
key=$2
|
||||
shift
|
||||
value=$2
|
||||
shift
|
||||
sshStoreSettings+="$sshStoreSettings$key=$value&"
|
||||
shift
|
||||
;;
|
||||
--post-kexec-ssh-port)
|
||||
postKexecSshPort=$2
|
||||
shift
|
||||
;;
|
||||
--copy-host-keys)
|
||||
copyHostKeys=y
|
||||
;;
|
||||
--show-trace)
|
||||
nixBuildFlags+=("--show-trace")
|
||||
;;
|
||||
--debug)
|
||||
enableDebug="-x"
|
||||
printBuildLogs=y
|
||||
set -x
|
||||
;;
|
||||
--disko-mode)
|
||||
case "$2" in
|
||||
format | mount | disko)
|
||||
diskoMode=$2
|
||||
;;
|
||||
*)
|
||||
abort "Supported values for --disko-mode are disko, mount and format. Unknown mode : $2"
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
;;
|
||||
--no-disko-deps)
|
||||
diskoDeps=n
|
||||
;;
|
||||
--build-on)
|
||||
case "$2" in
|
||||
auto | local | remote)
|
||||
buildOn=$2
|
||||
;;
|
||||
*)
|
||||
abort "Supported values for --build-on are auto, local and remote. Unknown mode : $2"
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
;;
|
||||
--extra-files)
|
||||
extraFiles=$2
|
||||
shift
|
||||
;;
|
||||
--chown)
|
||||
extraFilesOwnership["$2"]="$3"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--disk-encryption-keys)
|
||||
diskEncryptionKeys["$2"]="$3"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--phases)
|
||||
phases[kexec]=0
|
||||
phases[disko]=0
|
||||
phases[install]=0
|
||||
phases[reboot]=0
|
||||
IFS=, read -r -a phaseList <<<"$2"
|
||||
for phase in "${phaseList[@]}"; do
|
||||
if [[ ${phases[$phase]:-unset} == unset ]]; then
|
||||
abort "Unknown phase: $phase"
|
||||
fi
|
||||
phases[$phase]=1
|
||||
done
|
||||
shift
|
||||
;;
|
||||
--stop-after-disko)
|
||||
echo "WARNING: --stop-after-disko is deprecated, use --phases kexec,disko instead" 2>&1
|
||||
phases[kexec]=1
|
||||
phases[disko]=1
|
||||
phases[install]=0
|
||||
phases[reboot]=0
|
||||
;;
|
||||
--no-reboot)
|
||||
echo "WARNING: --no-reboot is deprecated, use --phases kexec,disko,install instead" 2>&1
|
||||
phases[kexec]=1
|
||||
phases[disko]=1
|
||||
phases[install]=1
|
||||
phases[reboot]=0
|
||||
;;
|
||||
--from)
|
||||
nixCopyOptions+=("--from" "$2")
|
||||
shift
|
||||
;;
|
||||
--option)
|
||||
key=$2
|
||||
shift
|
||||
value=$2
|
||||
shift
|
||||
nixOptions+=("--option" "$key" "$value")
|
||||
;;
|
||||
--no-substitute-on-destination)
|
||||
substituteOnDestination=n
|
||||
;;
|
||||
--build-on-remote)
|
||||
echo "WARNING: --build-on-remote is deprecated, use --build-on remote instead" 2>&1
|
||||
buildOnRemote=y
|
||||
buildOn="remote"
|
||||
;;
|
||||
--env-password)
|
||||
envPassword=y
|
||||
;;
|
||||
--vm-test)
|
||||
vmTest=y
|
||||
;;
|
||||
*)
|
||||
if [[ -z ${sshConnection} ]]; then
|
||||
sshConnection="$1"
|
||||
else
|
||||
showUsage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
diskoAttr="${diskoMode}Script"
|
||||
|
||||
if [[ ${diskoDeps} == "n" ]]; then
|
||||
diskoAttr="${diskoAttr}NoDeps"
|
||||
fi
|
||||
|
||||
if [[ ${printBuildLogs} == "y" ]]; then
|
||||
nixOptions+=("-L")
|
||||
fi
|
||||
|
||||
if [[ $substituteOnDestination == "y" ]]; then
|
||||
nixCopyOptions+=("--substitute-on-destination")
|
||||
fi
|
||||
|
||||
if [[ $vmTest == "n" ]] && [[ -z ${sshConnection} ]]; then
|
||||
abort "ssh-host must be set"
|
||||
fi
|
||||
|
||||
if [[ $buildOn == "local" ]] && [[ $buildOnRemote == "y" ]]; then
|
||||
abort "Conflicting flags: --build-on local and --build-on-remote used."
|
||||
fi
|
||||
|
||||
if [[ -n ${flake} ]]; then
|
||||
if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
|
||||
flake="${BASH_REMATCH[1]}"
|
||||
flakeAttr="${BASH_REMATCH[2]}"
|
||||
fi
|
||||
if [[ -z ${flakeAttr} ]]; then
|
||||
echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri." >&2
|
||||
echo 'For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Support .#foo shorthand
|
||||
if [[ $flakeAttr != nixosConfigurations.* ]]; then
|
||||
flakeAttr="nixosConfigurations.\"$flakeAttr\".config"
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# ssh wrapper
|
||||
runSshNoTty() {
|
||||
ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@"
|
||||
}
|
||||
runSshTimeout() {
|
||||
timeout 10 ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@"
|
||||
}
|
||||
runSsh() {
|
||||
ssh "$sshTtyParam" -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@"
|
||||
}
|
||||
|
||||
nixCopy() {
|
||||
NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix copy \
|
||||
"${nixOptions[@]}" \
|
||||
"${nixCopyOptions[@]}" \
|
||||
"$@"
|
||||
}
|
||||
nixBuild() {
|
||||
NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix build \
|
||||
--print-out-paths \
|
||||
--no-link \
|
||||
"${nixBuildFlags[@]}" \
|
||||
"${nixOptions[@]}" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
runVmTest() {
|
||||
if [[ -z ${flakeAttr} ]]; then
|
||||
echo "--vm-test is not supported with --store-paths" >&2
|
||||
echo "Please use --flake instead or build config.system.build.installTest of your nixos configuration manually" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${buildOn} == "remote" ]]; then
|
||||
echo "--vm-test is not supported with --build-on-remote" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n ${extraFiles} ]]; then
|
||||
echo "--vm-test is not supported with --extra-files" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ${#diskEncryptionKeys[@]} -gt 0 ]; then
|
||||
echo "--vm-test is not supported with --disk-encryption-keys" >&2
|
||||
exit 1
|
||||
fi
|
||||
nix build \
|
||||
--print-out-paths \
|
||||
--no-link \
|
||||
-L \
|
||||
"${nixBuildFlags[@]}" \
|
||||
"${nixOptions[@]}" \
|
||||
"${flake}#${flakeAttr}.system.build.installTest"
|
||||
}
|
||||
|
||||
uploadSshKey() {
|
||||
# ssh-copy-id requires this directory
|
||||
mkdir -p "$HOME/.ssh/"
|
||||
if [[ -n ${sshPrivateKeyFile} ]]; then
|
||||
cp "$sshPrivateKeyFile" "$sshKeyDir/nixos-anywhere"
|
||||
ssh-keygen -y -f "$sshKeyDir/nixos-anywhere" >"$sshKeyDir/nixos-anywhere.pub"
|
||||
else
|
||||
# we generate a temporary ssh keypair that we can use during nixos-anywhere
|
||||
ssh-keygen -t ed25519 -f "$sshKeyDir"/nixos-anywhere -P "" -C "nixos-anywhere" >/dev/null
|
||||
fi
|
||||
|
||||
declare -a sshCopyIdArgs
|
||||
if [[ -n ${sshPrivateKeyFile} ]]; then
|
||||
unset SSH_AUTH_SOCK # don't use system agent if key was supplied
|
||||
sshCopyIdArgs+=(-o "IdentityFile=${sshPrivateKeyFile}" -f)
|
||||
fi
|
||||
|
||||
step Uploading install SSH keys
|
||||
until
|
||||
if [[ ${envPassword} == y ]]; then
|
||||
sshpass -e \
|
||||
ssh-copy-id \
|
||||
-i "$sshKeyDir"/nixos-anywhere.pub \
|
||||
-o ConnectTimeout=10 \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o IdentitiesOnly=yes \
|
||||
-o StrictHostKeyChecking=no \
|
||||
"${sshCopyIdArgs[@]}" \
|
||||
"${sshArgs[@]}" \
|
||||
"$sshConnection"
|
||||
else
|
||||
ssh-copy-id \
|
||||
-i "$sshKeyDir"/nixos-anywhere.pub \
|
||||
-o ConnectTimeout=10 \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o StrictHostKeyChecking=no \
|
||||
"${sshCopyIdArgs[@]}" \
|
||||
"${sshArgs[@]}" \
|
||||
"$sshConnection"
|
||||
fi
|
||||
do
|
||||
sleep 3
|
||||
done
|
||||
}
|
||||
|
||||
importFacts() {
|
||||
step Gathering machine facts
|
||||
local facts filteredFacts
|
||||
if ! facts=$(runSsh -o ConnectTimeout=10 enableDebug=$enableDebug sh -- <"$here"/get-facts.sh); then
|
||||
exit 1
|
||||
fi
|
||||
filteredFacts=$(echo "$facts" | grep -E '^(has|is)[A-Za-z0-9_]+=\S+')
|
||||
if [[ -z $filteredFacts ]]; then
|
||||
abort "Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already"
|
||||
fi
|
||||
# make facts available in script
|
||||
# shellcheck disable=SC2046
|
||||
export $(echo "$filteredFacts" | xargs)
|
||||
|
||||
for var in isOs isArch isKexec isInstaller isContainer hasIpv6Only hasTar hasCpio hasSudo hasDoas hasWget hasCurl hasSetsid; do
|
||||
if [[ -z ${!var} ]]; then
|
||||
abort "Failed to retrieve fact $var from host"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
checkBuildLocally() {
|
||||
local system extraPlatforms machineSystem
|
||||
system="$(nix --extra-experimental-features 'nix-command flakes' config show system)"
|
||||
extraPlatforms="$(nix --extra-experimental-features 'nix-command flakes' config show extra-platforms)"
|
||||
|
||||
if [[ $# -gt 0 ]]; then
|
||||
machineSystem=$1
|
||||
elif [[ -n ${nixosSystem} ]]; then
|
||||
machineSystem="$(cat "${nixosSystem}"/system)"
|
||||
else
|
||||
machineSystem="$(nix --extra-experimental-features 'nix-command flakes' eval --raw "${flake}"#"${flakeAttr}".pkgs.system 2>/dev/null || echo "unknown")"
|
||||
if [[ ${machineSystem} == "unknown" ]]; then
|
||||
buildOn=auto
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${system} == "${machineSystem}" ]]; then
|
||||
buildOn=local
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ ${extraPlatforms} == "*${machineSystem}*" ]]; then
|
||||
buildOn=local
|
||||
return
|
||||
fi
|
||||
|
||||
local entropy
|
||||
entropy="$(date +'%Y%m%d%H%M%S')"
|
||||
if nix build \
|
||||
-L \
|
||||
"${nixOptions[@]}" \
|
||||
--expr \
|
||||
"derivation { system = \"$system\"; name = \"env-$entropy\"; builder = \"/bin/sh\"; args = [ \"-c\" \"echo > \$out\" ]; }"; then
|
||||
# The local build failed
|
||||
buildOn=local
|
||||
fi
|
||||
|
||||
buildOn=remote
|
||||
}
|
||||
|
||||
generateHardwareConfig() {
|
||||
local maybeSudo="$maybeSudo"
|
||||
mkdir -p "$(dirname "$hardwareConfigPath")"
|
||||
case "$hardwareConfigBackend" in
|
||||
nixos-facter)
|
||||
if [[ ${isInstaller} == "y" ]]; then
|
||||
if [[ ${hasNixOSFacter} == "n" ]]; then
|
||||
abort "nixos-facter is not available in booted installer, use nixos-generate-config. For nixos-facter, you may want to boot an installer image from here instead: https://github.com/nix-community/nixos-images"
|
||||
fi
|
||||
else
|
||||
maybeSudo=""
|
||||
fi
|
||||
|
||||
step "Generating hardware-configuration.nix using nixos-facter"
|
||||
runSshNoTty -o ConnectTimeout=10 ${maybeSudo} "nixos-facter" >"$hardwareConfigPath"
|
||||
;;
|
||||
nixos-generate-config)
|
||||
step "Generating hardware-configuration.nix using nixos-generate-config"
|
||||
runSshNoTty -o ConnectTimeout=10 nixos-generate-config --show-hardware-config --no-filesystems >"$hardwareConfigPath"
|
||||
;;
|
||||
*)
|
||||
abort "Unknown hardware config backend: $hardwareConfigBackend"
|
||||
;;
|
||||
esac
|
||||
|
||||
# to make sure nix knows about the new file
|
||||
if command -v git >/dev/null; then
|
||||
# handle relative paths
|
||||
hardwareConfigPath="$(realpath "$hardwareConfigPath")"
|
||||
pushd "$(dirname "$hardwareConfigPath")"
|
||||
if git rev-parse --is-inside-work-tree >/dev/null; then
|
||||
git add --intent-to-add --force -- "$hardwareConfigPath"
|
||||
fi
|
||||
popd
|
||||
fi
|
||||
}
|
||||
|
||||
runKexec() {
|
||||
if [[ ${isKexec} == "y" ]] || [[ ${isInstaller} == "y" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ ${isContainer} != "none" ]]; then
|
||||
echo "WARNING: This script does not support running from a '${isContainer}' container. kexec will likely not work" >&2
|
||||
fi
|
||||
|
||||
if [[ $kexecUrl == "" ]]; then
|
||||
case "${isArch}" in
|
||||
x86_64 | aarch64)
|
||||
kexecUrl="https://github.com/nix-community/nixos-images/releases/download/nixos-24.11/nixos-kexec-installer-noninteractive-${isArch}-linux.tar.gz"
|
||||
;;
|
||||
*)
|
||||
abort "Unsupported architecture: ${isArch}. Our default kexec images only support x86_64 and aarch64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information."
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
step Switching system into kexec
|
||||
runSsh sh <<SSH
|
||||
set -efu ${enableDebug}
|
||||
$maybeSudo rm -rf /root/kexec
|
||||
$maybeSudo mkdir -p /root/kexec
|
||||
SSH
|
||||
|
||||
# no way to reach global ipv4 destinations, use gh-v6.com automatically if github url
|
||||
if [[ ${hasIpv6Only} == "y" ]] && [[ $kexecUrl == "https://github.com/"* ]]; then
|
||||
kexecUrl=${kexecUrl/"github.com"/"gh-v6.com"}
|
||||
fi
|
||||
|
||||
if [[ -f $kexecUrl ]]; then
|
||||
runSsh "${maybeSudo} tar -C /root/kexec -xvzf-" <"$kexecUrl"
|
||||
elif [[ ${hasCurl} == "y" ]]; then
|
||||
runSsh "curl --fail -Ss -L '${kexecUrl}' | ${maybeSudo} tar -C /root/kexec -xvzf-"
|
||||
elif [[ ${hasWget} == "y" ]]; then
|
||||
runSsh "wget '${kexecUrl}' -O- | ${maybeSudo} tar -C /root/kexec -xvzf-"
|
||||
else
|
||||
curl --fail -Ss -L "${kexecUrl}" | runSsh "${maybeSudo} tar -C /root/kexec -xvzf-"
|
||||
fi
|
||||
|
||||
runSsh <<SSH
|
||||
TMPDIR=/root/kexec setsid ${maybeSudo} /root/kexec/kexec/run --kexec-extra-flags "${kexecExtraFlags}"
|
||||
SSH
|
||||
|
||||
# use the default SSH port to connect at this point
|
||||
for i in "${!sshArgs[@]}"; do
|
||||
if [[ ${sshArgs[i]} == "-p" ]]; then
|
||||
sshArgs[i + 1]=$postKexecSshPort
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# wait for machine to become unreachable.
|
||||
while runSshTimeout -- exit 0; do sleep 1; done
|
||||
|
||||
# After kexec we explicitly set the user to root@
|
||||
sshConnection="root@${sshHost}"
|
||||
|
||||
# waiting for machine to become available again
|
||||
until runSsh -o ConnectTimeout=10 -- exit 0; do sleep 5; done
|
||||
}
|
||||
|
||||
runDisko() {
|
||||
local diskoScript=$1
|
||||
for path in "${!diskEncryptionKeys[@]}"; do
|
||||
step "Uploading ${diskEncryptionKeys[$path]} to $path"
|
||||
runSsh "umask 077; mkdir -p \"$(dirname "$path")\"; cat > $path" <"${diskEncryptionKeys[$path]}"
|
||||
done
|
||||
if [[ -n ${diskoScript} ]]; then
|
||||
nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "$diskoScript"
|
||||
elif [[ ${buildOn} == "remote" ]]; then
|
||||
step Building disko script
|
||||
# We need to do a nix copy first because nix build doesn't have --no-check-sigs
|
||||
# Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359
|
||||
nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "${flake}#${flakeAttr}.system.build.${diskoMode}Script" \
|
||||
--derivation --no-check-sigs
|
||||
# If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store`
|
||||
diskoScript=$(
|
||||
nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}" \
|
||||
--eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&$sshStoreSettings"
|
||||
)
|
||||
fi
|
||||
|
||||
step Formatting hard drive with disko
|
||||
runSsh "$diskoScript"
|
||||
}
|
||||
|
||||
nixosInstall() {
|
||||
local nixosSystem=$1
|
||||
if [[ -n ${nixosSystem} ]]; then
|
||||
step Uploading the system closure
|
||||
nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "$nixosSystem"
|
||||
elif [[ ${buildOn} == "remote" ]]; then
|
||||
step Building the system closure
|
||||
# We need to do a nix copy first because nix build doesn't have --no-check-sigs
|
||||
# Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359
|
||||
nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "${flake}#${flakeAttr}.system.build.toplevel" \
|
||||
--derivation --no-check-sigs
|
||||
# If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store`
|
||||
nixosSystem=$(
|
||||
nixBuild "${flake}#${flakeAttr}.system.build.toplevel" \
|
||||
--eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&remote-store=local%3Froot=%2Fmnt&$sshStoreSettings"
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ -n ${extraFiles} ]]; then
|
||||
step Copying extra files
|
||||
tar -C "$extraFiles" -cpf- . | runSsh "tar -C /mnt -xf- --no-same-owner"
|
||||
|
||||
runSsh "chmod 755 /mnt" # tar also changes permissions of /mnt
|
||||
fi
|
||||
|
||||
if [[ ${#extraFilesOwnership[@]} -gt 0 ]]; then
|
||||
# shellcheck disable=SC2016
|
||||
printf "%s\n" "${!extraFilesOwnership[@]}" "${extraFilesOwnership[@]}" | pr -2t | runSsh 'while read file ownership; do chown -R "$ownership" "/mnt/$file"; done'
|
||||
fi
|
||||
|
||||
step Installing NixOS
|
||||
runSsh sh <<SSH
|
||||
set -eu ${enableDebug}
|
||||
# when running not in nixos we might miss this directory, but it's needed in the nixos chroot during installation
|
||||
export PATH="\$PATH:/run/current-system/sw/bin"
|
||||
|
||||
# needed for installation if initrd-secrets are used
|
||||
mkdir -p /mnt/tmp
|
||||
chmod 777 /mnt/tmp
|
||||
if [ ${copyHostKeys-n} = "y" ]; then
|
||||
# NB we copy host keys that are in turn copied by kexec installer.
|
||||
mkdir -m 755 -p /mnt/etc/ssh
|
||||
for p in /etc/ssh/ssh_host_*; do
|
||||
# Skip if the source file does not exist (i.e. glob did not match any files)
|
||||
# or the destination already exists (e.g. copied with --extra-files).
|
||||
if [ ! -e "\$p" ] || [ -e "/mnt/\$p" ]; then
|
||||
continue
|
||||
fi
|
||||
cp -a "\$p" "/mnt/\$p"
|
||||
done
|
||||
fi
|
||||
# https://stackoverflow.com/a/13864829
|
||||
if [ ! -z ${NIXOS_NO_CHECK+0} ]; then
|
||||
export NIXOS_NO_CHECK
|
||||
fi
|
||||
nixos-install --no-root-passwd --no-channel-copy --system "$nixosSystem"
|
||||
if [[ ${phases[reboot]} == 1 ]]; then
|
||||
if command -v zpool >/dev/null && [ "\$(zpool list)" != "no pools available" ]; then
|
||||
# we always want to export the zfs pools so people can boot from it without force import
|
||||
umount -Rv /mnt/
|
||||
swapoff -a
|
||||
zpool export -a || true
|
||||
fi
|
||||
nohup sh -c 'sleep 6 && reboot' >/dev/null &
|
||||
fi
|
||||
SSH
|
||||
|
||||
}
|
||||
|
||||
main() {
|
||||
parseArgs "$@"
|
||||
|
||||
if [[ ${vmTest} == y ]]; then
|
||||
if [[ ${hardwareConfigBackend} != "none" ]]; then
|
||||
abort "--vm-test is not supported with --generate-hardware-config. You need to generate the hardware configuration before you can run the VM test." >&2
|
||||
fi
|
||||
runVmTest
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ${buildOn} == "auto" ]]; then
|
||||
checkBuildLocally
|
||||
fi
|
||||
|
||||
# parse flake nixos-install style syntax, get the system attr
|
||||
if [[ -n ${flake} ]]; then
|
||||
if [[ ${buildOn} == "local" ]] && [[ ${hardwareConfigBackend} == "none" ]]; then
|
||||
if [[ ${phases[disko]} == 1 ]]; then
|
||||
diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}")
|
||||
fi
|
||||
if [[ ${phases[install]} == 1 ]]; then
|
||||
nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel")
|
||||
fi
|
||||
fi
|
||||
elif [[ -n ${diskoScript} ]] && [[ -n ${nixosSystem} ]]; then
|
||||
if [[ ! -e ${diskoScript} ]] || [[ ! -e ${nixosSystem} ]]; then
|
||||
abort "${diskoScript} and ${nixosSystem} must be existing store-paths"
|
||||
fi
|
||||
else
|
||||
abort "--flake or --store-paths must be set"
|
||||
fi
|
||||
|
||||
if [[ -n ${SSH_PRIVATE_KEY} ]] && [[ -z ${sshPrivateKeyFile} ]]; then
|
||||
# $sshKeyDir is getting deleted on trap EXIT
|
||||
sshPrivateKeyFile="$sshKeyDir/from-env"
|
||||
(
|
||||
umask 077
|
||||
printf '%s\n' "$SSH_PRIVATE_KEY" >"$sshPrivateKeyFile"
|
||||
)
|
||||
fi
|
||||
|
||||
sshSettings=$(ssh "${sshArgs[@]}" -G "${sshConnection}")
|
||||
sshUser=$(echo "$sshSettings" | awk '/^user / { print $2 }')
|
||||
sshHost=$(echo "$sshSettings" | awk '/^hostname / { print $2 }')
|
||||
|
||||
uploadSshKey
|
||||
|
||||
importFacts
|
||||
|
||||
if [[ ${hasTar-n} == "n" ]]; then
|
||||
abort "no tar command found, but required to unpack kexec tarball"
|
||||
fi
|
||||
|
||||
if [[ ${hasCpio-n} == "n" ]]; then
|
||||
abort "no cpio command found, but required to build the new initrd"
|
||||
fi
|
||||
|
||||
if [[ ${hasSetsid-n} == "n" ]]; then
|
||||
abort "no setsid command found, but required to run the kexec script under a new session"
|
||||
fi
|
||||
|
||||
maybeSudo=""
|
||||
if [[ ${hasSudo-n} == "y" ]]; then
|
||||
maybeSudo="sudo"
|
||||
elif [[ ${hasDoas-n} == "y" ]]; then
|
||||
maybeSudo="doas"
|
||||
fi
|
||||
|
||||
if [[ ${isOs} != "Linux" ]]; then
|
||||
abort "This script requires Linux as the operating system, but got $isOs"
|
||||
fi
|
||||
|
||||
if [[ ${phases[kexec]} == 1 ]]; then
|
||||
runKexec
|
||||
fi
|
||||
|
||||
if [[ ${hardwareConfigBackend} != "none" ]]; then
|
||||
generateHardwareConfig
|
||||
fi
|
||||
|
||||
# Before we do not have a valid hardware configuration we don't know the machine system
|
||||
if [[ ${buildOn} == "auto" ]]; then
|
||||
local remoteSystem
|
||||
remoteSystem=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features nix-command config show system)
|
||||
checkBuildLocally "${remoteSystem}"
|
||||
# if we cannot figure it out at this point, we will build on the remote host
|
||||
if [[ ${buildOn} == "auto" ]]; then
|
||||
buildOn=remote
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${buildOn} != "remote" ]] && [[ -n ${flake} ]] && [[ -z ${diskoScript} ]]; then
|
||||
if [[ ${phases[disko]} == 1 ]]; then
|
||||
diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}")
|
||||
fi
|
||||
if [[ ${phases[install]} == 1 ]]; then
|
||||
nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel")
|
||||
fi
|
||||
fi
|
||||
|
||||
# Installation will fail if non-root user is used for installer.
|
||||
# Switch to root user by copying authorized_keys.
|
||||
if [[ ${isInstaller} == "y" ]] && [[ ${sshUser} != "root" ]]; then
|
||||
# Allow copy to fail if authorized_keys does not exist, like if using /etc/ssh/authorized_keys.d/
|
||||
runSsh "${maybeSudo} mkdir -p /root/.ssh; ${maybeSudo} cp ~/.ssh/authorized_keys /root/.ssh || true"
|
||||
sshConnection="root@${sshHost}"
|
||||
fi
|
||||
|
||||
if [[ ${phases[disko]} == 1 ]]; then
|
||||
runDisko "$diskoScript"
|
||||
fi
|
||||
|
||||
if [[ ${phases[install]} == 1 ]]; then
|
||||
nixosInstall "$nixosSystem"
|
||||
fi
|
||||
|
||||
if [[ ${phases[reboot]} == 1 ]]; then
|
||||
step Waiting for the machine to become unreachable due to reboot
|
||||
while runSshTimeout -- exit 0; do sleep 1; done
|
||||
fi
|
||||
|
||||
step "Done!"
|
||||
}
|
||||
|
||||
main "$@"
|
|
@ -0,0 +1,21 @@
|
|||
# NixOS-Anywhere Terraform Modules Overview
|
||||
|
||||
The nixos-Anywhere terraform modules allow you to use Terraform for installing
|
||||
and updating NixOS. It simplifies the deployment process by integrating
|
||||
nixos-anywhere functionality.
|
||||
|
||||
Here's a brief overview of each module:
|
||||
|
||||
- **[All-in-One](all-in-one.md)**: This is a consolidated module that first
|
||||
installs NixOS using nixos-anywhere and then keeps it updated with
|
||||
nixos-rebuild. If you choose this, you won't need additional deployment tools
|
||||
like colmena.
|
||||
- **[Install](install.md)**: This module focuses solely on installing NixOS via
|
||||
nixos-anywhere.
|
||||
- **[NixOS-Rebuild](nixos-rebuild.md)**: Use this module to remotely update an
|
||||
existing NixOS machine using nixos-rebuild.
|
||||
- **[Nix-Build](nix-build.md)**: This is a handy helper module designed to build
|
||||
a flake attribute or an attribute from a nix file.
|
||||
|
||||
For detailed information and usage examples, click on the respective module
|
||||
links above.
|
|
@ -0,0 +1,235 @@
|
|||
# All-in-one
|
||||
|
||||
Combines the install and nixos-rebuild module in one interface to install NixOS
|
||||
with nixos-anywhere and then keep it up-to-date with nixos-rebuild.
|
||||
|
||||
## Example
|
||||
|
||||
```hcl
|
||||
locals {
|
||||
ipv4 = "192.0.2.1"
|
||||
}
|
||||
|
||||
module "deploy" {
|
||||
source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one"
|
||||
# with flakes
|
||||
nixos_system_attr = ".#nixosConfigurations.mymachine.config.system.build.toplevel"
|
||||
nixos_partitioner_attr = ".#nixosConfigurations.mymachine.config.system.build.diskoScript"
|
||||
# without flakes
|
||||
# file can use (pkgs.nixos []) function from nixpkgs
|
||||
#file = "${path.module}/../.."
|
||||
#nixos_system_attr = "config.system.build.toplevel"
|
||||
#nixos_partitioner_attr = "config.system.build.diskoScript"
|
||||
|
||||
target_host = local.ipv4
|
||||
# when instance id changes, it will trigger a reinstall
|
||||
instance_id = local.ipv4
|
||||
# useful if something goes wrong
|
||||
# debug_logging = true
|
||||
# build the closure on the remote machine instead of locally
|
||||
# build_on_remote = true
|
||||
# script is below
|
||||
extra_files_script = "${path.module}/decrypt-ssh-secrets.sh"
|
||||
disk_encryption_key_scripts = [{
|
||||
path = "/tmp/secret.key"
|
||||
# script is below
|
||||
script = "${path.module}/decrypt-zfs-key.sh"
|
||||
}]
|
||||
# Optional, arguments passed to special_args here will be available from a NixOS module in this example the `terraform` argument:
|
||||
# { terraform, ... }: {
|
||||
# networking.interfaces.enp0s3.ipv4.addresses = [{ address = terraform.ip; prefixLength = 24; }];
|
||||
# }
|
||||
# Note that this will means that your NixOS configuration will always depend on terraform!
|
||||
# Skip to `Pass data persistently to the NixOS` for an alternative approach
|
||||
#special_args = {
|
||||
# terraform = {
|
||||
# ip = "192.0.2.0"
|
||||
# }
|
||||
#}
|
||||
}
|
||||
```
|
||||
|
||||
_Note:_ You need to mark scripts as executable (`chmod +x`)
|
||||
|
||||
### ./decrypt-ssh-secrets.sh
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
mkdir -p etc/ssh var/lib/secrets
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
umask 0177
|
||||
sops --extract '["initrd_ssh_key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >./var/lib/secrets/initrd_ssh_key
|
||||
|
||||
# restore umask
|
||||
umask 0022
|
||||
|
||||
for keyname in ssh_host_rsa_key ssh_host_rsa_key.pub ssh_host_ed25519_key ssh_host_ed25519_key.pub; do
|
||||
if [[ $keyname == *.pub ]]; then
|
||||
umask 0133
|
||||
else
|
||||
umask 0177
|
||||
fi
|
||||
sops --extract '["'$keyname'"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >"./etc/ssh/$keyname"
|
||||
done
|
||||
```
|
||||
|
||||
### ./decrypt-zfs-key.sh
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
cd "$SCRIPT_DIR"
|
||||
sops --extract '["zfs-key"]' --decrypt "$SCRIPT_DIR/secrets.yaml"
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [nixos-wiki setup](https://github.com/NixOS/nixos-wiki-infra/blob/main/terraform/nixos-wiki/main.tf)
|
||||
for hetzner-cloud
|
||||
|
||||
## Pass data persistently to the NixOS
|
||||
|
||||
This guide outlines how to pass data from Terraform to NixOS by generating a
|
||||
file during Terraform execution and including it in your NixOS configuration.
|
||||
This approach works well if your Terraform and NixOS configurations are stored
|
||||
in the same Git repository.
|
||||
|
||||
### Why Use This Method?
|
||||
|
||||
This method provides a straightforward way to transfer values from Terraform to
|
||||
NixOS without relying on special_args.
|
||||
|
||||
- **Advantages**:
|
||||
- You can continue to use nix build or nixos-rebuild to evaluate your
|
||||
configuration without interruption. Simplifies configuration management by
|
||||
centralizing state in a single repository.
|
||||
- **Disadvantages**:
|
||||
- Deploying new machines requires tracking additional state. Every time
|
||||
Terraform updates the JSON file, you'll need to commit these changes to your
|
||||
repository.
|
||||
|
||||
### Implementation
|
||||
|
||||
Add the following snippet to your Terraform configuration to create and manage a
|
||||
JSON file containing the necessary variables for NixOS. This file will be
|
||||
automatically added to your Git repository, ensuring the data persists.
|
||||
|
||||
Assuming you have your terraform and nixos configuration in the same git
|
||||
repository. You can use the following snippet to `git add` a file generated by
|
||||
`terraform` during execution to pass data from terraform to NixOS. These changes
|
||||
should be committed afterwards. This is an alternative over using
|
||||
`special_args`. Advantage: you can still use nix build or nixos-rebuild on your
|
||||
flake to evaluate your configuration. Disadvantage: Deploying new machines also
|
||||
means you need to track additional state and make additional commits whenever
|
||||
terraform updates the json file.
|
||||
|
||||
```hcl
|
||||
locals {
|
||||
nixos_vars_file = "nixos-vars.json" # Path to the JSON file containing NixOS variables
|
||||
nixos_vars = {
|
||||
ip = "192.0.2.0" # Replace with actual variables
|
||||
}
|
||||
}
|
||||
resource "local_file" "nixos_vars" {
|
||||
content = jsonencode(local.nixos_vars) # Converts variables to JSON
|
||||
filename = local.nixos_vars_file # Specifies the output file path
|
||||
file_permission = "600"
|
||||
|
||||
# Automatically adds the generated file to Git
|
||||
provisioner "local-exec" {
|
||||
interpreter = ["bash", "-c"]
|
||||
command = "git add -f '${local.nixos_vars_file}'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After applying the Terraform changes, ensure you commit the updated
|
||||
`nixos-vars.json` file to your Git repository:
|
||||
|
||||
```bash
|
||||
git commit -m "Update NixOS variables from Terraform"
|
||||
```
|
||||
|
||||
You can import this json file into your configuration like this:
|
||||
|
||||
```nix
|
||||
let
|
||||
nixosVars = builtins.fromJSON (builtins.readFile ./nixos-vars.json);
|
||||
in
|
||||
{
|
||||
# Example usage of imported variables
|
||||
networking.hostName = "example-machine";
|
||||
networking.interfaces.eth0.ipv4.addresses = [
|
||||
{
|
||||
address = nixosVars.ip; # Use the IP from nixos-vars.json
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
<!-- BEGIN_TF_DOCS -->
|
||||
|
||||
## Requirements
|
||||
|
||||
No requirements.
|
||||
|
||||
## Providers
|
||||
|
||||
No providers.
|
||||
|
||||
## Modules
|
||||
|
||||
| Name | Source | Version |
|
||||
| -------------------------------------------------------------------------------------- | ---------------- | ------- |
|
||||
| <a name="module_install"></a> [install](#module_install) | ../install | n/a |
|
||||
| <a name="module_nixos-rebuild"></a> [nixos-rebuild](#module_nixos-rebuild) | ../nixos-rebuild | n/a |
|
||||
| <a name="module_partitioner-build"></a> [partitioner-build](#module_partitioner-build) | ../nix-build | n/a |
|
||||
| <a name="module_system-build"></a> [system-build](#module_system-build) | ../nix-build | n/a |
|
||||
|
||||
## Resources
|
||||
|
||||
No resources.
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: |
|
||||
| <a name="input_debug_logging"></a> [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no |
|
||||
| <a name="input_deployment_ssh_key"></a> [deployment\_ssh\_key](#input_deployment_ssh_key) | Content of private key used to deploy to the target\_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable | `string` | `null` | no |
|
||||
| <a name="input_disk_encryption_key_scripts"></a> [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system | <pre>list(object({<br> path = string<br> script = string<br> }))</pre> | `[]` | no |
|
||||
| <a name="input_extra_environment"></a> [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no |
|
||||
| <a name="input_extra_files_script"></a> [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no |
|
||||
| <a name="input_file"></a> [file](#input_file) | Nix file containing the nixos\_system\_attr and nixos\_partitioner\_attr. Use this if you are not using flake | `string` | `null` | no |
|
||||
| <a name="input_install_port"></a> [install\_port](#input_install_port) | SSH port used to connect to the target\_host, before installing NixOS. If null than the value of `target_port` is used | `string` | `null` | no |
|
||||
| <a name="input_install_ssh_key"></a> [install\_ssh\_key](#input_install_ssh_key) | Content of private key used to connect to the target\_host during initial installation | `string` | `null` | no |
|
||||
| <a name="input_install_user"></a> [install\_user](#input_install_user) | SSH user used to connect to the target\_host, before installing NixOS. If null than the value of `target_host` is used | `string` | `null` | no |
|
||||
| <a name="input_instance_id"></a> [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no |
|
||||
| <a name="input_kexec_tarball_url"></a> [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no |
|
||||
| <a name="input_nix_options"></a> [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no |
|
||||
| <a name="input_nixos_facter_path"></a> [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. | `string` | `""` | no |
|
||||
| <a name="input_nixos_generate_config_path"></a> [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. | `string` | `""` | no |
|
||||
| <a name="input_nixos_partitioner_attr"></a> [nixos\_partitioner\_attr](#input_nixos_partitioner_attr) | Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module | `string` | n/a | yes |
|
||||
| <a name="input_nixos_system_attr"></a> [nixos\_system\_attr](#input_nixos_system_attr) | The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes | `string` | n/a | yes |
|
||||
| <a name="input_no_reboot"></a> [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no |
|
||||
| <a name="input_phases"></a> [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `set(string)` | <pre>[<br> "kexec",<br> "disko",<br> "install",<br> "reboot"<br>]</pre> | no |
|
||||
| <a name="input_special_args"></a> [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no |
|
||||
| <a name="input_build_on_remote"></a> [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no |
|
||||
| <a name="input_stop_after_disko"></a> [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no |
|
||||
| <a name="input_target_host"></a> [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes |
|
||||
| <a name="input_target_port"></a> [target\_port](#input_target_port) | SSH port used to connect to the target\_host after installing NixOS. If install\_port is not set than this port is also used before installing. | `number` | `22` | no |
|
||||
| <a name="input_target_user"></a> [target\_user](#input_target_user) | SSH user used to connect to the target\_host after installing NixOS. If install\_user is not set than this user is also used before installing. | `string` | `"root"` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
| ----------------------------------------------------- | ----------- |
|
||||
| <a name="output_result"></a> [result](#output_result) | n/a |
|
||||
|
||||
<!-- END_TF_DOCS -->
|
|
@ -0,0 +1,64 @@
|
|||
module "system-build" {
|
||||
source = "../nix-build"
|
||||
attribute = var.nixos_system_attr
|
||||
file = var.file
|
||||
nix_options = var.nix_options
|
||||
special_args = var.special_args
|
||||
}
|
||||
|
||||
module "partitioner-build" {
|
||||
source = "../nix-build"
|
||||
attribute = var.nixos_partitioner_attr
|
||||
file = var.file
|
||||
nix_options = var.nix_options
|
||||
special_args = var.special_args
|
||||
}
|
||||
|
||||
locals {
|
||||
install_user = var.install_user == null ? var.target_user : var.install_user
|
||||
install_port = var.install_port == null ? var.target_port : var.install_port
|
||||
}
|
||||
|
||||
module "install" {
|
||||
source = "../install"
|
||||
kexec_tarball_url = var.kexec_tarball_url
|
||||
target_user = local.install_user
|
||||
target_host = var.target_host
|
||||
target_port = local.install_port
|
||||
nixos_partitioner = module.partitioner-build.result.out
|
||||
nixos_system = module.system-build.result.out
|
||||
ssh_private_key = var.install_ssh_key
|
||||
debug_logging = var.debug_logging
|
||||
extra_files_script = var.extra_files_script
|
||||
disk_encryption_key_scripts = var.disk_encryption_key_scripts
|
||||
extra_environment = var.extra_environment
|
||||
instance_id = var.instance_id
|
||||
phases = var.phases
|
||||
nixos_generate_config_path = var.nixos_generate_config_path
|
||||
nixos_facter_path = var.nixos_facter_path
|
||||
build_on_remote = var.build_on_remote
|
||||
# deprecated attributes
|
||||
stop_after_disko = var.stop_after_disko
|
||||
no_reboot = var.no_reboot
|
||||
}
|
||||
|
||||
module "nixos-rebuild" {
|
||||
depends_on = [
|
||||
module.install
|
||||
]
|
||||
|
||||
# Do not execute this step if var.stop_after_disko == true
|
||||
count = var.stop_after_disko ? 0 : 1
|
||||
|
||||
source = "../nixos-rebuild"
|
||||
nixos_system = module.system-build.result.out
|
||||
ssh_private_key = var.deployment_ssh_key
|
||||
target_host = var.target_host
|
||||
target_user = var.target_user
|
||||
target_port = var.target_port
|
||||
install_bootloader = var.install_bootloader
|
||||
}
|
||||
|
||||
output "result" {
|
||||
value = module.system-build.result
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
variable "kexec_tarball_url" {
|
||||
type = string
|
||||
description = "NixOS kexec installer tarball url"
|
||||
default = null
|
||||
}
|
||||
|
||||
# To make this re-usable we maybe should accept a store path here?
|
||||
variable "nixos_partitioner_attr" {
|
||||
type = string
|
||||
description = "Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module"
|
||||
}
|
||||
|
||||
# To make this re-usable we maybe should accept a store path here?
|
||||
variable "nixos_system_attr" {
|
||||
type = string
|
||||
description = "The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes"
|
||||
}
|
||||
|
||||
variable "file" {
|
||||
type = string
|
||||
description = "Nix file containing the nixos_system_attr and nixos_partitioner_attr. Use this if you are not using flake"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "target_host" {
|
||||
type = string
|
||||
description = "DNS host to deploy to"
|
||||
}
|
||||
|
||||
variable "install_user" {
|
||||
type = string
|
||||
description = "SSH user used to connect to the target_host, before installing NixOS. If null than the value of `target_host` is used"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "install_port" {
|
||||
type = string
|
||||
description = "SSH port used to connect to the target_host, before installing NixOS. If null than the value of `target_port` is used"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "target_user" {
|
||||
type = string
|
||||
description = "SSH user used to connect to the target_host after installing NixOS. If install_user is not set than this user is also used before installing."
|
||||
default = "root"
|
||||
}
|
||||
|
||||
variable "target_port" {
|
||||
type = number
|
||||
description = "SSH port used to connect to the target_host after installing NixOS. If install_port is not set than this port is also used before installing."
|
||||
default = 22
|
||||
}
|
||||
|
||||
variable "instance_id" {
|
||||
type = string
|
||||
description = "The instance id of the target_host, used to track when to reinstall the machine"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "install_ssh_key" {
|
||||
type = string
|
||||
description = "Content of private key used to connect to the target_host during initial installation"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "deployment_ssh_key" {
|
||||
type = string
|
||||
description = "Content of private key used to deploy to the target_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "debug_logging" {
|
||||
type = bool
|
||||
description = "Enable debug logging"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "stop_after_disko" {
|
||||
type = bool
|
||||
description = "DEPRECATED: Use `phases` instead. Exit after disko formatting"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "no_reboot" {
|
||||
type = bool
|
||||
description = "DEPRECATED: Use `phases` instead. Do not reboot after installation"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "phases" {
|
||||
type = set(string)
|
||||
description = "Phases to run. See `nixos-anywhere --help` for more information"
|
||||
default = ["kexec", "disko", "install", "reboot"]
|
||||
}
|
||||
|
||||
variable "extra_files_script" {
|
||||
type = string
|
||||
description = "A script that should place files in the current directory that will be copied to the targets / directory"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "disk_encryption_key_scripts" {
|
||||
type = list(object({
|
||||
path = string
|
||||
script = string
|
||||
}))
|
||||
description = "Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "extra_environment" {
|
||||
type = map(string)
|
||||
description = "Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "nix_options" {
|
||||
type = map(string)
|
||||
description = "the options of nix"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "nixos_generate_config_path" {
|
||||
type = string
|
||||
description = "Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "nixos_facter_path" {
|
||||
type = string
|
||||
description = "Path to which to write a `facter.json` generated by `nixos-facter`."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "special_args" {
|
||||
type = any
|
||||
default = {}
|
||||
description = "A map exposed as NixOS's `specialArgs` thru a file."
|
||||
}
|
||||
|
||||
variable "build_on_remote" {
|
||||
type = bool
|
||||
description = "Build the closure on the remote machine instead of building it locally and copying it over"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "install_bootloader" {
|
||||
type = bool
|
||||
description = "Install/re-install the bootloader"
|
||||
default = false
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
# Install
|
||||
|
||||
Install NixOS with nixos-anywhere
|
||||
|
||||
## Example
|
||||
|
||||
```hcl
|
||||
locals {
|
||||
ipv4 = "192.0.2.1"
|
||||
}
|
||||
|
||||
module "system-build" {
|
||||
source = "github.com/nix-community/nixos-anywhere//terraform/nix-build"
|
||||
# with flakes
|
||||
attribute = ".#nixosConfigurations.mymachine.config.system.build.toplevel"
|
||||
# without flakes
|
||||
# file can use (pkgs.nixos []) function from nixpkgs
|
||||
#file = "${path.module}/../.."
|
||||
#attribute = "config.system.build.toplevel"
|
||||
}
|
||||
|
||||
module "disko" {
|
||||
source = "github.com/nix-community/nixos-anywhere//terraform/nix-build"
|
||||
# with flakes
|
||||
attribute = ".#nixosConfigurations.mymachine.config.system.build.diskoScript"
|
||||
# without flakes
|
||||
# file can use (pkgs.nixos []) function from nixpkgs
|
||||
#file = "${path.module}/../.."
|
||||
#attribute = "config.system.build.diskoScript"
|
||||
}
|
||||
|
||||
module "install" {
|
||||
source = "github.com/nix-community/nixos-anywhere//terraform/install"
|
||||
nixos_system = module.system-build.result.out
|
||||
nixos_partitioner = module.disko.result.out
|
||||
target_host = local.ipv4
|
||||
}
|
||||
```
|
||||
|
||||
<!-- BEGIN_TF_DOCS -->
|
||||
|
||||
## Requirements
|
||||
|
||||
No requirements.
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
| --------------------------------------------------- | ------- |
|
||||
| <a name="provider_null"></a> [null](#provider_null) | n/a |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
| ------------------------------------------------------------------------------------------------------------------- | -------- |
|
||||
| [null_resource.nixos-remote](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
| --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: |
|
||||
| <a name="input_build_on_remote"></a> [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no |
|
||||
| <a name="input_debug_logging"></a> [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no |
|
||||
| <a name="input_disk_encryption_key_scripts"></a> [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system | <pre>list(object({<br> path = string<br> script = string<br> }))</pre> | `[]` | no |
|
||||
| <a name="input_extra_environment"></a> [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no |
|
||||
| <a name="input_extra_files_script"></a> [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no |
|
||||
| <a name="input_flake"></a> [flake](#input_flake) | The flake to install the system from | `string` | `""` | no |
|
||||
| <a name="input_instance_id"></a> [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no |
|
||||
| <a name="input_kexec_tarball_url"></a> [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no |
|
||||
| <a name="input_nixos_facter_path"></a> [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. This option cannot be set at the same time as `nixos_generate_config_path`. | `string` | `""` | no |
|
||||
| <a name="input_nixos_generate_config_path"></a> [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. This option cannot be set at the same time as `nixos_facter_path`. | `string` | `""` | no |
|
||||
| <a name="input_nixos_partitioner"></a> [nixos\_partitioner](#input_nixos_partitioner) | nixos partitioner and mount script | `string` | `""` | no |
|
||||
| <a name="input_nixos_system"></a> [nixos\_system](#input_nixos_system) | The nixos system to deploy | `string` | `""` | no |
|
||||
| <a name="input_no_reboot"></a> [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no |
|
||||
| <a name="input_phases"></a> [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `list(string)` | <pre>[<br> "kexec",<br> "disko",<br> "install",<br> "reboot"<br>]</pre> | no |
|
||||
| <a name="input_ssh_private_key"></a> [ssh\_private\_key](#input_ssh_private_key) | Content of private key used to connect to the target\_host | `string` | `""` | no |
|
||||
| <a name="input_stop_after_disko"></a> [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no |
|
||||
| <a name="input_target_host"></a> [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes |
|
||||
| <a name="input_target_pass"></a> [target\_pass](#input_target_pass) | Password used to connect to the target\_host | `string` | `null` | no |
|
||||
| <a name="input_target_port"></a> [target\_port](#input_target_port) | SSH port used to connect to the target\_host | `number` | `22` | no |
|
||||
| <a name="input_target_user"></a> [target\_user](#input_target_user) | SSH user used to connect to the target\_host | `string` | `"root"` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
No outputs.
|
||||
|
||||
<!-- END_TF_DOCS -->
|
|
@ -0,0 +1,35 @@
|
|||
locals {
|
||||
disk_encryption_key_scripts = [for k in var.disk_encryption_key_scripts : "\"${k.path}\" \"${k.script}\""]
|
||||
removed_phases = setunion(var.stop_after_disko ? ["install"] : [], (var.no_reboot ? ["reboot"] : []))
|
||||
phases = setsubtract(var.phases, local.removed_phases)
|
||||
arguments = jsonencode({
|
||||
ssh_private_key = var.ssh_private_key
|
||||
debug_logging = var.debug_logging
|
||||
kexec_tarball_url = var.kexec_tarball_url
|
||||
nixos_partitioner = var.nixos_partitioner
|
||||
nixos_system = var.nixos_system
|
||||
target_user = var.target_user
|
||||
target_host = var.target_host
|
||||
target_port = var.target_port
|
||||
target_pass = var.target_pass
|
||||
extra_files_script = var.extra_files_script
|
||||
build_on_remote = var.build_on_remote
|
||||
flake = var.flake
|
||||
phases = join(",", local.phases)
|
||||
nixos_generate_config_path = var.nixos_generate_config_path
|
||||
nixos_facter_path = var.nixos_facter_path
|
||||
})
|
||||
}
|
||||
|
||||
resource "null_resource" "nixos-remote" {
|
||||
triggers = {
|
||||
instance_id = var.instance_id
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
environment = merge({
|
||||
ARGUMENTS = local.arguments
|
||||
}, var.extra_environment)
|
||||
command = "${path.module}/run-nixos-anywhere.sh ${join(" ", local.disk_encryption_key_scripts)}"
|
||||
quiet = var.debug_logging
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
null = { source = "hashicorp/null" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
|
||||
|
||||
declare -A input
|
||||
|
||||
while IFS= read -r -d '' key && IFS= read -r -d '' value; do
|
||||
input[$key]=$value
|
||||
done < <(jq -j 'to_entries[] | (.key, "\u0000", .value, "\u0000")' <<<"${ARGUMENTS}")
|
||||
|
||||
args=()
|
||||
|
||||
if [[ ${input[debug_logging]} == "true" ]]; then
|
||||
set -x
|
||||
declare -p input
|
||||
args+=("--debug")
|
||||
fi
|
||||
if [[ ${input[kexec_tarball_url]} != "null" ]]; then
|
||||
args+=("--kexec" "${input[kexec_tarball_url]}")
|
||||
fi
|
||||
if [[ ${input[build_on_remote]} == "true" ]]; then
|
||||
args+=("--build-on-remote")
|
||||
fi
|
||||
if [[ -n ${input[flake]} ]]; then
|
||||
args+=("--flake" "${input[flake]}")
|
||||
else
|
||||
args+=("--store-paths" "${input[nixos_partitioner]}" "${input[nixos_system]}")
|
||||
fi
|
||||
if [[ -n ${input[nixos_generate_config_path]} ]]; then
|
||||
if [[ -n ${input[nixos_facter_path]} ]]; then
|
||||
echo "cannot set both variables 'nixos_generate_config_path' and 'nixos_facter_path'!" >&2
|
||||
exit 1
|
||||
fi
|
||||
args+=("--generate-hardware-config" "nixos-generate-config" "${input[nixos_generate_config_path]}")
|
||||
elif [[ -n ${input[nixos_facter_path]} ]]; then
|
||||
args+=("--generate-hardware-config" "nixos-facter" "${input[nixos_facter_path]}")
|
||||
fi
|
||||
args+=(--phases "${input[phases]}")
|
||||
if [[ ${input[ssh_private_key]} != null ]]; then
|
||||
export SSH_PRIVATE_KEY="${input[ssh_private_key]}"
|
||||
fi
|
||||
if [[ ${input[target_pass]} != null ]]; then
|
||||
export SSHPASS=${input[target_pass]}
|
||||
args+=("--env-password")
|
||||
fi
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
cleanup() {
|
||||
rm -rf "${tmpdir}"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
if [[ ${input[extra_files_script]} != "null" ]]; then
|
||||
if [[ ! -f ${input[extra_files_script]} ]]; then
|
||||
echo "extra_files_script '${input[extra_files_script]}' does not exist"
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -x ${input[extra_files_script]} ]]; then
|
||||
echo "extra_files_script '${input[extra_files_script]}' is not executable"
|
||||
exit 1
|
||||
fi
|
||||
extra_files_script=$(realpath "${input[extra_files_script]}")
|
||||
mkdir "${tmpdir}/extra-files"
|
||||
pushd "${tmpdir}/extra-files"
|
||||
$extra_files_script
|
||||
popd
|
||||
args+=("--extra-files" "${tmpdir}/extra-files")
|
||||
fi
|
||||
|
||||
args+=("-p" "${input[target_port]}")
|
||||
args+=("${input[target_user]}@${input[target_host]}")
|
||||
|
||||
keyIdx=0
|
||||
while [[ $# -gt 0 ]]; do
|
||||
if [[ ! -f $2 ]]; then
|
||||
echo "Script file '$2' does not exist"
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -x $2 ]]; then
|
||||
echo "Script file '$2' is not executable"
|
||||
exit 1
|
||||
fi
|
||||
mkdir -p "${tmpdir}/keys"
|
||||
"$2" >"${tmpdir}/keys/$keyIdx"
|
||||
args+=("--disk-encryption-keys" "$1" "${tmpdir}/keys/$keyIdx")
|
||||
shift
|
||||
shift
|
||||
keyIdx=$((keyIdx + 1))
|
||||
done
|
||||
|
||||
nix run --extra-experimental-features 'nix-command flakes' "path:${SCRIPT_DIR}/../..#nixos-anywhere" -- "${args[@]}"
|
|
@ -0,0 +1,123 @@
|
|||
variable "kexec_tarball_url" {
|
||||
type = string
|
||||
description = "NixOS kexec installer tarball url"
|
||||
default = null
|
||||
}
|
||||
|
||||
# To make this re-usable we maybe should accept a store path here?
|
||||
variable "nixos_partitioner" {
|
||||
type = string
|
||||
description = "nixos partitioner and mount script"
|
||||
default = ""
|
||||
}
|
||||
|
||||
# To make this re-usable we maybe should accept a store path here?
|
||||
variable "nixos_system" {
|
||||
type = string
|
||||
description = "The nixos system to deploy"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "target_host" {
|
||||
type = string
|
||||
description = "DNS host to deploy to"
|
||||
}
|
||||
|
||||
variable "target_user" {
|
||||
type = string
|
||||
description = "SSH user used to connect to the target_host"
|
||||
default = "root"
|
||||
}
|
||||
|
||||
variable "target_port" {
|
||||
type = number
|
||||
description = "SSH port used to connect to the target_host"
|
||||
default = 22
|
||||
}
|
||||
|
||||
variable "target_pass" {
|
||||
type = string
|
||||
description = "Password used to connect to the target_host"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "ssh_private_key" {
|
||||
type = string
|
||||
description = "Content of private key used to connect to the target_host"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "instance_id" {
|
||||
type = string
|
||||
description = "The instance id of the target_host, used to track when to reinstall the machine"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "debug_logging" {
|
||||
type = bool
|
||||
description = "Enable debug logging"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "extra_files_script" {
|
||||
type = string
|
||||
description = "A script that should place files in the current directory that will be copied to the targets / directory"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "disk_encryption_key_scripts" {
|
||||
type = list(object({
|
||||
path = string
|
||||
script = string
|
||||
}))
|
||||
description = "Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "extra_environment" {
|
||||
type = map(string)
|
||||
description = "Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "stop_after_disko" {
|
||||
type = bool
|
||||
description = "DEPRECATED: Use `phases` instead. Exit after disko formatting"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "no_reboot" {
|
||||
type = bool
|
||||
description = "DEPRECATED: Use `phases` instead. Do not reboot after installation"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "phases" {
|
||||
type = list(string)
|
||||
description = "Phases to run. See `nixos-anywhere --help` for more information"
|
||||
default = ["kexec", "disko", "install", "reboot"]
|
||||
}
|
||||
|
||||
variable "build_on_remote" {
|
||||
type = bool
|
||||
description = "Build the closure on the remote machine instead of building it locally and copying it over"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "flake" {
|
||||
type = string
|
||||
description = "The flake to install the system from"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "nixos_generate_config_path" {
|
||||
type = string
|
||||
description = "Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. This option cannot be set at the same time as `nixos_facter_path`."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "nixos_facter_path" {
|
||||
type = string
|
||||
description = "Path to which to write a `facter.json` generated by `nixos-facter`. This option cannot be set at the same time as `nixos_generate_config_path`."
|
||||
default = ""
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
# Nix-build
|
||||
|
||||
Small helper module to run do build a flake attribute or attribute from a nix
|
||||
file.
|
||||
|
||||
## Example
|
||||
|
||||
- See [install](install.md) or [nixos-rebuild](nixos-rebuild.md)
|
||||
|
||||
<!-- BEGIN_TF_DOCS -->
|
||||
|
||||
## Requirements
|
||||
|
||||
No requirements.
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
| --------------------------------------------------------------- | ------- |
|
||||
| <a name="provider_external"></a> [external](#provider_external) | n/a |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
| --------------------------------------------------------------------------------------------------------------------------- | ----------- |
|
||||
| [external_external.nix-build](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
| ---------------------------------------------------------------------- | --------------------------------------------------- | ------------- | ------- | :------: |
|
||||
| <a name="input_attribute"></a> [attribute](#input_attribute) | the attribute to build, can also be a flake | `string` | n/a | yes |
|
||||
| <a name="input_file"></a> [file](#input_file) | the nix file to evaluate, if not run in flake mode | `string` | `null` | no |
|
||||
| <a name="input_nix_options"></a> [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no |
|
||||
| <a name="input_special_args"></a> [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
| ----------------------------------------------------- | ----------- |
|
||||
| <a name="output_result"></a> [result](#output_result) | n/a |
|
||||
|
||||
<!-- END_TF_DOCS -->
|
|
@ -0,0 +1,17 @@
|
|||
locals {
|
||||
nix_options = jsonencode({
|
||||
options = { for k, v in var.nix_options : k => v }
|
||||
})
|
||||
}
|
||||
data "external" "nix-build" {
|
||||
program = [ "${path.module}/nix-build.sh" ]
|
||||
query = {
|
||||
attribute = var.attribute
|
||||
file = var.file
|
||||
nix_options = local.nix_options
|
||||
special_args = jsonencode(var.special_args)
|
||||
}
|
||||
}
|
||||
output "result" {
|
||||
value = data.external.nix-build.result
|
||||
}
|
57
launch/.terraform/modules/peertube.deploy/terraform/nix-build/nix-build.sh
Executable file
57
launch/.terraform/modules/peertube.deploy/terraform/nix-build/nix-build.sh
Executable file
|
@ -0,0 +1,57 @@
|
|||
#!/usr/bin/env bash
|
||||
set -efu
|
||||
|
||||
declare file attribute nix_options special_args
|
||||
eval "$(jq -r '@sh "attribute=\(.attribute) file=\(.file) nix_options=\(.nix_options) special_args=\(.special_args)"')"
|
||||
if [ "${nix_options}" != '{"options":{}}' ]; then
|
||||
options=$(echo "${nix_options}" | jq -r '.options | to_entries | map("--option \(.key) \(.value)") | join(" ")')
|
||||
else
|
||||
options=""
|
||||
fi
|
||||
if [[ ${special_args-} == "{}" ]]; then
|
||||
# no special arguments, proceed as normal
|
||||
if [[ -n ${file-} ]] && [[ -e ${file-} ]]; then
|
||||
# shellcheck disable=SC2086
|
||||
out=$(nix build --no-link --json $options -f "$file" "$attribute")
|
||||
else
|
||||
# shellcheck disable=SC2086
|
||||
out=$(nix build --no-link --json ${options} "$attribute")
|
||||
fi
|
||||
else
|
||||
if [[ ${file-} != 'null' ]]; then
|
||||
echo "special_args are currently only supported when using flakes!" >&2
|
||||
exit 1
|
||||
fi
|
||||
# pass the args in a pure fashion by extending the original config
|
||||
rest="$(echo "${attribute}" | cut -d "#" -f 2)"
|
||||
# e.g. config_path=nixosConfigurations.aarch64-linux.myconfig
|
||||
config_path="${rest%.config.*}"
|
||||
# e.g. config_attribute=config.system.build.toplevel
|
||||
config_attribute="config.${rest#*.config.}"
|
||||
|
||||
# grab flake nar from error message
|
||||
flake_rel="$(echo "${attribute}" | cut -d "#" -f 1)"
|
||||
# e.g. flake_rel="."
|
||||
flake_dir="$(readlink -f "${flake_rel}")"
|
||||
flake_path="${flake_dir}/flake.nix"
|
||||
flake_json="$(nix flake prefetch "${flake_dir}" --json)"
|
||||
flake_nar="$(echo "$flake_json" | jq -r '.hash')"
|
||||
store_path="$(echo "${flake_json}" | jq -r '.storePath')"
|
||||
# while we have a store path now, for a repo this reflects its root level,
|
||||
# so search for the largest child segment yielding a match in that store dir.
|
||||
iter_path="${flake_path}"
|
||||
while [[ ${iter_path} != "/" ]]; do
|
||||
parent="$(dirname "${iter_path}")"
|
||||
child_segment="${flake_path//$parent/}"
|
||||
if [[ -f "${store_path}${child_segment}" ]]; then
|
||||
target_segment="${child_segment}"
|
||||
fi
|
||||
iter_path="${parent}"
|
||||
done
|
||||
# substitute variables into the template
|
||||
nix_expr="(builtins.getFlake ''file://${flake_dir}?dir=${target_segment//\/flake.nix/}&narHash=${flake_nar}'').${config_path}.extendModules { specialArgs = builtins.fromJSON ''${special_args}''; }"
|
||||
# inject `special_args` into nixos config's `specialArgs`
|
||||
# shellcheck disable=SC2086
|
||||
out=$(nix build --no-link --json ${options} --expr "${nix_expr}" "${config_attribute}")
|
||||
fi
|
||||
printf '%s' "$out" | jq -c '.[].outputs'
|
|
@ -0,0 +1,22 @@
|
|||
variable "attribute" {
|
||||
type = string
|
||||
description = "the attribute to build, can also be a flake"
|
||||
}
|
||||
|
||||
variable "file" {
|
||||
type = string
|
||||
description = "the nix file to evaluate, if not run in flake mode"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "nix_options" {
|
||||
type = map(string)
|
||||
description = "the options of nix"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "special_args" {
|
||||
type = any
|
||||
default = {}
|
||||
description = "A map exposed as NixOS's `specialArgs` thru a file."
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
# Nixos-rebuild
|
||||
|
||||
Update NixOS machine with nixos-rebuild on a remote machine
|
||||
|
||||
## Example
|
||||
|
||||
```hcl
|
||||
locals {
|
||||
ipv4 = "192.0.2.1"
|
||||
}
|
||||
|
||||
module "system-build" {
|
||||
source = "github.com/nix-community/nixos-anywhere//terraform/nix-build"
|
||||
# with flakes
|
||||
attribute = ".#nixosConfigurations.mymachine.config.system.build.toplevel"
|
||||
# without flakes
|
||||
# file can use (pkgs.nixos []) function from nixpkgs
|
||||
#file = "${path.module}/../.."
|
||||
#attribute = "config.system.build.toplevel"
|
||||
}
|
||||
|
||||
module "deploy" {
|
||||
source = "github.com/nix-community/nixos-anywhere//terraform/nixos-rebuild"
|
||||
nixos_system = module.system-build.result.out
|
||||
target_host = local.ipv4
|
||||
}
|
||||
```
|
||||
|
||||
<!-- BEGIN_TF_DOCS -->
|
||||
|
||||
## Requirements
|
||||
|
||||
No requirements.
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
| --------------------------------------------------- | ------- |
|
||||
| <a name="provider_null"></a> [null](#provider_null) | n/a |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
| -------------------------------------------------------------------------------------------------------------------- | -------- |
|
||||
| [null_resource.nixos-rebuild](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
| -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -------- | :------: |
|
||||
| <a name="input_ignore_systemd_errors"></a> [ignore\_systemd\_errors](#input_ignore_systemd_errors) | Ignore systemd errors happening during deploy | `bool` | `false` | no |
|
||||
| <a name="input_nixos_system"></a> [nixos\_system](#input_nixos_system) | The nixos system to deploy | `string` | n/a | yes |
|
||||
| <a name="input_ssh_private_key"></a> [ssh\_private\_key](#input_ssh_private_key) | Content of private key used to connect to the target\_host. If set to - no key is passed to openssh and ssh will use its own configuration | `string` | `"-"` | no |
|
||||
| <a name="input_target_host"></a> [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes |
|
||||
| <a name="input_target_port"></a> [target\_port](#input_target_port) | SSH port used to connect to the target\_host | `number` | `22` | no |
|
||||
| <a name="input_target_user"></a> [target\_user](#input_target_user) | User to deploy as | `string` | `"root"` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
No outputs.
|
||||
|
||||
<!-- END_TF_DOCS -->
|
68
launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/deploy.sh
Executable file
68
launch/.terraform/modules/peertube.deploy/terraform/nixos-rebuild/deploy.sh
Executable file
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -uex -o pipefail
|
||||
|
||||
if [ "$#" -ne 6 ]; then
|
||||
echo "USAGE: $0 NIXOS_SYSTEM TARGET_USER TARGET_HOST TARGET_PORT IGNORE_SYSTEMD_ERRORS INSTALL_BOOTLOADER" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NIXOS_SYSTEM=$1
|
||||
TARGET_USER=$2
|
||||
TARGET_HOST=$3
|
||||
TARGET_PORT=$4
|
||||
IGNORE_SYSTEMD_ERRORS=$5
|
||||
INSTALL_BOOTLOADER=$6
|
||||
|
||||
shift 6
|
||||
|
||||
TARGET="${TARGET_USER}@${TARGET_HOST}"
|
||||
|
||||
workDir=$(mktemp -d)
|
||||
trap 'rm -rf "$workDir"' EXIT
|
||||
|
||||
sshOpts=(-p "${TARGET_PORT}")
|
||||
sshOpts+=(-o UserKnownHostsFile=/dev/null)
|
||||
sshOpts+=(-o StrictHostKeyChecking=no)
|
||||
|
||||
set +x
|
||||
if [[ -n ${SSH_KEY+x} && ${SSH_KEY} != "-" ]]; then
|
||||
sshPrivateKeyFile="$workDir/ssh_key"
|
||||
# Create the file with 0700 - umask calculation: 777 - 700 = 077
|
||||
(
|
||||
umask 077
|
||||
echo "$SSH_KEY" >"$sshPrivateKeyFile"
|
||||
)
|
||||
unset SSH_AUTH_SOCK # don't use system agent if key was supplied
|
||||
sshOpts+=(-o "IdentityFile=${sshPrivateKeyFile}")
|
||||
fi
|
||||
set -x
|
||||
|
||||
try=1
|
||||
until NIX_SSHOPTS="${sshOpts[*]}" nix copy -s --experimental-features nix-command --to "ssh://$TARGET" "$NIXOS_SYSTEM"; do
|
||||
if [[ $try -gt 10 ]]; then
|
||||
echo "retries exhausted" >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 10
|
||||
try=$((try + 1))
|
||||
done
|
||||
|
||||
if [[ $INSTALL_BOOTLOADER == "true" ]]; then
|
||||
extra_env='NIXOS_INSTALL_BOOTLOADER=1'
|
||||
else
|
||||
extra_env=''
|
||||
fi
|
||||
|
||||
switchCommand="nix-env -p /nix/var/nix/profiles/system --set $(printf "%q" "$NIXOS_SYSTEM"); $extra_env /nix/var/nix/profiles/system/bin/switch-to-configuration switch"
|
||||
|
||||
if [[ $TARGET_USER != "root" ]]; then
|
||||
switchCommand="sudo bash -c '$switchCommand'"
|
||||
fi
|
||||
deploy_status=0
|
||||
# shellcheck disable=SC2029
|
||||
ssh "${sshOpts[@]}" "$TARGET" "$switchCommand" || deploy_status="$?"
|
||||
if [[ $IGNORE_SYSTEMD_ERRORS == "true" && $deploy_status == "4" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
exit "$deploy_status"
|
|
@ -0,0 +1,11 @@
|
|||
resource "null_resource" "nixos-rebuild" {
|
||||
triggers = {
|
||||
store_path = var.nixos_system
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
environment = {
|
||||
SSH_KEY = var.ssh_private_key
|
||||
}
|
||||
command = "${path.module}/deploy.sh ${var.nixos_system} ${var.target_user} ${var.target_host} ${var.target_port} ${var.ignore_systemd_errors} ${var.install_bootloader}"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
variable "nixos_system" {
|
||||
type = string
|
||||
description = "The nixos system to deploy"
|
||||
}
|
||||
|
||||
variable "target_host" {
|
||||
type = string
|
||||
description = "DNS host to deploy to"
|
||||
}
|
||||
|
||||
variable "target_user" {
|
||||
type = string
|
||||
default = "root"
|
||||
description = "User to deploy as"
|
||||
}
|
||||
|
||||
variable "target_port" {
|
||||
type = number
|
||||
description = "SSH port used to connect to the target_host"
|
||||
default = 22
|
||||
}
|
||||
|
||||
variable "ssh_private_key" {
|
||||
type = string
|
||||
description = "Content of private key used to connect to the target_host. If set to - no key is passed to openssh and ssh will use its own configuration"
|
||||
default = "-"
|
||||
}
|
||||
|
||||
variable "ignore_systemd_errors" {
|
||||
type = bool
|
||||
description = "Ignore systemd errors happening during deploy"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "install_bootloader" {
|
||||
type = bool
|
||||
description = "Install/re-install the bootloader"
|
||||
default = false
|
||||
}
|
14
launch/.terraform/modules/peertube.deploy/terraform/update-docs.sh
Executable file
14
launch/.terraform/modules/peertube.deploy/terraform/update-docs.sh
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
files=()
|
||||
find "${SCRIPT_DIR}"/* -type d | while read -r i; do
|
||||
module_name=$(basename "$i")
|
||||
markdown_file="${SCRIPT_DIR}/${module_name}.md"
|
||||
terraform-docs --config "${SCRIPT_DIR}/.terraform-docs.yml" markdown table --output-file "${markdown_file}" --output-mode inject "${module_name}"
|
||||
files+=("${markdown_file}")
|
||||
done
|
||||
cd ..
|
||||
nix fmt -- --no-cache
|
|
@ -0,0 +1,33 @@
|
|||
{ withSystem, inputs, ... }:
|
||||
|
||||
{
|
||||
flake.checks.x86_64-linux = withSystem "x86_64-linux" (
|
||||
{
|
||||
pkgs,
|
||||
system,
|
||||
inputs',
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
testInputsUnstable = {
|
||||
inherit pkgs;
|
||||
inherit (inputs.disko.nixosModules) disko;
|
||||
nixos-anywhere = config.packages.nixos-anywhere;
|
||||
kexec-installer = "${inputs'.nixos-images.packages.kexec-installer-nixos-unstable-noninteractive}/nixos-kexec-installer-noninteractive-${system}.tar.gz";
|
||||
};
|
||||
testInputsStable = testInputsUnstable // {
|
||||
kexec-installer = "${inputs'.nixos-images.packages.kexec-installer-nixos-stable-noninteractive}/nixos-kexec-installer-noninteractive-${system}.tar.gz";
|
||||
};
|
||||
in
|
||||
{
|
||||
from-nixos = import ./from-nixos.nix testInputsUnstable;
|
||||
from-nixos-stable = import ./from-nixos.nix testInputsStable;
|
||||
from-nixos-with-sudo = import ./from-nixos-with-sudo.nix testInputsUnstable;
|
||||
from-nixos-with-sudo-stable = import ./from-nixos-with-sudo.nix testInputsStable;
|
||||
from-nixos-with-generated-config = import ./from-nixos-generate-config.nix testInputsUnstable;
|
||||
from-nixos-build-on-remote = import ./from-nixos-build-on-remote.nix testInputsUnstable;
|
||||
from-nixos-separated-phases = import ./from-nixos-separated-phases.nix testInputsUnstable;
|
||||
}
|
||||
);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
(import ./lib/test-base.nix) (
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
name = "from-nixos-build-on-remote";
|
||||
nodes = {
|
||||
installer = ./modules/installer.nix;
|
||||
installed = {
|
||||
services.openssh.enable = true;
|
||||
virtualisation.memorySize = 1024;
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ];
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
def create_test_machine(
|
||||
oldmachine=None, **kwargs
|
||||
): # taken from <nixpkgs/nixos/tests/installer.nix>
|
||||
start_command = [
|
||||
"${pkgs.qemu_test}/bin/qemu-kvm",
|
||||
"-cpu",
|
||||
"max",
|
||||
"-m",
|
||||
"1024",
|
||||
"-virtfs",
|
||||
"local,path=/nix/store,security_model=none,mount_tag=nix-store",
|
||||
"-drive",
|
||||
f"file={oldmachine.state_dir}/installed.qcow2,id=drive1,if=none,index=1,werror=report",
|
||||
"-device",
|
||||
"virtio-blk-pci,drive=drive1",
|
||||
]
|
||||
machine = create_machine(start_command=" ".join(start_command), **kwargs)
|
||||
driver.machines.append(machine)
|
||||
return machine
|
||||
start_all()
|
||||
|
||||
installer.succeed("""
|
||||
nixos-anywhere \
|
||||
-i /root/.ssh/install_key \
|
||||
--debug \
|
||||
--build-on-remote \
|
||||
--kexec /etc/nixos-anywhere/kexec-installer \
|
||||
--store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \
|
||||
root@installed >&2
|
||||
""")
|
||||
try:
|
||||
installed.shutdown()
|
||||
except BrokenPipeError:
|
||||
# qemu has already exited
|
||||
pass
|
||||
new_machine = create_test_machine(oldmachine=installed, name="after_install")
|
||||
new_machine.start()
|
||||
hostname = new_machine.succeed("hostname").strip()
|
||||
assert "nixos-anywhere" == hostname, f"'nixos-anywhere' != '{hostname}'"
|
||||
'';
|
||||
}
|
||||
)
|
|
@ -0,0 +1,71 @@
|
|||
(import ./lib/test-base.nix) {
|
||||
name = "from-nixos-generate-config";
|
||||
nodes = {
|
||||
installer =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
./modules/installer.nix
|
||||
];
|
||||
environment.systemPackages = [ pkgs.jq ];
|
||||
};
|
||||
installed = {
|
||||
services.openssh.enable = true;
|
||||
virtualisation.memorySize = 1024;
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ];
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
installer.fail("test -f /tmp/hw/config.nix")
|
||||
installer.succeed("echo super-secret > /tmp/disk-1.key")
|
||||
output = installer.succeed("""
|
||||
nixos-anywhere \
|
||||
-i /root/.ssh/install_key \
|
||||
--debug \
|
||||
--kexec /etc/nixos-anywhere/kexec-installer \
|
||||
--disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \
|
||||
--disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \
|
||||
--phases kexec,disko \
|
||||
--generate-hardware-config nixos-generate-config /tmp/hw/config.nix \
|
||||
--store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \
|
||||
root@installed >&2
|
||||
echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
|
||||
root@installed cat /tmp/disk-1.key)'"
|
||||
echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
|
||||
root@installed cat /tmp/disk-2.key)'"
|
||||
""")
|
||||
|
||||
installer.succeed("cat /tmp/hw/config.nix >&2")
|
||||
installer.succeed("nix-instantiate --parse /tmp/hw/config.nix")
|
||||
|
||||
assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}"
|
||||
assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}"
|
||||
|
||||
installer.fail("test -f /test/hw/config.json")
|
||||
|
||||
output = installer.succeed("""
|
||||
nixos-anywhere \
|
||||
-i /root/.ssh/install_key \
|
||||
--debug \
|
||||
--kexec /etc/nixos-anywhere/kexec-installer \
|
||||
--disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \
|
||||
--disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \
|
||||
--phases kexec,disko \
|
||||
--generate-hardware-config nixos-facter /tmp/hw/config.json \
|
||||
--store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \
|
||||
installed >&2
|
||||
echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
|
||||
root@installed cat /tmp/disk-1.key)'"
|
||||
echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
|
||||
root@installed cat /tmp/disk-2.key)'"
|
||||
""")
|
||||
|
||||
installer.succeed("cat /tmp/hw/config.json >&2")
|
||||
installer.succeed("jq < /tmp/hw/config.json")
|
||||
|
||||
assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}"
|
||||
assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}"
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
(import ./lib/test-base.nix) {
|
||||
name = "from-nixos-separated-phases";
|
||||
nodes = {
|
||||
installer = ./modules/installer.nix;
|
||||
installed = {
|
||||
services.openssh.enable = true;
|
||||
virtualisation.memorySize = 1024;
|
||||
|
||||
users.users.nixos = {
|
||||
isNormalUser = true;
|
||||
openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ];
|
||||
extraGroups = [ "wheel" ];
|
||||
};
|
||||
security.sudo.enable = true;
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
with subtest("Kexec Phase"):
|
||||
installer.succeed("""
|
||||
nixos-anywhere \
|
||||
-i /root/.ssh/install_key \
|
||||
--debug \
|
||||
--kexec /etc/nixos-anywhere/kexec-installer \
|
||||
--phases kexec \
|
||||
--store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \
|
||||
nixos@installed >&2
|
||||
""")
|
||||
|
||||
with subtest("Disko Phase"):
|
||||
output = installer.succeed("""
|
||||
nixos-anywhere \
|
||||
-i /root/.ssh/install_key \
|
||||
--debug \
|
||||
--phases disko \
|
||||
--store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \
|
||||
installed >&2
|
||||
""")
|
||||
|
||||
with subtest("Install Phase"):
|
||||
installer.succeed("""
|
||||
nixos-anywhere \
|
||||
-i /root/.ssh/install_key \
|
||||
--debug \
|
||||
--phases install \
|
||||
--store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \
|
||||
root@installed >&2
|
||||
""")
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
(import ./lib/test-base.nix) {
|
||||
name = "from-nixos-with-sudo";
|
||||
nodes = {
|
||||
installer = ./modules/installer.nix;
|
||||
installed = {
|
||||
services.openssh.enable = true;
|
||||
virtualisation.memorySize = 1024;
|
||||
|
||||
users.users.nixos = {
|
||||
isNormalUser = true;
|
||||
openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ];
|
||||
extraGroups = [ "wheel" ];
|
||||
};
|
||||
security.sudo.enable = true;
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
installer.succeed("echo super-secret > /tmp/disk-1.key")
|
||||
output = installer.succeed("""
|
||||
nixos-anywhere \
|
||||
-i /root/.ssh/install_key \
|
||||
--debug \
|
||||
--kexec /etc/nixos-anywhere/kexec-installer \
|
||||
--phases kexec,disko \
|
||||
--disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \
|
||||
--disk-encryption-keys /tmp/disk-2.key <(echo another-secret) \
|
||||
--store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \
|
||||
nixos@installed >&2
|
||||
echo "disk-1.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
|
||||
root@installed cat /tmp/disk-1.key)'"
|
||||
echo "disk-2.key: '$(ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
|
||||
root@installed cat /tmp/disk-2.key)'"
|
||||
""")
|
||||
|
||||
assert "disk-1.key: 'super-secret'" in output, f"output does not contain expected values: {output}"
|
||||
assert "disk-2.key: 'another-secret'" in output, f"output does not contain expected values: {output}"
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
(import ./lib/test-base.nix) (
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
name = "from-nixos";
|
||||
nodes = {
|
||||
installer = ./modules/installer.nix;
|
||||
installed = {
|
||||
services.openssh.enable = true;
|
||||
virtualisation.memorySize = 1024;
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keyFiles = [ ./modules/ssh-keys/ssh.pub ];
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
def create_test_machine(
|
||||
oldmachine=None, **kwargs
|
||||
): # taken from <nixpkgs/nixos/tests/installer.nix>
|
||||
start_command = [
|
||||
"${pkgs.qemu_test}/bin/qemu-kvm",
|
||||
"-cpu",
|
||||
"max",
|
||||
"-m",
|
||||
"1024",
|
||||
"-virtfs",
|
||||
"local,path=/nix/store,security_model=none,mount_tag=nix-store",
|
||||
"-drive",
|
||||
f"file={oldmachine.state_dir}/installed.qcow2,id=drive1,if=none,index=1,werror=report",
|
||||
"-device",
|
||||
"virtio-blk-pci,drive=drive1",
|
||||
]
|
||||
machine = create_machine(start_command=" ".join(start_command), **kwargs)
|
||||
driver.machines.append(machine)
|
||||
return machine
|
||||
start_all()
|
||||
installer.succeed("mkdir -p /tmp/extra-files/var/lib/secrets")
|
||||
installer.succeed("echo value > /tmp/extra-files/var/lib/secrets/key")
|
||||
installer.succeed("mkdir -p /tmp/extra-files/home/user/.ssh")
|
||||
installer.succeed("echo secretkey > /tmp/extra-files/home/user/.ssh/id_ed25519")
|
||||
installer.succeed("echo publickey > /tmp/extra-files/home/user/.ssh/id_ed25519.pub")
|
||||
installer.succeed("chmod 600 /tmp/extra-files/home/user/.ssh/id_ed25519")
|
||||
ssh_key_path = "/etc/ssh/ssh_host_ed25519_key.pub"
|
||||
ssh_key_output = installer.wait_until_succeeds(f"""
|
||||
ssh -i /root/.ssh/install_key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
|
||||
root@installed cat {ssh_key_path}
|
||||
""")
|
||||
installer.succeed("""
|
||||
nixos-anywhere \
|
||||
-i /root/.ssh/install_key \
|
||||
--debug \
|
||||
--kexec /etc/nixos-anywhere/kexec-installer \
|
||||
--extra-files /tmp/extra-files \
|
||||
--store-paths /etc/nixos-anywhere/disko /etc/nixos-anywhere/system-to-install \
|
||||
--chown /home/user 1000:100 \
|
||||
--copy-host-keys \
|
||||
root@installed >&2
|
||||
""")
|
||||
try:
|
||||
installed.shutdown()
|
||||
except BrokenPipeError:
|
||||
# qemu has already exited
|
||||
pass
|
||||
new_machine = create_test_machine(oldmachine=installed, name="after_install")
|
||||
new_machine.start()
|
||||
hostname = new_machine.succeed("hostname").strip()
|
||||
assert "nixos-anywhere" == hostname, f"'nixos-anywhere' != '{hostname}'"
|
||||
content = new_machine.succeed("cat /var/lib/secrets/key").strip()
|
||||
assert "value" == content, f"secret does not have expected value: {content}"
|
||||
ssh_key_content = new_machine.succeed(f"cat {ssh_key_path}").strip()
|
||||
assert ssh_key_content in ssh_key_output, "SSH host identity changed"
|
||||
priv_key_perms = new_machine.succeed("stat -c %a /home/user/.ssh/id_ed25519").strip()
|
||||
assert priv_key_perms == "600", f"unexpected permissions for private key: {priv_key_perms}"
|
||||
user_dir_ownership = new_machine.succeed("stat -c %u:%g /home/user").strip()
|
||||
assert user_dir_ownership == "1000:100", f"unexpected user home dir permissions: {user_dir_ownership}"
|
||||
'';
|
||||
}
|
||||
)
|
|
@ -0,0 +1,20 @@
|
|||
test:
|
||||
{
|
||||
pkgs ? import <nixpkgs> { },
|
||||
nixos-anywhere ? pkgs.callPackage ../../src { },
|
||||
disko ? "${builtins.fetchTarball "https://github.com/nix-community/disko/archive/master.tar.gz"}/module.nix",
|
||||
kexec-installer ? builtins.fetchurl "https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-${pkgs.stdenv.hostPlatform.system}.tar.gz",
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
nixos-lib = import (pkgs.path + "/nixos/lib") { };
|
||||
in
|
||||
(nixos-lib.runTest {
|
||||
hostPkgs = pkgs;
|
||||
# speed-up evaluation
|
||||
defaults.documentation.enable = lib.mkDefault false;
|
||||
# to accept external dependencies such as disko
|
||||
node.specialArgs.inputs = { inherit nixos-anywhere disko kexec-installer; };
|
||||
imports = [ test ];
|
||||
}).config.result
|
|
@ -0,0 +1,22 @@
|
|||
{ pkgs, inputs, ... }:
|
||||
let
|
||||
disko = inputs.disko;
|
||||
kexec-installer = inputs.kexec-installer;
|
||||
system-to-install = pkgs.nixos [
|
||||
./system-to-install.nix
|
||||
disko
|
||||
];
|
||||
in
|
||||
{
|
||||
system.activationScripts.rsa-key = ''
|
||||
${pkgs.coreutils}/bin/install -D -m600 ${./ssh-keys/ssh} /root/.ssh/install_key
|
||||
'';
|
||||
|
||||
environment.systemPackages = [ inputs.nixos-anywhere ];
|
||||
|
||||
environment.etc = {
|
||||
"nixos-anywhere/disko".source = system-to-install.config.system.build.diskoScriptNoDeps;
|
||||
"nixos-anywhere/system-to-install".source = system-to-install.config.system.build.toplevel;
|
||||
"nixos-anywhere/kexec-installer".source = kexec-installer;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACDM4kPg4V7DMYceuA8VIUdBvw30gM9qagERA8v1VGBBBQAAAJDpULAq6VCw
|
||||
KgAAAAtzc2gtZWQyNTUxOQAAACDM4kPg4V7DMYceuA8VIUdBvw30gM9qagERA8v1VGBBBQ
|
||||
AAAECpjfl5WMMIDvEyZJTeXzRNFzpDpj4fqdIXHZauKAlE5MziQ+DhXsMxhx64DxUhR0G/
|
||||
DfSAz2pqAREDy/VUYEEFAAAACWxhc3NAbW9ycwECAwQ=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
|
@ -0,0 +1 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMziQ+DhXsMxhx64DxUhR0G/DfSAz2pqAREDy/VUYEEF
|
|
@ -0,0 +1,47 @@
|
|||
{ modulesPath, self, ... }:
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/testing/test-instrumentation.nix")
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
(modulesPath + "/profiles/minimal.nix")
|
||||
];
|
||||
networking.hostName = "nixos-anywhere";
|
||||
documentation.enable = false;
|
||||
hardware.enableAllFirmware = false;
|
||||
networking.hostId = "8425e349"; # from profiles/base.nix, needed for zfs
|
||||
boot.zfs.devNodes = "/dev/disk/by-uuid"; # needed because /dev/disk/by-id is empty in qemu-vms
|
||||
disko.devices = {
|
||||
disk = {
|
||||
vda = {
|
||||
device = "/dev/vda";
|
||||
type = "disk";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02";
|
||||
};
|
||||
ESP = {
|
||||
size = "100M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "ext4";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.treefmt-nix.flakeModule
|
||||
];
|
||||
perSystem =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
treefmt = {
|
||||
projectRootFile = "flake.nix";
|
||||
programs.mdsh.enable = true;
|
||||
programs.nixpkgs-fmt.enable = true;
|
||||
programs.shellcheck.enable = true;
|
||||
programs.shfmt.enable = true;
|
||||
programs.deno.enable = !pkgs.deno.meta.broken;
|
||||
settings.formatter.shellcheck.options = [
|
||||
"-s"
|
||||
"bash"
|
||||
];
|
||||
};
|
||||
formatter = config.treefmt.build.wrapper;
|
||||
};
|
||||
}
|
23
launch/.terraform/modules/pixelfed.deploy/CONTRIBUTING.md
Normal file
23
launch/.terraform/modules/pixelfed.deploy/CONTRIBUTING.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
To run `nixos-anywhere` from the repo:
|
||||
|
||||
```console
|
||||
nix run . -- --help
|
||||
```
|
||||
|
||||
To format the code:
|
||||
|
||||
```console
|
||||
nix fmt
|
||||
```
|
||||
|
||||
To run all tests:
|
||||
|
||||
```console
|
||||
nix flake check -vL
|
||||
```
|
||||
|
||||
To run an individual test:
|
||||
|
||||
```
|
||||
nix build .#checks.x86_64-linux.from-nixos -vL
|
||||
```
|
21
launch/.terraform/modules/pixelfed.deploy/LICENSE
Normal file
21
launch/.terraform/modules/pixelfed.deploy/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 Numtide
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
123
launch/.terraform/modules/pixelfed.deploy/README.md
Normal file
123
launch/.terraform/modules/pixelfed.deploy/README.md
Normal file
|
@ -0,0 +1,123 @@
|
|||
# nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" width="150" height="150">
|
||||
|
||||
[Documentation Index](docs/INDEX.md)
|
||||
|
||||
## README
|
||||
|
||||
Setting up a new machine is time-consuming, and becomes complicated when it
|
||||
needs to be done remotely. If you're installing NixOS, the **nixos-anywhere**
|
||||
tool allows you to pre-configure the whole process including:
|
||||
|
||||
- Disk partitioning and formatting
|
||||
- Configuring and installing NixOS
|
||||
- Installing additional files and software
|
||||
|
||||
You can then initiate an unattended installation with a single CLI command.
|
||||
Since **nixos-anywhere** can access the new machine using SSH, it's ideal for
|
||||
remote installations.
|
||||
|
||||
Once you have initiated the command, there is no need to 'babysit' the
|
||||
installation. It all happens automatically.
|
||||
|
||||
You can use the stored configuration to repeat the same installation if you need
|
||||
to.
|
||||
|
||||
## Overview
|
||||
|
||||
If you have machines on a mix of platforms, you'll need a common installation
|
||||
solution that works anywhere. **nixos-anywhere** is ideal in this situation.
|
||||
|
||||
**nixos-anywhere** can be used equally well for cloud servers, bare metal
|
||||
servers such as Hetzner, and local servers accessible via a LAN. You can create
|
||||
standard configurations, and use the same configuration to create identical
|
||||
servers anywhere.
|
||||
|
||||
You first create Nix configurations to specify partitioning, formatting and
|
||||
NixOS configurations. Further options can be controlled by a flake and by
|
||||
run-time switches.
|
||||
|
||||
Once the configuration has been created, a single command will:
|
||||
|
||||
- Connect to the remote server via SSH
|
||||
- Detect whether a NixOS installer is present; if not, it will use the Linux
|
||||
`kexec` tool to boot into a Nixos installer.
|
||||
- Use the [disko](https://github.com/nix-community/disko) tool to partition and
|
||||
format the hard drive
|
||||
- Install NixOS
|
||||
- Optionally install any Nix packages and other software required.
|
||||
- Optionally copy additional files to the new machine
|
||||
|
||||
It's also possible to use **nixos-anywhere** to simplify the installation on a
|
||||
machine that has no current operating system, first booting from a NixOS
|
||||
installer image. This feature is described in the
|
||||
[how-to guide](./docs/howtos/no-os.md#installing-on-a-machine-with-no-operating-system).
|
||||
It's useful because you can pre-configure your required software and
|
||||
preferences, and build the new machine with a single command.
|
||||
|
||||
**Important Note:** Never use a production server as the target. It will be
|
||||
completely overwritten and all data lost. This tool should only be used for
|
||||
commissioning a new computer or repurposing an old machine once all important
|
||||
data has been migrated.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Source Machine:
|
||||
|
||||
- Can be any machine with Nix installed, e.g. a NixOS machine.
|
||||
|
||||
- Target Machine:
|
||||
|
||||
- Unless you're using the option to boot from a NixOS installer image, or
|
||||
providing your own `kexec` image, it must be running x86-64 Linux with kexec
|
||||
support. Most `x86_64` Linux systems do have kexec support. By providing
|
||||
your own [image](./docs/howtos/custom-kexec.md#using-your-own-kexec-image)
|
||||
you can also perform kexec for other architectures eg aarch64
|
||||
- The machine must be reachable over the public internet or local network.
|
||||
Nixos-anywhere does not support wifi networks. If a VPN is needed, define a
|
||||
custom installer via the --kexec flag which connects to your VPN.
|
||||
- When `kexec` is used the target must have at least 1 GB of RAM, excluding
|
||||
swap.
|
||||
|
||||
## How to use nixos-anywhere
|
||||
|
||||
The [Quickstart Guide](./docs/quickstart.md) gives more information on how to
|
||||
run **nixos-anywhere** in its simplest form. For more specific instructions to
|
||||
suit individual requirements, see the [How To Guide](./docs/howtos/INDEX.md).
|
||||
|
||||
## Related Tools
|
||||
|
||||
**nixos-anywhere** makes use of the
|
||||
[disko](https://github.com/nix-community/disko) tool to handle the partitioning
|
||||
and formatting of the disks.
|
||||
|
||||
## Contact
|
||||
|
||||
For questions, come join us in the
|
||||
[nixos-anywhere](https://matrix.to/#/#nixos-anywhere:nixos.org) matrix room.
|
||||
|
||||
## Licensing and Contribution details
|
||||
|
||||
This software is provided free under the
|
||||
[MIT License](https://opensource.org/licenses/MIT).
|
||||
|
||||
---
|
||||
|
||||
This project is supported by [Numtide](https://numtide.com/).
|
||||

|
||||
|
||||
We are a team of independent freelancers that love open source. We help our
|
||||
customers make their project lifecycles more efficient by:
|
||||
|
||||
- Providing and supporting useful tools such as this one
|
||||
- Building and deploying infrastructure, and offering dedicated DevOps support
|
||||
- Building their in-house Nix skills, and integrating Nix with their workflows
|
||||
- Developing additional features and tools
|
||||
- Carrying out custom research and development.
|
||||
|
||||
[Contact us](https://numtide.com/contact) if you have a project in mind, or if
|
||||
you need help with any of our supported tools, including this one. We'd love to
|
||||
hear from you.
|
11
launch/.terraform/modules/pixelfed.deploy/docs/INDEX.md
Normal file
11
launch/.terraform/modules/pixelfed.deploy/docs/INDEX.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Table of Content: - nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img title="" src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" alt="" width="149">
|
||||
|
||||
- [README](../README.md)
|
||||
- [Quickstart](./quickstart.md)
|
||||
- [System Requirements](./requirements.md)
|
||||
- [How to Guide](./howtos/INDEX.md)
|
||||
- [Reference](./reference.md)
|
26
launch/.terraform/modules/pixelfed.deploy/docs/SUMMARY.md
Normal file
26
launch/.terraform/modules/pixelfed.deploy/docs/SUMMARY.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Summary: - nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img title="" src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" alt="" width="149">
|
||||
|
||||
The **nixos-anywhere** tool allows you to pre-configure the whole process of
|
||||
installing NixOS, and run the install remotely with a single CLI command.
|
||||
|
||||
Refer to the following documentation for more information.
|
||||
|
||||
[System Requirements](./requirements.md): CPU and memory requirements
|
||||
|
||||
[Quickstart](./quickstart.md): Instructions for a typical installation
|
||||
|
||||
[How to Guide](./howtos/INDEX.md): Instructions for non-typical use cases
|
||||
|
||||
- [Installing on a machine with no operating system](./howtos/no-os.md)
|
||||
- [Using your own kexec image](./howtos/custom-kexec.md)
|
||||
- [Secrets and full disk encryption](./howtos/secrets.md)
|
||||
- [Use without flakes](./howtos/use-without-flakes.md)
|
||||
- [Terraform](./howtos/terraform.md)
|
||||
- [Nix-channels / `NIX_PATH`](./howtos/nix-path.md)
|
||||
- [IPv6-only targets](./howtos/ipv6.md)
|
||||
|
||||
[Reference](./reference.md): Reference Guide
|
6
launch/.terraform/modules/pixelfed.deploy/docs/book.toml
Normal file
6
launch/.terraform/modules/pixelfed.deploy/docs/book.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[book]
|
||||
authors = [ ]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "."
|
||||
title = "nixos-anywhere - install NixOS everywhere"
|
63
launch/.terraform/modules/pixelfed.deploy/docs/cli.md
Normal file
63
launch/.terraform/modules/pixelfed.deploy/docs/cli.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
# CLI
|
||||
|
||||
```
|
||||
Usage: nixos-anywhere [options] [<ssh-host>]
|
||||
|
||||
Options:
|
||||
|
||||
* -f, --flake <flake_uri>
|
||||
set the flake to install the system from.
|
||||
* --target-host <ssh-host>
|
||||
specified the SSH target host to deploy onto.
|
||||
* -i <identity_file>
|
||||
selects which SSH private key file to use.
|
||||
* -p, --ssh-port <ssh_port>
|
||||
set the ssh port to connect with
|
||||
* --ssh-option <ssh_option>
|
||||
set an ssh option
|
||||
* -L, --print-build-logs
|
||||
print full build logs
|
||||
* --env-password
|
||||
set a password used by ssh-copy-id, the password should be set by
|
||||
the environment variable SSHPASS
|
||||
* -s, --store-paths <disko-script> <nixos-system>
|
||||
set the store paths to the disko-script and nixos-system directly
|
||||
if this is given, flake is not needed
|
||||
* --no-reboot
|
||||
do not reboot after installation, allowing further customization of the target installation.
|
||||
* --kexec <path>
|
||||
use another kexec tarball to bootstrap NixOS
|
||||
* --kexec-extra-flags
|
||||
extra flags to add into the call to kexec, e.g. "--no-sync"
|
||||
* --ssh-store-setting <key> <value>
|
||||
ssh store settings appended to the store URI, e.g. "compress true". <value> needs to be URI encoded.
|
||||
* --post-kexec-ssh-port <ssh_port>
|
||||
after kexec is executed, use a custom ssh port to connect. Defaults to 22
|
||||
* --copy-host-keys
|
||||
copy over existing /etc/ssh/ssh_host_* host keys to the installation
|
||||
* --stop-after-disko
|
||||
exit after disko formatting, you can then proceed to install manually or some other way
|
||||
* --extra-files <path>
|
||||
contents of local <path> are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten
|
||||
Copied files will be owned by root. See documentation for details.
|
||||
* --disk-encryption-keys <remote_path> <local_path>
|
||||
copy the contents of the file or pipe in local_path to remote_path in the installer environment,
|
||||
after kexec but before installation. Can be repeated.
|
||||
* --no-substitute-on-destination
|
||||
disable passing --substitute-on-destination to nix-copy
|
||||
* --debug
|
||||
enable debug output
|
||||
* --option <key> <value>
|
||||
nix option to pass to every nix related command
|
||||
* --from <store-uri>
|
||||
URL of the source Nix store to copy the nixos and disko closure from
|
||||
* --build-on-remote
|
||||
build the closure on the remote machine instead of locally and copy-closuring it
|
||||
* --vm-test
|
||||
build the system and test the disk configuration inside a VM without installing it to the target.
|
||||
* --build-on auto|remote|local
|
||||
sets the build on settings to auto, remote or local. Default is auto.
|
||||
auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build
|
||||
local: will build on the local host
|
||||
remote: will build on the remote host
|
||||
```
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
perSystem =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
packages.docs =
|
||||
pkgs.runCommand "nixos-anywhere-docs"
|
||||
{
|
||||
passthru.serve = pkgs.writeShellScriptBin "serve" ''
|
||||
set -euo pipefail
|
||||
cd docs
|
||||
workdir=$(${pkgs.coreutils}/bin/mktemp -d)
|
||||
trap 'rm -rf "$workdir"' EXIT
|
||||
${pkgs.mdbook}/bin/mdbook serve --dest-dir "$workdir"
|
||||
'';
|
||||
}
|
||||
''
|
||||
cp -r ${lib.cleanSource ./.}/* .
|
||||
${pkgs.mdbook}/bin/mdbook build --dest-dir "$out"
|
||||
'';
|
||||
};
|
||||
}
|
1
launch/.terraform/modules/pixelfed.deploy/docs/howtos.md
Normal file
1
launch/.terraform/modules/pixelfed.deploy/docs/howtos.md
Normal file
|
@ -0,0 +1 @@
|
|||
# How to Guide
|
|
@ -0,0 +1,29 @@
|
|||
# How To Guide: nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img title="" src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" alt="" width="129">
|
||||
|
||||
[Documentation Index](./INDEX.md)
|
||||
|
||||
## Contents
|
||||
|
||||
[Installing on a machine with no operating system](./no-os.md)
|
||||
|
||||
[Kexec on systems with limited RAM](./limited-ram.md)
|
||||
|
||||
[Copying files to the new installation](./extra-files.md)
|
||||
|
||||
[Using your own kexec image](./custom-kexec.md)
|
||||
|
||||
[Repair installations without wiping data](./disko-modes.md)
|
||||
|
||||
[Secrets and full disk encryption](./secrets.md)
|
||||
|
||||
[Use without flakes](./use-without-flakes.md)
|
||||
|
||||
[Terraform](./terraform.md)
|
||||
|
||||
[Nix-channels / `NIX_PATH`](./nix-path.md)
|
||||
|
||||
[IPv6-only targets](./ipv6.md)
|
|
@ -0,0 +1,40 @@
|
|||
# Using your own kexec image
|
||||
|
||||
By default, `nixos-anywhere` downloads the kexec image from the
|
||||
[NixOS images repository](https://github.com/nix-community/nixos-images#kexec-tarballs).
|
||||
|
||||
However, you can provide your own `kexec` image file if you need to use a
|
||||
different one. This is particularly useful for architectures other than `x86_64`
|
||||
and `aarch64`, since they don't have a pre-build image.
|
||||
|
||||
To do this, use the `--kexec` command line switch followed by the path to your
|
||||
image file. The image will be uploaded prior to execution.
|
||||
|
||||
Here's an example command that demonstrates how to use a custom kexec image with
|
||||
`nixos-anywhere`:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- \
|
||||
--kexec "$(nix build --print-out-paths github:nix-community/nixos-images#packages.aarch64-linux.kexec-installer-nixos-unstable-noninteractive)/nixos-kexec-installer-noninteractive-aarch64-linux.tar.gz" \
|
||||
--flake 'github:your-user/your-repo#your-system' \
|
||||
root@yourip
|
||||
```
|
||||
|
||||
Make sure to replace `github:your-user/your-repo#your-system` with the
|
||||
appropriate Flake URL representing your NixOS configuration.
|
||||
|
||||
The example above assumes that your local machine can build for aarch64 in one
|
||||
of the following ways:
|
||||
|
||||
- Natively
|
||||
|
||||
- Through a remote builder
|
||||
|
||||
- By emulating the architecture with qemu using the following NixOS
|
||||
configuration:
|
||||
|
||||
```nix
|
||||
{
|
||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
||||
}
|
||||
```
|
|
@ -0,0 +1,19 @@
|
|||
# Repair installations without wiping data
|
||||
|
||||
By default, nixos-anywhere will reformat all configured disks before running the
|
||||
installation. However it is also possible to mount the filesystems of an
|
||||
existing installation and run `nixos-install`. This is useful to recover from a
|
||||
misconfigured NixOS installation by first booting into a NixOS installer or
|
||||
recovery system.
|
||||
|
||||
To only mount existing filesystems, add `--disko-mode mount` to
|
||||
`nixos-anywhere`:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --disko-mode mount --flake <path to configuration>#<configuration name> --target-host root@<ip address>
|
||||
```
|
||||
|
||||
1. This will first boot into a nixos-installer
|
||||
2. Mounts disks with disko
|
||||
3. Runs nixos-install based on the provided flake
|
||||
4. Reboots the machine.
|
|
@ -0,0 +1,114 @@
|
|||
# Copying files to the new installation
|
||||
|
||||
The `--extra-files <path>` option allows copying files to the target host after
|
||||
installation.
|
||||
|
||||
The contents of the `<path>` is recursively copied and overwrites the targets
|
||||
root (/). The contents _must_ be in a structure and permissioned as it should be
|
||||
on the target.
|
||||
|
||||
In this way, there is no need to repeatedly pass arguments (eg: a fictional
|
||||
argument: `--copy <source> <dest>`) to `nixos-anywhere` to complete the intended
|
||||
outcome.
|
||||
|
||||
The path and directory structure passed to `--extra-files` should be prepared
|
||||
beforehand.
|
||||
|
||||
This allows a simple programmatic invocation of `nixos-anywhere` for multiple
|
||||
hosts.
|
||||
|
||||
## Simple Example
|
||||
|
||||
You want `/etc/ssh/ssh_host_*` and `/persist` from the local system on the
|
||||
target. The `<path>` contents will look like this:
|
||||
|
||||
```console
|
||||
$ cd /tmp
|
||||
$ root=$(mktemp -d)
|
||||
$ sudo cp --verbose --archive --parents /etc/ssh/ssh_host_* ${root}
|
||||
$ cp --verbose --archive --link /persist ${root}
|
||||
```
|
||||
|
||||
The directory structure would look like this:
|
||||
|
||||
```console
|
||||
drwx------ myuser1 users 20 tmp.d6nx5QUwPN
|
||||
drwxr-xr-x root root 6 ├── etc
|
||||
drwx------ myuser1 users 160 │ └── ssh
|
||||
.rw------- root root 399 │ ├── ssh_host_ed25519_key
|
||||
.rw-r--r-- root root 91 │ ├── ssh_host_ed25519_key.pub
|
||||
drwxr-xr-x myuser1 users 22 └── persist
|
||||
drwxr-xr-x myuser1 users 14 ├── all
|
||||
drwxr-xr-x myuser1 users 22 │ ├── my
|
||||
.rw-r--r-- myuser1 users 6 │ │ ├── test3
|
||||
drwxr-xr-x myuser1 users 10 │ │ └── things
|
||||
.rw-r--r-- myuser1 users 6 │ │ └── test4
|
||||
.rw-r--r-- myuser1 users 6 │ └── test2
|
||||
drwxr-xr-x myuser1 users 0 ├── blah
|
||||
.rw-r--r-- myuser1 users 6 └── test
|
||||
```
|
||||
|
||||
**NOTE**: Permissions will be copied, but ownership on the target will be root.
|
||||
|
||||
Then pass $root like:
|
||||
|
||||
> nixos-anywhere --flake ".#" --extra-files $root --target-host root@newhost
|
||||
|
||||
## Programmatic Example
|
||||
|
||||
```sh
|
||||
for host in host1 host2 host3; do
|
||||
root="target/${host}"
|
||||
install -d -m755 ${root}/etc/ssh
|
||||
ssh-keygen -A -C root@${host} -f ${root}
|
||||
nixos-anywhere --extra-files "${root}" --flake ".#${host}" --target-host "root@${host}"
|
||||
done
|
||||
```
|
||||
|
||||
## Considerations
|
||||
|
||||
### Ownership
|
||||
|
||||
The new system may have differing UNIX user and group id's for users created
|
||||
during installation.
|
||||
|
||||
When the files are extracted on the remote the copied data will be owned by
|
||||
root.
|
||||
|
||||
If you wish to change the ownership after the files are copied onto the system,
|
||||
you can use the `--chown` option.
|
||||
|
||||
For example, if you did `--chown /home/myuser/.ssh 1000:100`, this would equate
|
||||
to running `chown -R /home/myuser/.ssh 1000:100` where the uid is 1000 and the
|
||||
gid is 100. **Only do this when you can _guarantee_ what the uid and gid will
|
||||
be.**
|
||||
|
||||
### Symbolic Links
|
||||
|
||||
Do not create symbolic links to reference data to copy.
|
||||
|
||||
GNU `tar` is used to do the copy over ssh. It is an archival tool used to
|
||||
re/store directory structures as is. Thus `tar` copies symbolic links created
|
||||
with `ln -s` by default. It does not follow them to copy the underlying file.
|
||||
|
||||
### Hard links
|
||||
|
||||
**NOTE**: hard links can only be created on the same filesystem.
|
||||
|
||||
If you have larger persistent data to copy to the target. GNU `tar` will copy
|
||||
data referenced by hard links created with `ln`. A hard link does not create
|
||||
another copy the data.
|
||||
|
||||
To copy a directory tree to the new target you can use the `cp` command with the
|
||||
`--link` option which creates hard links.
|
||||
|
||||
#### Example
|
||||
|
||||
```sh
|
||||
cd /tmp
|
||||
root=$(mktemp -d)
|
||||
cp --verbose --archive --link --parents /persist/home/myuser ${root}
|
||||
```
|
||||
|
||||
`--parents` will create the directory structure of the source at the
|
||||
destination.
|
|
@ -0,0 +1,23 @@
|
|||
# NixOS-anywhere on IPv6-only targets
|
||||
|
||||
As GitHub engineers still haven't enabled the IPv6 switch, the kexec image
|
||||
hosted on GitHub, cannot be used unfortunately on IPv6-only hosts. However it is
|
||||
possible to use an IPv6 proxy for GitHub content like that:
|
||||
|
||||
```
|
||||
nixos-anywhere \
|
||||
--kexec https://gh-v6.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \
|
||||
...
|
||||
```
|
||||
|
||||
This proxy is hosted by [numtide](https://numtide.com/). It also works for IPv4.
|
||||
|
||||
Alternatively it is also possible to reference a local file:
|
||||
|
||||
```
|
||||
nixos-anywhere \
|
||||
--kexec ./nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz \
|
||||
...
|
||||
```
|
||||
|
||||
This tarball will be then uploaded via sftp to the target.
|
|
@ -0,0 +1,29 @@
|
|||
# Kexec on Systems with Limited RAM
|
||||
|
||||
When working with nixos-anywhere on systems with limited RAM (around 1GB), you
|
||||
can use the `--no-disko-deps` option to reduce memory usage during installation.
|
||||
|
||||
## How it works
|
||||
|
||||
The `--no-disko-deps` option uploads only the disko partitioning script without
|
||||
including its dependencies. This significantly reduces memory usage because:
|
||||
|
||||
1. The installer normally stores all dependencies in memory
|
||||
2. Partitioning tools can be quite large when bundled with their dependencies
|
||||
|
||||
## Usage example
|
||||
|
||||
```bash
|
||||
nix run github:nix-community/nixos-anywhere -- --no-disko-deps --flake <path to configuration>#<configuration name> --target-host root@<ip address>
|
||||
```
|
||||
|
||||
## Trade-off
|
||||
|
||||
While this approach saves memory, it means the partitioning tools will be
|
||||
whatever versions are available on the target system, rather than the specific
|
||||
versions defined in your NixOS configuration. This could potentially lead to
|
||||
version inconsistencies between the partitioning tools and the NixOS system
|
||||
being installed.
|
||||
|
||||
This trade-off is usually acceptable for memory-constrained environments where
|
||||
installation would otherwise fail due to insufficient RAM.
|
|
@ -0,0 +1,57 @@
|
|||
# Nix-channels / `NIX_PATH`
|
||||
|
||||
nixos-anywhere does not install channels onto the new system by default to save
|
||||
time and disk space. This for example results in errors like:
|
||||
|
||||
```
|
||||
(stack trace truncated; use '--show-trace' to show the full trace)
|
||||
|
||||
error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)
|
||||
|
||||
at «none»:0: (source not available)
|
||||
```
|
||||
|
||||
when using tools like nix-shell/nix-env that rely on `NIX_PATH` being set.
|
||||
|
||||
# Solution 1: Set the `NIX_PATH` via nixos configuration (recommended)
|
||||
|
||||
Instead of stateful channels, one can also populate the `NIX_PATH` using nixos
|
||||
configuration instead:
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
# ... other inputs
|
||||
|
||||
outputs = inputs@{ nixpkgs, ... }:
|
||||
{
|
||||
nixosConfigurations.yoursystem = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux"; # adapt to your actual system
|
||||
modules = [
|
||||
# This line will populate NIX_PATH
|
||||
{ nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; }
|
||||
# ... other modules and your configuration.nix
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Advantage: This solution will be automatically kept up-to-date every time the
|
||||
flake is updated.
|
||||
|
||||
In your shell you will see something in your `$NIX_PATH`:
|
||||
|
||||
```shellSession
|
||||
$ echo $NIX_PATH
|
||||
/root/.nix-defexpr/channels:nixpkgs=/nix/store/8b61j28rpy11dg8hanbs2x710d8w3v0d-source
|
||||
```
|
||||
|
||||
# Solution 2: Manually add the channel
|
||||
|
||||
On the installed machine, run:
|
||||
|
||||
```shellSession
|
||||
$ nix-channel --add https://nixos.org/channels/nixos-unstable nixos
|
||||
$ nix-channel --update
|
||||
```
|
|
@ -0,0 +1,71 @@
|
|||
# Installing on a machine with no operating system
|
||||
|
||||
If your machine doesn't currently have an operating system installed, you can
|
||||
still run `nixos-anywhere` remotely to automate the install. To do this, you
|
||||
would first need to boot the target machine from the standard NixOS installer.
|
||||
You can either boot from a USB or use `netboot`.
|
||||
|
||||
The
|
||||
[NixOS installation guide](https://nixos.org/manual/nixos/stable/index.html#sec-booting-from-usb)
|
||||
has detailed instructions on how to boot the installer.
|
||||
|
||||
When you run `nixos-anywhere`, it will determine whether a NixOS installer is
|
||||
present by checking whether the `/etc/os-release` file contains the identifier
|
||||
`VARIANT_ID=installer`. This identifier is available on releases NixOS 23.05 or
|
||||
later.
|
||||
|
||||
If an installer is detected, `nixos-anywhere` will not attempt to `kexec` into
|
||||
its own image. This is particularly useful for targets that don't have enough
|
||||
RAM for `kexec` or don't support `kexec`.
|
||||
|
||||
NixOS starts an SSH server on the installer by default, but you need to set a
|
||||
password in order to access it. To set a password for the `nixos` user, run the
|
||||
following command in a terminal on the NixOS machine:
|
||||
|
||||
```
|
||||
passwd
|
||||
```
|
||||
|
||||
If you don't know the IP address of the installer on your network, you can find
|
||||
it by running the following command:
|
||||
|
||||
```
|
||||
$ ip addr
|
||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
|
||||
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
||||
inet 127.0.0.1/8 scope host lo
|
||||
valid_lft forever preferred_lft forever
|
||||
inet6 ::1/128 scope host
|
||||
valid_lft forever preferred_lft forever
|
||||
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
||||
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
|
||||
altname enp0s3
|
||||
altname ens3
|
||||
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0
|
||||
valid_lft 86385sec preferred_lft 75585sec
|
||||
inet6 fec0::5054:ff:fe12:3456/64 scope site dynamic mngtmpaddr noprefixroute
|
||||
valid_lft 86385sec preferred_lft 14385sec
|
||||
inet6 fe80::5054:ff:fe12:3456/64 scope link
|
||||
valid_lft forever preferred_lft forever
|
||||
```
|
||||
|
||||
This will display the IP addresses assigned to your network interface(s),
|
||||
including the IP address of the installer. In the example output below, the
|
||||
installer's IP addresses are `10.0.2.15`, `fec0::5054:ff:fe12:3456`, and
|
||||
`fe80::5054:ff:fe12:3456%eth0`:
|
||||
|
||||
To test if you can connect and your password works, you can use the following
|
||||
SSH command (replace the IP address with your own):
|
||||
|
||||
```
|
||||
ssh -v nixos@fec0::5054:ff:fe12:3456
|
||||
```
|
||||
|
||||
You can then use the IP address to run `nixos-anywhere` like this:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --flake '.#myconfig' --target-host nixos@fec0::5054:ff:fe12:3456
|
||||
```
|
||||
|
||||
This example assumes a flake in the current directory containing a configuration
|
||||
named `myconfig`.
|
|
@ -0,0 +1,76 @@
|
|||
# Secrets and full disk encryption
|
||||
|
||||
The `nixos-anywhere` utility offers the capability to install secrets onto a
|
||||
target machine. This feature is particularly beneficial when you want to
|
||||
bootstrap secrets management tools such as
|
||||
[sops-nix](https://github.com/Mic92/sops-nix) or
|
||||
[agenix](https://github.com/ryantm/agenix), which rely on machine-specific
|
||||
secrets to decrypt other uploaded secrets.
|
||||
|
||||
## Example: Decrypting an OpenSSH Host Key with pass
|
||||
|
||||
In this example, we demonstrate how to use a script to decrypt an OpenSSH host
|
||||
key from the `pass` password manager and subsequently pass it to
|
||||
`nixos-anywhere` during the installation process:
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Create a temporary directory
|
||||
temp=$(mktemp -d)
|
||||
|
||||
# Function to cleanup temporary directory on exit
|
||||
cleanup() {
|
||||
rm -rf "$temp"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Create the directory where sshd expects to find the host keys
|
||||
install -d -m755 "$temp/etc/ssh"
|
||||
|
||||
# Decrypt your private key from the password store and copy it to the temporary directory
|
||||
pass ssh_host_ed25519_key > "$temp/etc/ssh/ssh_host_ed25519_key"
|
||||
|
||||
# Set the correct permissions so sshd will accept the key
|
||||
chmod 600 "$temp/etc/ssh/ssh_host_ed25519_key"
|
||||
|
||||
# Install NixOS to the host system with our secrets
|
||||
nixos-anywhere --extra-files "$temp" --flake '.#your-host' --target-host root@yourip
|
||||
```
|
||||
|
||||
## Example: Uploading Disk Encryption Secrets
|
||||
|
||||
In a similar vein, `nixos-anywhere` can upload disk encryption secrets, which
|
||||
are necessary during formatting with disko. Here's an example that demonstrates
|
||||
how to provide your disk encryption password as a file or via the `pass` utility
|
||||
to `nixos-anywhere`:
|
||||
|
||||
```bash
|
||||
# Write your disk encryption password to a file
|
||||
echo "my-super-safe-password" > /tmp/disk-1.key
|
||||
|
||||
# Call nixos-anywhere with disk encryption keys
|
||||
nixos-anywhere \
|
||||
--disk-encryption-keys /tmp/disk-1.key /tmp/disk-1.key \
|
||||
--disk-encryption-keys /tmp/disk-2.key <(pass my-disk-encryption-password) \
|
||||
--flake '.#your-host' \
|
||||
root@yourip
|
||||
```
|
||||
|
||||
In the above example, replace `"my-super-safe-password"` with your actual
|
||||
encryption password, and `my-disk-encryption-password` with the relevant entry
|
||||
in your pass password store. Also, ensure to replace `'.#your-host'` and
|
||||
`root@yourip` with your actual flake and IP address, respectively.
|
||||
|
||||
## Example: Using existing SSH host keys
|
||||
|
||||
If the system contains existing trusted `/etc/ssh/ssh_host_*` SSH host keys and
|
||||
certificates, `nixos-anywhere` can copy them in case they are necessary during
|
||||
installation and system activation.
|
||||
|
||||
```
|
||||
nixos-anywhere --copy-host-keys --flake '.#your-host' root@yourip
|
||||
```
|
||||
|
||||
This would copy `/etc/ssh/ssh_host_*` to `/mnt` after kexec but before
|
||||
installation, ignoring files that already exist in destination.
|
|
@ -0,0 +1,23 @@
|
|||
# Terraform
|
||||
|
||||
The nixos-anywhere terraform modules allow you to use Terraform for installing
|
||||
and updating NixOS. It simplifies the deployment process by integrating
|
||||
nixos-anywhere functionality.
|
||||
|
||||
Our terraform module requires the
|
||||
[null](https://registry.terraform.io/providers/hashicorp/null/latest) and
|
||||
[external](https://registry.terraform.io/providers/hashicorp/external/latest)
|
||||
provider.
|
||||
|
||||
You can get these by from nixpkgs like this:
|
||||
|
||||
```nix
|
||||
nix-shell -p '(pkgs.terraform.withPlugins (p: [ p.null p.external ]))'
|
||||
```
|
||||
|
||||
You can add this expression the `packages` list in your devshell in flake.nix or
|
||||
in shell.nix.
|
||||
|
||||
Checkout out the
|
||||
[module reference](https://github.com/nix-community/nixos-anywhere/tree/main/terraform)
|
||||
for examples and module parameter on how to use the modules.
|
|
@ -0,0 +1,82 @@
|
|||
# Use without flakes
|
||||
|
||||
First,
|
||||
[import the disko NixOS module](https://github.com/nix-community/disko/blob/master/docs/HowTo.md#installing-nixos-module)
|
||||
in your NixOS configuration and define disko devices as described in the
|
||||
[examples](https://github.com/nix-community/disko/tree/master/example).
|
||||
|
||||
Let's assume that your NixOS configuration lives in `configuration.nix` and your
|
||||
target machine is called `machine`:
|
||||
|
||||
## 1. Download your favourite disk layout:
|
||||
|
||||
See https://github.com/nix-community/disko-templates/ for more examples:
|
||||
|
||||
The example below will work with both UEFI and BIOS-based systems.
|
||||
|
||||
```bash
|
||||
curl https://raw.githubusercontent.com/nix-community/disko-templates/main/single-disk-ext4/disko-config.nix > ./disko-config.nix
|
||||
```
|
||||
|
||||
## 2. Get a hardware-configuration.nix from on the target machine
|
||||
|
||||
- **Option 1**: If NixOS is not installed, boot into an installer without first
|
||||
installing NixOS.
|
||||
- **Option 2**: Use the kexec tarball method, as described
|
||||
[here](https://github.com/nix-community/nixos-images#kexec-tarballs).
|
||||
|
||||
- **Generate Configuration**: Run the following command on the target machine:
|
||||
|
||||
```bash
|
||||
nixos-generate-config --no-filesystems --dir /tmp/config
|
||||
```
|
||||
|
||||
This creates the necessary configuration files under `/tmp/config/`. Copy
|
||||
`/tmp/config/nixos/hardware-configuration.nix` to your local machine into the
|
||||
same directory as `disko-config.nix`.
|
||||
|
||||
## 3. Set NixOS version to use
|
||||
|
||||
```nix
|
||||
# default.nix
|
||||
let
|
||||
# replace nixos-24.11 with your preferred nixos version or revision from here: https://status.nixos.org/
|
||||
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/refs/heads/nixos-24.11.tar.gz";
|
||||
in
|
||||
import (nixpkgs + "/nixos/lib/eval-config.nix") {
|
||||
modules = [ ./configuration.nix ];
|
||||
}
|
||||
```
|
||||
|
||||
## 4. Write a NixOS configuration
|
||||
|
||||
```nix
|
||||
# configuration.nix
|
||||
{
|
||||
imports = [
|
||||
"${fetchTarball "https://github.com/nix-community/disko/tarball/master"}/module.nix"
|
||||
./disko-config.nix
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
# Replace this with the system of the installation target you want to install!!!
|
||||
disko.devices.disk.main.device = "/dev/sda";
|
||||
|
||||
# Set this to the NixOS version that you have set in the previous step.
|
||||
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
||||
system.stateVersion = "24.11";
|
||||
}
|
||||
```
|
||||
|
||||
## 5. Build and deploy with nixos-anywhere
|
||||
|
||||
Your current directory now should contain the following files from the previous
|
||||
step:
|
||||
|
||||
- `configuration.nix`, `default.nix`, `disko-config.nix` and
|
||||
`hardware-configuration.nix`
|
||||
|
||||
Run `nixos-anywhere` as follows:
|
||||
|
||||
```bash
|
||||
nixos-anywhere --store-paths $(nix-build -A config.system.build.formatScript -A config.system.build.toplevel --no-out-link) root@machine
|
||||
```
|
BIN
launch/.terraform/modules/pixelfed.deploy/docs/logo.png
Normal file
BIN
launch/.terraform/modules/pixelfed.deploy/docs/logo.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 29 KiB |
133
launch/.terraform/modules/pixelfed.deploy/docs/logo.svg
Normal file
133
launch/.terraform/modules/pixelfed.deploy/docs/logo.svg
Normal file
|
@ -0,0 +1,133 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
width="512"
|
||||
height="512"
|
||||
id="svg322"
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
inkscape:export-filename="logo.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#">
|
||||
<defs
|
||||
id="defs326">
|
||||
<marker
|
||||
markerWidth="512"
|
||||
markerHeight="512"
|
||||
refX="256"
|
||||
refY="256"
|
||||
orient="auto"
|
||||
id="marker11007">
|
||||
<path
|
||||
d="M 0,0 H 512 V 512 H 0 Z"
|
||||
fill="#fbfdfc"
|
||||
id="path246" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview324"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.2304247"
|
||||
inkscape:cx="32.280848"
|
||||
inkscape:cy="129.79591"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2090"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg322" />
|
||||
<path
|
||||
d="M0,0 L4,2 L18,10 L27,18 L30,26 L30,34 L27,46 L23,60 L17,73 L8,94 L3,105 L3,116 L7,119 L13,121 L39,126 L55,131 L64,137 L68,142 L70,146 L70,154 L66,162 L57,170 L45,176 L37,179 L20,182 L11,183 L-17,184 L-24,192 L-34,206 L-47,221 L-59,232 L-73,241 L-85,246 L-93,248 L-113,248 L-127,245 L-132,243 L-132,241 L-123,235 L-113,226 L-105,218 L-96,205 L-88,189 L-82,168 L-80,136 L-72,125 L-54,98 L-38,71 L-23,44 L-13,25 L-5,9 Z "
|
||||
fill="#517ED0"
|
||||
transform="translate(435,104)"
|
||||
id="path248" />
|
||||
<path
|
||||
d="M0,0 L10,1 L19,6 L31,17 L40,26 L49,37 L57,48 L67,62 L75,74 L91,75 L107,78 L127,85 L141,93 L153,105 L160,115 L167,130 L170,139 L171,149 L162,146 L155,143 L138,139 L110,139 L93,143 L87,146 L80,146 L71,144 L57,142 L22,140 L-23,140 L-45,141 L-65,143 L-74,143 L-81,135 L-83,129 L-83,117 L-79,109 L-73,102 L-63,95 L-46,87 L-28,82 L-11,79 L14,79 L11,71 L-2,48 L-10,34 L-14,23 L-14,13 L-11,7 L-5,2 Z "
|
||||
fill="#517DD0"
|
||||
transform="translate(132,13)"
|
||||
id="path250" />
|
||||
<path
|
||||
d="M0,0 L11,2 L20,5 L29,7 L55,7 L72,4 L80,2 L104,7 L126,9 L142,10 L234,10 L240,14 L245,20 L246,24 L246,33 L241,43 L234,50 L221,58 L205,65 L183,70 L162,73 L151,73 L159,87 L174,112 L179,122 L180,125 L180,136 L175,145 L167,150 L153,150 L143,143 L130,130 L117,113 L107,99 L95,80 L90,76 L71,74 L50,69 L34,62 L23,54 L15,46 L8,34 L2,17 L0,7 Z "
|
||||
fill="#4DB0CE"
|
||||
transform="translate(213,350)"
|
||||
id="path252" />
|
||||
<path
|
||||
d="M0,0 L2,0 L7,17 L12,30 L21,45 L31,57 L39,64 L46,71 L47,73 L49,89 L54,107 L60,122 L72,147 L83,167 L99,191 L113,212 L117,220 L117,234 L114,240 L111,243 L80,243 L63,231 L50,219 L38,207 L31,199 L30,196 L27,196 L25,200 L11,215 L2,224 L-9,230 L-13,231 L-21,231 L-27,227 L-32,221 L-36,210 L-36,203 L-28,186 L-22,174 L-17,159 L-13,141 L-12,131 L-12,99 L-16,64 L-18,49 L-18,34 L-15,24 L-8,11 Z "
|
||||
fill="#517ED0"
|
||||
transform="translate(158,269)"
|
||||
id="path256" />
|
||||
<path
|
||||
d="M0,0 L12,1 L28,8 L40,16 L50,24 L65,37 L75,48 L77,51 L79,51 L89,37 L98,27 L107,18 L117,14 L126,14 L134,19 L139,25 L142,32 L142,40 L137,54 L128,74 L123,88 L118,109 L117,117 L117,147 L121,169 L124,181 L124,200 L120,211 L111,225 L106,229 L100,214 L92,199 L80,183 L70,173 L64,168 L62,153 L57,139 L49,123 L34,97 L21,75 L6,53 L-6,36 L-12,26 L-13,23 L-13,11 L-9,5 L-4,1 Z "
|
||||
fill="#4EB0CF"
|
||||
transform="translate(246,0)"
|
||||
id="path258" />
|
||||
<path
|
||||
d="M0,0 L6,0 L6,2 L11,1 L22,1 L32,6 L41,8 L53,8 L60,16 L62,17 L61,22 L56,28 L54,33 L54,43 L58,45 L58,48 L52,47 L46,42 L46,40 L30,45 L24,53 L24,61 L25,62 L31,62 L35,58 L39,59 L41,62 L43,71 L44,72 L50,72 L53,80 L53,82 L61,80 L65,78 L70,78 L72,80 L82,79 L92,84 L103,95 L106,98 L108,99 L117,100 L123,105 L123,114 L118,128 L110,142 L99,156 L88,165 L77,173 L60,180 L55,180 L56,176 L65,170 L67,166 L67,151 L72,144 L73,141 L73,134 L69,129 L65,127 L55,126 L47,116 L45,112 L45,102 L49,97 L55,94 L55,87 L49,83 L44,78 L34,72 L18,64 L11,58 L4,42 L0,35 L1,26 L2,19 L-2,16 L-8,13 L-9,12 L-9,6 L-6,2 Z "
|
||||
fill="#4D99CF"
|
||||
transform="translate(223,166)"
|
||||
id="path260" />
|
||||
<path
|
||||
d="M0,0 L9,0 L20,8 L36,14 L44,17 L46,20 L46,27 L42,33 L42,44 L47,49 L46,52 L39,52 L25,46 L15,37 L6,27 L0,17 L-3,10 L-2,2 Z "
|
||||
fill="#4FABD1"
|
||||
transform="translate(176,284)"
|
||||
id="path262"
|
||||
style="fill:#4d99cf;fill-opacity:1" />
|
||||
<path
|
||||
d="M0,0 L14,0 L23,1 L29,5 L30,6 L30,11 L25,10 L24,9 L24,4 L-1,4 Z "
|
||||
fill="#438ED7"
|
||||
transform="translate(247,157)"
|
||||
id="path266" />
|
||||
<path
|
||||
id="path268"
|
||||
transform="translate(203,179)"
|
||||
d="m 0,0 3,1 1,8 h 8 v 4 l -2,1 H 2 L -2,9 V 2 Z"
|
||||
style="fill:#4d99cf;fill-opacity:1" />
|
||||
<path
|
||||
id="path288"
|
||||
transform="translate(278,222)"
|
||||
d="M 0,0 6,1 7,4 9,5 H 2 L -1,3 Z m 0,0 6,1 6,2 8,1 V 7 H 7 L 0,4 Z"
|
||||
style="fill:#4d99cf;fill-opacity:1" />
|
||||
<path
|
||||
d="M0,0 L3,1 L-7,8 L-9,8 L-9,6 L-5,5 L-4,2 Z "
|
||||
fill="#6184C5"
|
||||
transform="translate(371,336)"
|
||||
id="path304"
|
||||
style="fill:#517ed0;fill-opacity:1" />
|
||||
<path
|
||||
id="path314"
|
||||
style="fill:#4eb0cf;fill-opacity:1"
|
||||
transform="translate(113,201)"
|
||||
d="M 0,0 H 2 L 0,4 -2.8602037,5.4301018 -4,6 V 8 L -6,7 Z m 48,-40 h 25 l 14,3 4,2 -1,3 -10,8 -10,11 -9,14 -7,14 -5,17 -2,11 -1,15 -8,10 -12,21 -11,19 -6,10 -11,19 -12,22 -11,21 -9,20 -5,1 -10,-5 -8,-4 -4,-6 -1,-3 v -18 l 6,-26 5,-13 5,-12 6,-13 2,-5 v -6 l -5,-3 -29,-4 -18,-6 -10,-6 -5,-5 -2,-4 V 50 l 7,-8 10,-7 18,-6 10,-2 10,-1 18.016033,-0.600534 L -22,25 l 5,-5 8,-9 7,-9 8,-10 9,-10 9,-9 10,-7 8,-4 z" />
|
||||
<metadata
|
||||
id="metadata148">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
After (image error) Size: 6.4 KiB |
334
launch/.terraform/modules/pixelfed.deploy/docs/quickstart.md
Normal file
334
launch/.terraform/modules/pixelfed.deploy/docs/quickstart.md
Normal file
|
@ -0,0 +1,334 @@
|
|||
# Quickstart Guide: nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" width="150" height="150">
|
||||
|
||||
[Documentation Index](./INDEX.md)
|
||||
|
||||
## Introduction
|
||||
|
||||
This guide documents a simple installation of NixOS using **nixos-anywhere** on
|
||||
a target machine running x86_64 Linux with
|
||||
[kexec](https://man7.org/linux/man-pages/man8/kexec.8.html) support. The example
|
||||
used in this guide installs NixOS on a Hetzner cloud machine. The configuration
|
||||
may be different for some other instances. We will be including further examples
|
||||
in the [How To Guide](./howtos/INDEX.md) as and when they are available.
|
||||
|
||||
You will need:
|
||||
|
||||
- A [flake](https://wiki.nixos.org/wiki/Flakes) that controls the actions to be
|
||||
performed
|
||||
- A disk configuration containing details of the file system that will be
|
||||
created on the new server.
|
||||
- A target machine that is reachable via SSH, either using keys or a password,
|
||||
and the privilege to either log in directly as root or a user with
|
||||
password-less sudo.
|
||||
|
||||
**nixos-anywhere** doesn’t need to be installed. You can run it directly from
|
||||
[the Github repository.](https://github.com/nix-community/nixos-anywhere)
|
||||
|
||||
Details of the flake, the disk configuration and the CLI command are discussed
|
||||
below.
|
||||
|
||||
## Steps required to run nixos-anywhere
|
||||
|
||||
### 1. Enable Flakes
|
||||
|
||||
Check if your nix has flakes enabled by running `nix flake`. It will tell you if
|
||||
it's not. To enable flakes, refer to the
|
||||
[NixOS Wiki](https://wiki.nixos.org/wiki/Flakes#enable-flakes).
|
||||
|
||||
### 2. Initialize a Flake
|
||||
|
||||
The easiest way to start is to copy our
|
||||
[example flake.nix](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix)
|
||||
into a new directory. This example is tailored for a virtual machine setup
|
||||
similar to one on [Hetzner Cloud](https://www.hetzner.com/cloud), so you might
|
||||
need to adapt it for your setup.
|
||||
|
||||
If you already have a flake, you can use it by adding
|
||||
[disko configuration](https://github.com/nix-community/disko?tab=readme-ov-file#how-to-use-disko)
|
||||
to it.
|
||||
|
||||
### 3. Configure your SSH key
|
||||
|
||||
If you cloned
|
||||
[our nixos-anywhere-example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/configuration.nix)
|
||||
you will also replace the SSH key like this: In your configuration, locate the
|
||||
line that reads:
|
||||
|
||||
```bash
|
||||
# change this to your ssh key
|
||||
"CHANGE"
|
||||
```
|
||||
|
||||
Replace the text `CHANGE` with your own SSH key. This is crucial, as you will
|
||||
not be able to log into the target machine post-installation without it. If you
|
||||
have a .pem file you can run
|
||||
|
||||
```bash
|
||||
ssh-keygen -y -f /path/to/your/key.pem
|
||||
```
|
||||
|
||||
then paste the result in between the quotes like "ssh-rsa AAA..."
|
||||
|
||||
### 4. Configure Storage
|
||||
|
||||
In the same directory, create a file called `disk-config.nix`. This file will
|
||||
define the disk layout for the
|
||||
[disko](https://github.com/nix-community/disko/blob/master/docs/INDEX.md) tool,
|
||||
which is used by nixos-anywhere to partition, format, and mount the disks.
|
||||
|
||||
For a basic installation, you can copy the contents from the example provided
|
||||
[here](https://github.com/nix-community/nixos-anywhere-examples/blob/main/disk-config.nix).
|
||||
This configuration sets up a standard GPT (GUID Partition Table) that is
|
||||
compatible with both EFI and BIOS systems and mounts the disk as `/dev/sda`. You
|
||||
may need to adjust `/dev/sda` to match the correct disk on your machine. To
|
||||
identify the disk, run the `lsblk` command and replace `sda` with the actual
|
||||
disk name.
|
||||
|
||||
For example, on this machine, we would select `/dev/nvme0n1` as the disk:
|
||||
|
||||
```
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
||||
nvme0n1 259:0 0 1.8T 0 disk
|
||||
```
|
||||
|
||||
If this setup does not match your requirements, you can choose an example that
|
||||
better suits your disk layout from the
|
||||
[disko examples](https://github.com/nix-community/disko/tree/master/example).
|
||||
For more detailed information, refer to the
|
||||
[disko documentation](https://github.com/nix-community/disko).
|
||||
|
||||
### 5. Lock your Flake
|
||||
|
||||
```
|
||||
nix flake lock
|
||||
```
|
||||
|
||||
This will download your flake dependencies and make a `flake.lock` file that
|
||||
describes how to reproducibly build your system.
|
||||
|
||||
Optionally, you can commit these files to a repo such as Github, or you can
|
||||
simply reference your local directory when you run **nixos-anywhere**. This
|
||||
example uses a local directory on the source machine.
|
||||
|
||||
### 6. Connectivity to the Target Machine
|
||||
|
||||
**nixos-anywhere** will create a temporary SSH key to use for the installation.
|
||||
If your SSH key is not found, you will be asked for your password. If you are
|
||||
using a non-root user, you must have access to sudo without a password. To avoid
|
||||
SSH password prompts, set the `SSHPASS` environment variable to your password
|
||||
and add `--env-password` to the `nixos-anywhere` command. If providing a
|
||||
specific SSH key through `-i` (identity_file), this key will then be used for
|
||||
the installation and no temporary SSH key will be created.
|
||||
|
||||
### 7. (Optional) Test your NixOS and Disko configuration
|
||||
|
||||
Skip this step and continue with Step 8, if you don't have a hardware
|
||||
configuration (hardware-configuration.nix or facter.json) generated yet or make
|
||||
sure you don't import non-existing hardware-configuration.nix or facter.json
|
||||
during running the vm test.
|
||||
|
||||
The following command will automatically test your nixos configuration and run
|
||||
disko inside a virtual machine, where
|
||||
|
||||
- `<path to configuration>` is the path to the directory or repository
|
||||
containing `flake.nix` and `disk-config.nix`
|
||||
|
||||
- `<configuration name>` must match the name that immediately follows the text
|
||||
`nixosConfigurations.` in the flake, as indicated by the comment in the
|
||||
[example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix).
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --flake <path to configuration>#<configuration name> --vm-test
|
||||
```
|
||||
|
||||
### 8. Prepare Hardware Configuration
|
||||
|
||||
If you're not using a virtual machine, it's recommended to allow
|
||||
`nixos-anywhere` to generate a hardware configuration during installation. This
|
||||
ensures that essential drivers, such as those required for disk detection, are
|
||||
properly configured.
|
||||
|
||||
To enable `nixos-anywhere` to integrate its generated configuration into your
|
||||
NixOS setup, you need to include an import for the hardware configuration
|
||||
beforehand.
|
||||
|
||||
Here’s an example:
|
||||
|
||||
```diff
|
||||
nixosConfigurations.generic = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
disko.nixosModules.disko
|
||||
./configuration.nix
|
||||
+ ./hardware-configuration.nix
|
||||
];
|
||||
};
|
||||
```
|
||||
|
||||
When running `nixos-anywhere`, this file is automatically generated by including
|
||||
the following flags in your command:
|
||||
`--generate-hardware-config nixos-generate-config ./hardware-configuration.nix`.
|
||||
The second flag, `./hardware-configuration.nix`, specifies where
|
||||
`nixos-generate-config` will store the configuration. Adjust this path to
|
||||
reflect the location where you want the `hardware-configuration.nix` for this
|
||||
machine to be saved.
|
||||
|
||||
#### 8.1 nixos-facter
|
||||
|
||||
As an alternative to `nixos-generate-config`, you can use the experimental
|
||||
[nixos-facter](https://github.com/numtide/nixos-facter) command, which offers
|
||||
more comprehensive hardware reports and advanced configuration options.
|
||||
|
||||
To use `nixos-facter`, add the following to your flake inputs:
|
||||
|
||||
```diff
|
||||
{
|
||||
+ inputs.nixos-facter-modules.url = "github:numtide/nixos-facter-modules";
|
||||
}
|
||||
```
|
||||
|
||||
Next, import the module into your configuration and specify `facter.json` as the
|
||||
path where the hardware report will be saved:
|
||||
|
||||
```diff
|
||||
nixosConfigurations.generic-nixos-facter = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
disko.nixosModules.disko
|
||||
./configuration.nix
|
||||
+ nixos-facter-modules.nixosModules.facter
|
||||
+ { config.facter.reportPath = ./facter.json }
|
||||
];
|
||||
};
|
||||
```
|
||||
|
||||
To generate the configuration for `nixos-facter` with `nixos-anywhere`, use the
|
||||
following flags: `--generate-hardware-config nixos-facter ./facter.json`. The
|
||||
second flag, `./facter.json`, specifies where `nixos-generate-config` will store
|
||||
the hardware report. Adjust this path to suit the location where you want the
|
||||
`facter.json` to be saved.
|
||||
|
||||
### 9. Run it
|
||||
|
||||
You can now run **nixos-anywhere** from the command line as shown below, where:
|
||||
|
||||
- `<path to configuration>` is the path to the directory or repository
|
||||
containing `flake.nix` and `disk-config.nix`
|
||||
|
||||
- `<configuration name>` must match the name that immediately follows the text
|
||||
`nixosConfigurations.` in the flake, as indicated by the comment in the
|
||||
[example](https://github.com/nix-community/nixos-anywhere-examples/blob/main/flake.nix).
|
||||
|
||||
- `<ip address>` is the IP address of the target machine.
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --flake <path to configuration>#<configuration name> --target-host root@<ip address>
|
||||
```
|
||||
|
||||
The command would look like this if you had created your files in a directory
|
||||
named `/home/mydir/test` and the IP address of your target machine is
|
||||
`37.27.18.135`:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --flake /home/mydir/test#hetzner-cloud --target-host root@37.27.18.135
|
||||
```
|
||||
|
||||
If you also need to generate hardware configuration amend flags for
|
||||
nixos-generate-config:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-generate-config ./hardware-configuration.nix --flake <path to configuration>#<configuration name> --target-host root@<ip address>
|
||||
```
|
||||
|
||||
Or these flags if you are using nixos-facter instead:
|
||||
|
||||
```
|
||||
nix run github:nix-community/nixos-anywhere -- --generate-hardware-config nixos-facter ./facter.json --flake <path to configuration>#<configuration name> --target-host root@<ip address>
|
||||
```
|
||||
|
||||
Adjust the location of `./hardware-configuration.nix` and `./facter.json`
|
||||
accordingly.
|
||||
|
||||
**nixos-anywhere** will then run, showing various output messages at each stage.
|
||||
It may take some time to complete, depending on Internet speeds. It should
|
||||
finish by showing the messages below before returning to the command prompt.
|
||||
|
||||
```
|
||||
Installation finished. No error reported.
|
||||
Warning: Permanently added '<ip-address>' (ED25519) to the list of known hosts
|
||||
```
|
||||
|
||||
When this happens, the target server will have been overwritten with a new
|
||||
installation of NixOS. Note that the server's public SSH key will have changed.
|
||||
|
||||
If you have previously accessed this server using SSH, you may see the following
|
||||
message the next time you try to log in to the target.
|
||||
|
||||
```
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
|
||||
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
|
||||
It is also possible that a host key has just been changed.
|
||||
The fingerprint for the ED25519 key sent by the remote host is
|
||||
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
|
||||
Please contact your system administrator.
|
||||
Add correct host key in ~/.ssh/known_hosts to get rid of this message.
|
||||
Offending ECDSA key in ~/.ssh/known_hosts:6
|
||||
remove with:
|
||||
ssh-keygen -f ~/.ssh/known_hosts" -R "<ip address>"
|
||||
Host key for <ip_address> has changed and you have requested strict checking.
|
||||
Host key verification failed.
|
||||
```
|
||||
|
||||
This is because the `known_hosts` file in the `.ssh` directory now contains a
|
||||
mismatch, since the server has been overwritten. To solve this, use a text
|
||||
editor to remove the old entry from the `known_hosts` file (or use the command
|
||||
`ssh-keygen -R <ip_address>`). The next connection attempt will then treat this
|
||||
as a new server.
|
||||
|
||||
The error message line `Offending ECDSA key in ~/.ssh/known_hosts:6` gives the
|
||||
line number that needs to be removed from the `known_hosts` file (line 6 in this
|
||||
example).
|
||||
|
||||
# Finished!
|
||||
|
||||
**nixos-anywhere**'s job is now done, as it is a tool to install NixOS onto the
|
||||
target machine.
|
||||
|
||||
Any future changes to the configuration should be made to your flake. You would
|
||||
reference this flake when using the NixOS `nixos-rebuild` command or a separate
|
||||
3rd party deployment tool of your choice i.e.
|
||||
[deploy-rs](https://github.com/serokell/deploy-rs),
|
||||
[colmena](https://github.com/zhaofengli/colmena),
|
||||
[nixinate](https://github.com/MatthewCroughan/nixinate),
|
||||
[clan](https://clan.lol/) (author's choice).
|
||||
|
||||
To update on the machine locally (replace `<URL to your flake>` with your flake
|
||||
i.e. `.#` if your flake is in the current directory):
|
||||
|
||||
```
|
||||
nixos-rebuild switch --flake <URL to your flake>
|
||||
```
|
||||
|
||||
To update remotely you will need to have configured an
|
||||
[ssh server](https://search.nixos.org/options?show=services.sshd.enable) and
|
||||
your ssh key for the
|
||||
[root user](https://search.nixos.org/options?show=users.users.%3Cname%3E.openssh.authorizedKeys.keys):
|
||||
|
||||
```
|
||||
nixos-rebuild switch --flake <URL to your flake> --target-host "root@<ip address>"
|
||||
```
|
||||
|
||||
See the Nix documentation for use of the flake
|
||||
[URL-like syntax](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake#url-like-syntax).
|
||||
|
||||
For more information on different use cases of **nixos-anywhere** please refer
|
||||
to the [How to Guide](./howtos/INDEX.md), and for more technical information and
|
||||
explanation of known error messages, refer to the
|
||||
[Reference Manual](./reference.md).
|
137
launch/.terraform/modules/pixelfed.deploy/docs/reference.md
Normal file
137
launch/.terraform/modules/pixelfed.deploy/docs/reference.md
Normal file
|
@ -0,0 +1,137 @@
|
|||
# Reference Manual: nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img title="" src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" alt="" width="141">
|
||||
|
||||
[Documentation Index](./INDEX.md)
|
||||
|
||||
TODO: Populate this guide properly
|
||||
|
||||
## Contents
|
||||
|
||||
[Command Line Usage](#command-line-usage)
|
||||
|
||||
[Explanation of known error messages](#explanation-of-known-error-messages)
|
||||
|
||||
## Command Line Usage
|
||||
|
||||
<!-- `$ bash ./src/nixos-anywhere.sh --help` -->
|
||||
|
||||
```
|
||||
Usage: nixos-anywhere [options] [<ssh-host>]
|
||||
|
||||
Options:
|
||||
|
||||
* -f, --flake <flake_uri>
|
||||
set the flake to install the system from. i.e.
|
||||
nixos-anywhere --flake .#mymachine
|
||||
Also supports variants:
|
||||
nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant
|
||||
* --target-host <ssh-host>
|
||||
set the SSH target host to deploy onto.
|
||||
* -i <identity_file>
|
||||
selects which SSH private key file to use.
|
||||
* -p, --ssh-port <ssh_port>
|
||||
set the ssh port to connect with
|
||||
* --ssh-option <ssh_option>
|
||||
set an ssh option
|
||||
* -L, --print-build-logs
|
||||
print full build logs
|
||||
* --env-password
|
||||
set a password used by ssh-copy-id, the password should be set by
|
||||
the environment variable SSHPASS
|
||||
* -s, --store-paths <disko-script> <nixos-system>
|
||||
set the store paths to the disko-script and nixos-system directly
|
||||
if this is given, flake is not needed
|
||||
* --kexec <path>
|
||||
use another kexec tarball to bootstrap NixOS
|
||||
* --kexec-extra-flags
|
||||
extra flags to add into the call to kexec, e.g. "--no-sync"
|
||||
* --ssh-store-setting <key> <value>
|
||||
ssh store settings appended to the store URI, e.g. "compress true". <value> needs to be URI encoded.
|
||||
* --post-kexec-ssh-port <ssh_port>
|
||||
after kexec is executed, use a custom ssh port to connect. Defaults to 22
|
||||
* --copy-host-keys
|
||||
copy over existing /etc/ssh/ssh_host_* host keys to the installation
|
||||
* --extra-files <path>
|
||||
contents of local <path> are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten
|
||||
Copied files will be owned by root unless specified by --chown option. See documentation for details.
|
||||
* --chown <path> <ownership>
|
||||
change ownership of <path> recursively. Recommended to use uid:gid as opposed to username:groupname for ownership.
|
||||
Option can be specified more than once.
|
||||
* --disk-encryption-keys <remote_path> <local_path>
|
||||
copy the contents of the file or pipe in local_path to remote_path in the installer environment,
|
||||
after kexec but before installation. Can be repeated.
|
||||
* --no-substitute-on-destination
|
||||
disable passing --substitute-on-destination to nix-copy
|
||||
* --debug
|
||||
enable debug output
|
||||
* --show-trace
|
||||
show nix build traces
|
||||
* --option <key> <value>
|
||||
nix option to pass to every nix related command
|
||||
* --from <store-uri>
|
||||
URL of the source Nix store to copy the nixos and disko closure from
|
||||
* --build-on-remote
|
||||
build the closure on the remote machine instead of locally and copy-closuring it
|
||||
* --vm-test
|
||||
build the system and test the disk configuration inside a VM without installing it to the target.
|
||||
* --generate-hardware-config nixos-facter|nixos-generate-config <path>
|
||||
generate a hardware-configuration.nix file using the specified backend and write it to the specified path.
|
||||
The backend can be either 'nixos-facter' or 'nixos-generate-config'.
|
||||
* --phases
|
||||
comma separated list of phases to run. Default is: kexec,disko,install,reboot
|
||||
kexec: kexec into the nixos installer
|
||||
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
|
||||
install: install the system
|
||||
reboot: unmount the filesystems, export any ZFS pools and reboot the machine
|
||||
* --disko-mode disko|mount|format
|
||||
set the disko mode to format, mount or destroy. Default is disko.
|
||||
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
|
||||
* --no-disko-deps
|
||||
This will only upload the disko script and not the partitioning tools dependencies.
|
||||
Installers usually have dependencies available.
|
||||
Use this option if your target machine has not enough RAM to store the dependencies in memory.
|
||||
* --build-on auto|remote|local
|
||||
sets the build on settings to auto, remote or local. Default is auto.
|
||||
auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build
|
||||
local: will build on the local host
|
||||
remote: will build on the remote host
|
||||
```
|
||||
|
||||
## Explanation of known error messages
|
||||
|
||||
TODO: Add additional error messages and meanings. Fill in missing explanations
|
||||
|
||||
This section lists known error messages and their explanations. Some
|
||||
explanations may refer to the following CLI syntax:
|
||||
|
||||
`nix run github:nix-community/nixos-anywhere -- --flake <path to configuration>#<configuration name> root@<ip address>`
|
||||
|
||||
This list is not comprehensive. It's possible you may encounter errors that
|
||||
originate from the underlying operating system. These should be documented in
|
||||
the relevant operating system manual.
|
||||
|
||||
| Id | Message | Explanation |
|
||||
| -- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| 1 | Failure unpacking initrd | You don't have enough RAM to hold `kexec` |
|
||||
| 2 | Flake <flake_url> does not provide attribute | The configuration name you specified in your flake URI is not defined as a NixOS configuration in your flake eg if your URI was mydir#myconfig, then myconfig should be included in the flake as `nixosConfigurations.myconfig` |
|
||||
| 3 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | As for error #2 |
|
||||
| | For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri | |
|
||||
| 4 | Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already | TODO: Explain |
|
||||
| 5 | ssh-host must be set | <ip_address> has not been supplied |
|
||||
| 6 | <disko_script> and <nixos_system> must be existing store-paths | This occurs if the -s switch has been used to specify the disko script and store path correctly, and the scripts cannot be found at the given URI |
|
||||
| 7 | flake must be set | This occurs if both the -flake option (use a flake) and the -s option (specify paths directly) have been omitted. Either one or the other must be specified. |
|
||||
| 8 | no tar command found, but required to unpack kexec tarball | The destination machine does not have a `tar` command available. This is needed to unpack the `kexec`. |
|
||||
| 9 | no setsid command found, but required to run the kexec script under a new session | The destination machine does not have the `setsid` command available |
|
||||
| 10 | This script requires Linux as the operating system, but got <operating system> | The destination machine is not running Linux |
|
||||
| 11 | The default kexec image only support x86_64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information. | By default, `nixos-anywhere` uses its own `kexec` image, which will only run on x86_64 CPUs. For other CPU types, you can use your own `kexec` image instead. Refer to the [How To Guide](./howtos#using-your-own-kexec-image) for instructions. |
|
||||
| 12 | Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri. | This is a `disko` error. As for Error #2 |
|
||||
| | For example, to use the output diskoConfigurations.foo from the flake.nix, append \"#foo\" to the flake-uri. | |
|
||||
| 13 | mode must be either create, mount or zap_create_mount | This is a `disko` error. The `disko` switches have not been used correctly. This could happen if you supplied your own `disko` script using the -s option |
|
||||
| 14 | disko config must be an existing file or flake must be set | This is a `disko` error. This will happen if the `disko.devices` entry in your flake doesn't match the name of a file in the same location as your flake. |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
|
@ -0,0 +1,39 @@
|
|||
# System Requirements: nixos-anywhere
|
||||
|
||||
**_Install NixOS everywhere via ssh_**
|
||||
|
||||
<img src="https://raw.githubusercontent.com/nix-community/nixos-anywhere/main/docs/logo.png" width="150" height="150">
|
||||
|
||||
[Documentation Index](./INDEX.md)
|
||||
|
||||
## Requirements
|
||||
|
||||
### Source Machine
|
||||
|
||||
1. **Supported Systems:**
|
||||
- Linux or macOS computers with Nix installed.
|
||||
- NixOS
|
||||
- Windows systems using WSL2.
|
||||
|
||||
2. **Nix Installation:** If Nix is not yet installed on your system, refer to
|
||||
the [nix installation page](https://nixos.org/download#download-nix).
|
||||
|
||||
### Destination Machine
|
||||
|
||||
The machine must be reachable over the public internet or local network.
|
||||
Nixos-anywhere does not support wifi networks. If a VPN is needed, define a
|
||||
custom installer via the --kexec flag which connects to your VPN.
|
||||
|
||||
1. **Direct Boot Option:**
|
||||
- Must be already running a NixOS installer.
|
||||
|
||||
2. **Alternative Boot Options:** If not booting directly from a NixOS installer
|
||||
image:
|
||||
- **Architecture & Support:** Must be operating on:
|
||||
- x86-64 or aarch64 Linux systems with kexec support. Note: While most
|
||||
x86-64 Linux systems support kexec, if you're using an architecture other
|
||||
than those mentioned, you may need to specify a
|
||||
[different kexec image](./howtos/INDEX.md#using-your-own-kexec-image)
|
||||
manually.
|
||||
- **Memory Requirements:**
|
||||
- At least 1 GB of RAM (excluding swap space).
|
132
launch/.terraform/modules/pixelfed.deploy/flake.lock
generated
Normal file
132
launch/.terraform/modules/pixelfed.deploy/flake.lock
generated
Normal file
|
@ -0,0 +1,132 @@
|
|||
{
|
||||
"nodes": {
|
||||
"disko": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1741786315,
|
||||
"narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"ref": "master",
|
||||
"repo": "disko",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1741352980,
|
||||
"narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-images": {
|
||||
"inputs": {
|
||||
"nixos-stable": [
|
||||
"nixos-stable"
|
||||
],
|
||||
"nixos-unstable": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1741866599,
|
||||
"narHash": "sha256-Re/T1Cjmiis0tdphj/Wjqt+c2RlMw/il7LBWzvwQPz0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-images",
|
||||
"rev": "63285ff93fc1daa2caac9f86e2302ae4edc5e84f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-images",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1741862977,
|
||||
"narHash": "sha256-prZ0M8vE/ghRGGZcflvxCu40ObKaB+ikn74/xQoNrGQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "cdd2ef009676ac92b715ff26630164bb88fec4e0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1742051767,
|
||||
"narHash": "sha256-JpyjnalnIqJ7cvP8HzaoJN9/i2bDx83dToodHHjGuNg=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ec886d10b507760c90ed01e2eac7f0679d0a47ae",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"disko": "disko",
|
||||
"flake-parts": "flake-parts",
|
||||
"nixos-images": "nixos-images",
|
||||
"nixos-stable": "nixos-stable",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1739829690,
|
||||
"narHash": "sha256-mL1szCeIsjh6Khn3nH2cYtwO5YXG6gBiTw1A30iGeDU=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "3d0579f5cc93436052d94b73925b48973a104204",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
55
launch/.terraform/modules/pixelfed.deploy/flake.nix
Normal file
55
launch/.terraform/modules/pixelfed.deploy/flake.nix
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
description = "A universal nixos installer, just needs ssh access to the target system";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small";
|
||||
flake-parts = {
|
||||
url = "github:hercules-ci/flake-parts";
|
||||
inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# used for testing
|
||||
disko = {
|
||||
url = "github:nix-community/disko/master";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
nixos-stable.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||
nixos-images.url = "github:nix-community/nixos-images";
|
||||
nixos-images.inputs.nixos-unstable.follows = "nixpkgs";
|
||||
nixos-images.inputs.nixos-stable.follows = "nixos-stable";
|
||||
|
||||
# used for development
|
||||
treefmt-nix = {
|
||||
url = "github:numtide/treefmt-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
inputs:
|
||||
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"x86_64-darwin"
|
||||
"aarch64-linux"
|
||||
"aarch64-darwin"
|
||||
];
|
||||
imports = [
|
||||
./src/flake-module.nix
|
||||
./tests/flake-module.nix
|
||||
./docs/flake-module.nix
|
||||
# allow to disable treefmt in downstream flakes
|
||||
] ++ inputs.nixpkgs.lib.optional (inputs.treefmt-nix ? flakeModule) ./treefmt/flake-module.nix;
|
||||
|
||||
perSystem =
|
||||
{ self', lib, ... }:
|
||||
{
|
||||
checks =
|
||||
let
|
||||
packages = lib.mapAttrs' (n: lib.nameValuePair "package-${n}") self'.packages;
|
||||
devShells = lib.mapAttrs' (n: lib.nameValuePair "devShell-${n}") self'.devShells;
|
||||
in
|
||||
packages // devShells;
|
||||
};
|
||||
};
|
||||
}
|
38
launch/.terraform/modules/pixelfed.deploy/scripts/create-release.sh
Executable file
38
launch/.terraform/modules/pixelfed.deploy/scripts/create-release.sh
Executable file
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env nix
|
||||
#! nix shell nixpkgs#bash nixpkgs#gnused --command bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$SCRIPT_DIR/.."
|
||||
|
||||
version=${1:-}
|
||||
if [[ -z $version ]]; then
|
||||
echo "USAGE: $0 version" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$(git symbolic-ref --short HEAD)" != "main" ]]; then
|
||||
echo "must be on main branch" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ensure we are up-to-date
|
||||
uncommitted_changes=$(git diff --compact-summary)
|
||||
if [[ -n $uncommitted_changes ]]; then
|
||||
echo -e "There are uncommitted changes, exiting:\n${uncommitted_changes}" >&2
|
||||
exit 1
|
||||
fi
|
||||
git pull git@github.com:nix-community/nixos-anywhere main
|
||||
unpushed_commits=$(git log --format=oneline origin/main..main)
|
||||
if [[ $unpushed_commits != "" ]]; then
|
||||
echo -e "\nThere are unpushed changes, exiting:\n$unpushed_commits" >&2
|
||||
exit 1
|
||||
fi
|
||||
sed -i -e "s!version = \".*\";!version = \"${version}\";!" src/default.nix
|
||||
git add src/default.nix
|
||||
nix-shell -p nix-fast-build --command "nix-fast-build --eval-workers 2"
|
||||
git commit -m "bump version ${version}"
|
||||
git tag "${version}"
|
||||
|
||||
echo "now run 'git push --tags origin main'"
|
63
launch/.terraform/modules/pixelfed.deploy/src/default.nix
Normal file
63
launch/.terraform/modules/pixelfed.deploy/src/default.nix
Normal file
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
stdenv,
|
||||
openssh,
|
||||
gitMinimal,
|
||||
nixVersions,
|
||||
nix,
|
||||
coreutils,
|
||||
curl,
|
||||
gnugrep,
|
||||
gnutar,
|
||||
gawk,
|
||||
findutils,
|
||||
gnused,
|
||||
sshpass,
|
||||
terraform-docs,
|
||||
lib,
|
||||
makeWrapper,
|
||||
mkShellNoCC,
|
||||
}:
|
||||
let
|
||||
runtimeDeps = [
|
||||
gitMinimal # for git flakes
|
||||
# pinned because nix-copy-closure hangs if ControlPath provided for SSH: https://github.com/NixOS/nix/issues/8480
|
||||
(if lib.versionAtLeast nix.version "2.16" then nix else nixVersions.nix_2_16)
|
||||
coreutils
|
||||
curl # when uploading tarballs
|
||||
gnugrep
|
||||
gawk
|
||||
findutils
|
||||
gnused # needed by ssh-copy-id
|
||||
sshpass # used to provide password for ssh-copy-id
|
||||
gnutar # used to upload extra-files
|
||||
];
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
pname = "nixos-anywhere";
|
||||
version = "1.8.0";
|
||||
src = ./..;
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
installPhase = ''
|
||||
install -D --target-directory=$out/libexec/nixos-anywhere/ -m 0755 src/*.sh
|
||||
|
||||
# We prefer the system's openssh over our own, since it might come with features not present in ours:
|
||||
# https://github.com/nix-community/nixos-anywhere/issues/62
|
||||
makeShellWrapper $out/libexec/nixos-anywhere/nixos-anywhere.sh $out/bin/nixos-anywhere \
|
||||
--prefix PATH : ${lib.makeBinPath runtimeDeps} --suffix PATH : ${lib.makeBinPath [ openssh ]}
|
||||
'';
|
||||
|
||||
# Dependencies for our devshell
|
||||
passthru.devShell = mkShellNoCC {
|
||||
packages = runtimeDeps ++ [
|
||||
openssh
|
||||
terraform-docs
|
||||
];
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "Install nixos everywhere via ssh";
|
||||
homepage = "https://github.com/nix-community/nixos-anywhere";
|
||||
license = licenses.mit;
|
||||
platforms = platforms.all;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
perSystem =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
packages = {
|
||||
nixos-anywhere = pkgs.callPackage ./. { };
|
||||
default = config.packages.nixos-anywhere;
|
||||
};
|
||||
devShells.default = config.packages.nixos-anywhere.devShell;
|
||||
};
|
||||
}
|
23
launch/.terraform/modules/pixelfed.deploy/src/get-facts.sh
Executable file
23
launch/.terraform/modules/pixelfed.deploy/src/get-facts.sh
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/bin/sh
|
||||
set -efu "${enableDebug:-}"
|
||||
has() {
|
||||
command -v "$1" >/dev/null && echo "y" || echo "n"
|
||||
}
|
||||
isNixos=$(if test -f /etc/os-release && grep -Eq 'ID(_LIKE)?="?nixos"?' /etc/os-release; then echo "y"; else echo "n"; fi)
|
||||
cat <<FACTS
|
||||
isOs=$(uname)
|
||||
isArch=$(uname -m)
|
||||
isKexec=$(if test -f /etc/is_kexec; then echo "y"; else echo "n"; fi)
|
||||
isNixos=$isNixos
|
||||
isInstaller=$(if [ "$isNixos" = "y" ] && grep -Eq 'VARIANT_ID="?installer"?' /etc/os-release; then echo "y"; else echo "n"; fi)
|
||||
isContainer=$(if [ "$(has systemd-detect-virt)" = "y" ]; then systemd-detect-virt --container; else echo "none"; fi)
|
||||
hasIpv6Only=$(if [ "$(has ip)" = "n" ] || ip r g 1 >/dev/null 2>/dev/null || ! ip -6 r g :: >/dev/null 2>/dev/null; then echo "n"; else echo "y"; fi)
|
||||
hasTar=$(has tar)
|
||||
hasCpio=$(has cpio)
|
||||
hasSudo=$(has sudo)
|
||||
hasDoas=$(has doas)
|
||||
hasWget=$(has wget)
|
||||
hasCurl=$(has curl)
|
||||
hasSetsid=$(has setsid)
|
||||
hasNixOSFacter=$(command -v nixos-facter >/dev/null && echo "y" || echo "n")
|
||||
FACTS
|
880
launch/.terraform/modules/pixelfed.deploy/src/nixos-anywhere.sh
Executable file
880
launch/.terraform/modules/pixelfed.deploy/src/nixos-anywhere.sh
Executable file
|
@ -0,0 +1,880 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
here=$(dirname "${BASH_SOURCE[0]}")
|
||||
flake=""
|
||||
flakeAttr=""
|
||||
kexecUrl=""
|
||||
kexecExtraFlags=""
|
||||
sshStoreSettings=""
|
||||
enableDebug=""
|
||||
nixBuildFlags=()
|
||||
diskoAttr=""
|
||||
diskoScript=""
|
||||
diskoMode="disko"
|
||||
diskoDeps=y
|
||||
nixosSystem=""
|
||||
extraFiles=""
|
||||
vmTest="n"
|
||||
nixOptions=(
|
||||
--extra-experimental-features 'nix-command flakes'
|
||||
"--no-write-lock-file"
|
||||
)
|
||||
SSH_PRIVATE_KEY=${SSH_PRIVATE_KEY-}
|
||||
|
||||
declare -A phases
|
||||
phases[kexec]=1
|
||||
phases[disko]=1
|
||||
phases[install]=1
|
||||
phases[reboot]=1
|
||||
|
||||
hardwareConfigBackend=none
|
||||
hardwareConfigPath=
|
||||
sshPrivateKeyFile=
|
||||
if [ -t 0 ]; then # stdin is a tty, we allow interactive input to ssh i.e. passwords
|
||||
sshTtyParam="-t"
|
||||
else
|
||||
sshTtyParam="-T"
|
||||
fi
|
||||
sshConnection=
|
||||
postKexecSshPort=22
|
||||
buildOnRemote=n
|
||||
buildOn=auto
|
||||
envPassword=n
|
||||
|
||||
# Facts set by get-facts.sh
|
||||
isOs=
|
||||
isArch=
|
||||
isKexec=
|
||||
isInstaller=
|
||||
isContainer=
|
||||
hasIpv6Only=
|
||||
hasTar=
|
||||
hasCpio=
|
||||
hasSudo=
|
||||
hasDoas=
|
||||
hasWget=
|
||||
hasCurl=
|
||||
hasSetsid=
|
||||
hasNixOSFacter=
|
||||
|
||||
sshKeyDir=$(mktemp -d)
|
||||
trap 'rm -rf "$sshKeyDir"' EXIT
|
||||
mkdir -p "$sshKeyDir"
|
||||
|
||||
declare -A diskEncryptionKeys=()
|
||||
declare -A extraFilesOwnership=()
|
||||
declare -a nixCopyOptions=()
|
||||
declare -a sshArgs=()
|
||||
|
||||
showUsage() {
|
||||
cat <<USAGE
|
||||
Usage: nixos-anywhere [options] [<ssh-host>]
|
||||
|
||||
Options:
|
||||
|
||||
* -f, --flake <flake_uri>
|
||||
set the flake to install the system from. i.e.
|
||||
nixos-anywhere --flake .#mymachine
|
||||
Also supports variants:
|
||||
nixos-anywhere --flake .#nixosConfigurations.mymachine.config.virtualisation.vmVariant
|
||||
* --target-host <ssh-host>
|
||||
set the SSH target host to deploy onto.
|
||||
* -i <identity_file>
|
||||
selects which SSH private key file to use.
|
||||
* -p, --ssh-port <ssh_port>
|
||||
set the ssh port to connect with
|
||||
* --ssh-option <ssh_option>
|
||||
set an ssh option
|
||||
* -L, --print-build-logs
|
||||
print full build logs
|
||||
* --env-password
|
||||
set a password used by ssh-copy-id, the password should be set by
|
||||
the environment variable SSHPASS
|
||||
* -s, --store-paths <disko-script> <nixos-system>
|
||||
set the store paths to the disko-script and nixos-system directly
|
||||
if this is given, flake is not needed
|
||||
* --kexec <path>
|
||||
use another kexec tarball to bootstrap NixOS
|
||||
* --kexec-extra-flags
|
||||
extra flags to add into the call to kexec, e.g. "--no-sync"
|
||||
* --ssh-store-setting <key> <value>
|
||||
ssh store settings appended to the store URI, e.g. "compress true". <value> needs to be URI encoded.
|
||||
* --post-kexec-ssh-port <ssh_port>
|
||||
after kexec is executed, use a custom ssh port to connect. Defaults to 22
|
||||
* --copy-host-keys
|
||||
copy over existing /etc/ssh/ssh_host_* host keys to the installation
|
||||
* --extra-files <path>
|
||||
contents of local <path> are recursively copied to the root (/) of the new NixOS installation. Existing files are overwritten
|
||||
Copied files will be owned by root unless specified by --chown option. See documentation for details.
|
||||
* --chown <path> <ownership>
|
||||
change ownership of <path> recursively. Recommended to use uid:gid as opposed to username:groupname for ownership.
|
||||
Option can be specified more than once.
|
||||
* --disk-encryption-keys <remote_path> <local_path>
|
||||
copy the contents of the file or pipe in local_path to remote_path in the installer environment,
|
||||
after kexec but before installation. Can be repeated.
|
||||
* --no-substitute-on-destination
|
||||
disable passing --substitute-on-destination to nix-copy
|
||||
* --debug
|
||||
enable debug output
|
||||
* --show-trace
|
||||
show nix build traces
|
||||
* --option <key> <value>
|
||||
nix option to pass to every nix related command
|
||||
* --from <store-uri>
|
||||
URL of the source Nix store to copy the nixos and disko closure from
|
||||
* --build-on-remote
|
||||
build the closure on the remote machine instead of locally and copy-closuring it
|
||||
* --vm-test
|
||||
build the system and test the disk configuration inside a VM without installing it to the target.
|
||||
* --generate-hardware-config nixos-facter|nixos-generate-config <path>
|
||||
generate a hardware-configuration.nix file using the specified backend and write it to the specified path.
|
||||
The backend can be either 'nixos-facter' or 'nixos-generate-config'.
|
||||
* --phases
|
||||
comma separated list of phases to run. Default is: kexec,disko,install,reboot
|
||||
kexec: kexec into the nixos installer
|
||||
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
|
||||
install: install the system
|
||||
reboot: unmount the filesystems, export any ZFS pools and reboot the machine
|
||||
* --disko-mode disko|mount|format
|
||||
set the disko mode to format, mount or destroy. Default is disko.
|
||||
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
|
||||
* --no-disko-deps
|
||||
This will only upload the disko script and not the partitioning tools dependencies.
|
||||
Installers usually have dependencies available.
|
||||
Use this option if your target machine has not enough RAM to store the dependencies in memory.
|
||||
* --build-on auto|remote|local
|
||||
sets the build on settings to auto, remote or local. Default is auto.
|
||||
auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build
|
||||
local: will build on the local host
|
||||
remote: will build on the remote host
|
||||
USAGE
|
||||
}
|
||||
|
||||
abort() {
|
||||
echo "aborted: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
step() {
|
||||
echo "### $* ###"
|
||||
}
|
||||
|
||||
parseArgs() {
|
||||
local substituteOnDestination=y
|
||||
local printBuildLogs=n
|
||||
local buildOnRemote=n
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-f | --flake)
|
||||
flake=$2
|
||||
shift
|
||||
;;
|
||||
--target-host)
|
||||
sshConnection=$2
|
||||
shift
|
||||
;;
|
||||
-i)
|
||||
sshPrivateKeyFile=$2
|
||||
shift
|
||||
;;
|
||||
-p | --ssh-port)
|
||||
sshArgs+=("-p" "$2")
|
||||
shift
|
||||
;;
|
||||
--ssh-option)
|
||||
sshArgs+=("-o" "$2")
|
||||
shift
|
||||
;;
|
||||
-L | --print-build-logs)
|
||||
printBuildLogs=y
|
||||
;;
|
||||
-s | --store-paths)
|
||||
diskoScript=$(readlink -f "$2")
|
||||
nixosSystem=$(readlink -f "$3")
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--generate-hardware-config)
|
||||
if [[ $# -lt 3 ]]; then
|
||||
abort "Missing arguments for --generate-hardware-config <backend> <path>"
|
||||
fi
|
||||
case "$2" in
|
||||
nixos-facter | nixos-generate-config)
|
||||
hardwareConfigBackend=$2
|
||||
;;
|
||||
*)
|
||||
abort "Unknown hardware config backend: $2"
|
||||
;;
|
||||
esac
|
||||
hardwareConfigPath=$3
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-t | --tty)
|
||||
echo "the '$1' flag is deprecated, a tty is now detected automatically" >&2
|
||||
;;
|
||||
--help)
|
||||
showUsage
|
||||
exit 0
|
||||
;;
|
||||
--kexec)
|
||||
kexecUrl=$2
|
||||
shift
|
||||
;;
|
||||
--kexec-extra-flags)
|
||||
kexecExtraFlags=$2
|
||||
shift
|
||||
;;
|
||||
--ssh-store-setting)
|
||||
key=$2
|
||||
shift
|
||||
value=$2
|
||||
shift
|
||||
sshStoreSettings+="$sshStoreSettings$key=$value&"
|
||||
shift
|
||||
;;
|
||||
--post-kexec-ssh-port)
|
||||
postKexecSshPort=$2
|
||||
shift
|
||||
;;
|
||||
--copy-host-keys)
|
||||
copyHostKeys=y
|
||||
;;
|
||||
--show-trace)
|
||||
nixBuildFlags+=("--show-trace")
|
||||
;;
|
||||
--debug)
|
||||
enableDebug="-x"
|
||||
printBuildLogs=y
|
||||
set -x
|
||||
;;
|
||||
--disko-mode)
|
||||
case "$2" in
|
||||
format | mount | disko)
|
||||
diskoMode=$2
|
||||
;;
|
||||
*)
|
||||
abort "Supported values for --disko-mode are disko, mount and format. Unknown mode : $2"
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
;;
|
||||
--no-disko-deps)
|
||||
diskoDeps=n
|
||||
;;
|
||||
--build-on)
|
||||
case "$2" in
|
||||
auto | local | remote)
|
||||
buildOn=$2
|
||||
;;
|
||||
*)
|
||||
abort "Supported values for --build-on are auto, local and remote. Unknown mode : $2"
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
;;
|
||||
--extra-files)
|
||||
extraFiles=$2
|
||||
shift
|
||||
;;
|
||||
--chown)
|
||||
extraFilesOwnership["$2"]="$3"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--disk-encryption-keys)
|
||||
diskEncryptionKeys["$2"]="$3"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--phases)
|
||||
phases[kexec]=0
|
||||
phases[disko]=0
|
||||
phases[install]=0
|
||||
phases[reboot]=0
|
||||
IFS=, read -r -a phaseList <<<"$2"
|
||||
for phase in "${phaseList[@]}"; do
|
||||
if [[ ${phases[$phase]:-unset} == unset ]]; then
|
||||
abort "Unknown phase: $phase"
|
||||
fi
|
||||
phases[$phase]=1
|
||||
done
|
||||
shift
|
||||
;;
|
||||
--stop-after-disko)
|
||||
echo "WARNING: --stop-after-disko is deprecated, use --phases kexec,disko instead" 2>&1
|
||||
phases[kexec]=1
|
||||
phases[disko]=1
|
||||
phases[install]=0
|
||||
phases[reboot]=0
|
||||
;;
|
||||
--no-reboot)
|
||||
echo "WARNING: --no-reboot is deprecated, use --phases kexec,disko,install instead" 2>&1
|
||||
phases[kexec]=1
|
||||
phases[disko]=1
|
||||
phases[install]=1
|
||||
phases[reboot]=0
|
||||
;;
|
||||
--from)
|
||||
nixCopyOptions+=("--from" "$2")
|
||||
shift
|
||||
;;
|
||||
--option)
|
||||
key=$2
|
||||
shift
|
||||
value=$2
|
||||
shift
|
||||
nixOptions+=("--option" "$key" "$value")
|
||||
;;
|
||||
--no-substitute-on-destination)
|
||||
substituteOnDestination=n
|
||||
;;
|
||||
--build-on-remote)
|
||||
echo "WARNING: --build-on-remote is deprecated, use --build-on remote instead" 2>&1
|
||||
buildOnRemote=y
|
||||
buildOn="remote"
|
||||
;;
|
||||
--env-password)
|
||||
envPassword=y
|
||||
;;
|
||||
--vm-test)
|
||||
vmTest=y
|
||||
;;
|
||||
*)
|
||||
if [[ -z ${sshConnection} ]]; then
|
||||
sshConnection="$1"
|
||||
else
|
||||
showUsage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
diskoAttr="${diskoMode}Script"
|
||||
|
||||
if [[ ${diskoDeps} == "n" ]]; then
|
||||
diskoAttr="${diskoAttr}NoDeps"
|
||||
fi
|
||||
|
||||
if [[ ${printBuildLogs} == "y" ]]; then
|
||||
nixOptions+=("-L")
|
||||
fi
|
||||
|
||||
if [[ $substituteOnDestination == "y" ]]; then
|
||||
nixCopyOptions+=("--substitute-on-destination")
|
||||
fi
|
||||
|
||||
if [[ $vmTest == "n" ]] && [[ -z ${sshConnection} ]]; then
|
||||
abort "ssh-host must be set"
|
||||
fi
|
||||
|
||||
if [[ $buildOn == "local" ]] && [[ $buildOnRemote == "y" ]]; then
|
||||
abort "Conflicting flags: --build-on local and --build-on-remote used."
|
||||
fi
|
||||
|
||||
if [[ -n ${flake} ]]; then
|
||||
if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
|
||||
flake="${BASH_REMATCH[1]}"
|
||||
flakeAttr="${BASH_REMATCH[2]}"
|
||||
fi
|
||||
if [[ -z ${flakeAttr} ]]; then
|
||||
echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri." >&2
|
||||
echo 'For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Support .#foo shorthand
|
||||
if [[ $flakeAttr != nixosConfigurations.* ]]; then
|
||||
flakeAttr="nixosConfigurations.\"$flakeAttr\".config"
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# ssh wrapper
|
||||
runSshNoTty() {
|
||||
ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@"
|
||||
}
|
||||
runSshTimeout() {
|
||||
timeout 10 ssh -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@"
|
||||
}
|
||||
runSsh() {
|
||||
ssh "$sshTtyParam" -i "$sshKeyDir"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${sshArgs[@]}" "$sshConnection" "$@"
|
||||
}
|
||||
|
||||
nixCopy() {
|
||||
NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix copy \
|
||||
"${nixOptions[@]}" \
|
||||
"${nixCopyOptions[@]}" \
|
||||
"$@"
|
||||
}
|
||||
nixBuild() {
|
||||
NIX_SSHOPTS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $sshKeyDir/nixos-anywhere ${sshArgs[*]}" nix build \
|
||||
--print-out-paths \
|
||||
--no-link \
|
||||
"${nixBuildFlags[@]}" \
|
||||
"${nixOptions[@]}" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
runVmTest() {
|
||||
if [[ -z ${flakeAttr} ]]; then
|
||||
echo "--vm-test is not supported with --store-paths" >&2
|
||||
echo "Please use --flake instead or build config.system.build.installTest of your nixos configuration manually" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${buildOn} == "remote" ]]; then
|
||||
echo "--vm-test is not supported with --build-on-remote" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n ${extraFiles} ]]; then
|
||||
echo "--vm-test is not supported with --extra-files" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ${#diskEncryptionKeys[@]} -gt 0 ]; then
|
||||
echo "--vm-test is not supported with --disk-encryption-keys" >&2
|
||||
exit 1
|
||||
fi
|
||||
nix build \
|
||||
--print-out-paths \
|
||||
--no-link \
|
||||
-L \
|
||||
"${nixBuildFlags[@]}" \
|
||||
"${nixOptions[@]}" \
|
||||
"${flake}#${flakeAttr}.system.build.installTest"
|
||||
}
|
||||
|
||||
uploadSshKey() {
|
||||
# ssh-copy-id requires this directory
|
||||
mkdir -p "$HOME/.ssh/"
|
||||
if [[ -n ${sshPrivateKeyFile} ]]; then
|
||||
cp "$sshPrivateKeyFile" "$sshKeyDir/nixos-anywhere"
|
||||
ssh-keygen -y -f "$sshKeyDir/nixos-anywhere" >"$sshKeyDir/nixos-anywhere.pub"
|
||||
else
|
||||
# we generate a temporary ssh keypair that we can use during nixos-anywhere
|
||||
ssh-keygen -t ed25519 -f "$sshKeyDir"/nixos-anywhere -P "" -C "nixos-anywhere" >/dev/null
|
||||
fi
|
||||
|
||||
declare -a sshCopyIdArgs
|
||||
if [[ -n ${sshPrivateKeyFile} ]]; then
|
||||
unset SSH_AUTH_SOCK # don't use system agent if key was supplied
|
||||
sshCopyIdArgs+=(-o "IdentityFile=${sshPrivateKeyFile}" -f)
|
||||
fi
|
||||
|
||||
step Uploading install SSH keys
|
||||
until
|
||||
if [[ ${envPassword} == y ]]; then
|
||||
sshpass -e \
|
||||
ssh-copy-id \
|
||||
-i "$sshKeyDir"/nixos-anywhere.pub \
|
||||
-o ConnectTimeout=10 \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o IdentitiesOnly=yes \
|
||||
-o StrictHostKeyChecking=no \
|
||||
"${sshCopyIdArgs[@]}" \
|
||||
"${sshArgs[@]}" \
|
||||
"$sshConnection"
|
||||
else
|
||||
ssh-copy-id \
|
||||
-i "$sshKeyDir"/nixos-anywhere.pub \
|
||||
-o ConnectTimeout=10 \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o StrictHostKeyChecking=no \
|
||||
"${sshCopyIdArgs[@]}" \
|
||||
"${sshArgs[@]}" \
|
||||
"$sshConnection"
|
||||
fi
|
||||
do
|
||||
sleep 3
|
||||
done
|
||||
}
|
||||
|
||||
importFacts() {
|
||||
step Gathering machine facts
|
||||
local facts filteredFacts
|
||||
if ! facts=$(runSsh -o ConnectTimeout=10 enableDebug=$enableDebug sh -- <"$here"/get-facts.sh); then
|
||||
exit 1
|
||||
fi
|
||||
filteredFacts=$(echo "$facts" | grep -E '^(has|is)[A-Za-z0-9_]+=\S+')
|
||||
if [[ -z $filteredFacts ]]; then
|
||||
abort "Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already"
|
||||
fi
|
||||
# make facts available in script
|
||||
# shellcheck disable=SC2046
|
||||
export $(echo "$filteredFacts" | xargs)
|
||||
|
||||
for var in isOs isArch isKexec isInstaller isContainer hasIpv6Only hasTar hasCpio hasSudo hasDoas hasWget hasCurl hasSetsid; do
|
||||
if [[ -z ${!var} ]]; then
|
||||
abort "Failed to retrieve fact $var from host"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
checkBuildLocally() {
|
||||
local system extraPlatforms machineSystem
|
||||
system="$(nix --extra-experimental-features 'nix-command flakes' config show system)"
|
||||
extraPlatforms="$(nix --extra-experimental-features 'nix-command flakes' config show extra-platforms)"
|
||||
|
||||
if [[ $# -gt 0 ]]; then
|
||||
machineSystem=$1
|
||||
elif [[ -n ${nixosSystem} ]]; then
|
||||
machineSystem="$(cat "${nixosSystem}"/system)"
|
||||
else
|
||||
machineSystem="$(nix --extra-experimental-features 'nix-command flakes' eval --raw "${flake}"#"${flakeAttr}".pkgs.system 2>/dev/null || echo "unknown")"
|
||||
if [[ ${machineSystem} == "unknown" ]]; then
|
||||
buildOn=auto
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${system} == "${machineSystem}" ]]; then
|
||||
buildOn=local
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ ${extraPlatforms} == "*${machineSystem}*" ]]; then
|
||||
buildOn=local
|
||||
return
|
||||
fi
|
||||
|
||||
local entropy
|
||||
entropy="$(date +'%Y%m%d%H%M%S')"
|
||||
if nix build \
|
||||
-L \
|
||||
"${nixOptions[@]}" \
|
||||
--expr \
|
||||
"derivation { system = \"$system\"; name = \"env-$entropy\"; builder = \"/bin/sh\"; args = [ \"-c\" \"echo > \$out\" ]; }"; then
|
||||
# The local build failed
|
||||
buildOn=local
|
||||
fi
|
||||
|
||||
buildOn=remote
|
||||
}
|
||||
|
||||
generateHardwareConfig() {
|
||||
local maybeSudo="$maybeSudo"
|
||||
mkdir -p "$(dirname "$hardwareConfigPath")"
|
||||
case "$hardwareConfigBackend" in
|
||||
nixos-facter)
|
||||
if [[ ${isInstaller} == "y" ]]; then
|
||||
if [[ ${hasNixOSFacter} == "n" ]]; then
|
||||
abort "nixos-facter is not available in booted installer, use nixos-generate-config. For nixos-facter, you may want to boot an installer image from here instead: https://github.com/nix-community/nixos-images"
|
||||
fi
|
||||
else
|
||||
maybeSudo=""
|
||||
fi
|
||||
|
||||
step "Generating hardware-configuration.nix using nixos-facter"
|
||||
runSshNoTty -o ConnectTimeout=10 ${maybeSudo} "nixos-facter" >"$hardwareConfigPath"
|
||||
;;
|
||||
nixos-generate-config)
|
||||
step "Generating hardware-configuration.nix using nixos-generate-config"
|
||||
runSshNoTty -o ConnectTimeout=10 nixos-generate-config --show-hardware-config --no-filesystems >"$hardwareConfigPath"
|
||||
;;
|
||||
*)
|
||||
abort "Unknown hardware config backend: $hardwareConfigBackend"
|
||||
;;
|
||||
esac
|
||||
|
||||
# to make sure nix knows about the new file
|
||||
if command -v git >/dev/null; then
|
||||
# handle relative paths
|
||||
hardwareConfigPath="$(realpath "$hardwareConfigPath")"
|
||||
pushd "$(dirname "$hardwareConfigPath")"
|
||||
if git rev-parse --is-inside-work-tree >/dev/null; then
|
||||
git add --intent-to-add --force -- "$hardwareConfigPath"
|
||||
fi
|
||||
popd
|
||||
fi
|
||||
}
|
||||
|
||||
runKexec() {
|
||||
if [[ ${isKexec} == "y" ]] || [[ ${isInstaller} == "y" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ ${isContainer} != "none" ]]; then
|
||||
echo "WARNING: This script does not support running from a '${isContainer}' container. kexec will likely not work" >&2
|
||||
fi
|
||||
|
||||
if [[ $kexecUrl == "" ]]; then
|
||||
case "${isArch}" in
|
||||
x86_64 | aarch64)
|
||||
kexecUrl="https://github.com/nix-community/nixos-images/releases/download/nixos-24.11/nixos-kexec-installer-noninteractive-${isArch}-linux.tar.gz"
|
||||
;;
|
||||
*)
|
||||
abort "Unsupported architecture: ${isArch}. Our default kexec images only support x86_64 and aarch64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information."
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
step Switching system into kexec
|
||||
runSsh sh <<SSH
|
||||
set -efu ${enableDebug}
|
||||
$maybeSudo rm -rf /root/kexec
|
||||
$maybeSudo mkdir -p /root/kexec
|
||||
SSH
|
||||
|
||||
# no way to reach global ipv4 destinations, use gh-v6.com automatically if github url
|
||||
if [[ ${hasIpv6Only} == "y" ]] && [[ $kexecUrl == "https://github.com/"* ]]; then
|
||||
kexecUrl=${kexecUrl/"github.com"/"gh-v6.com"}
|
||||
fi
|
||||
|
||||
if [[ -f $kexecUrl ]]; then
|
||||
runSsh "${maybeSudo} tar -C /root/kexec -xvzf-" <"$kexecUrl"
|
||||
elif [[ ${hasCurl} == "y" ]]; then
|
||||
runSsh "curl --fail -Ss -L '${kexecUrl}' | ${maybeSudo} tar -C /root/kexec -xvzf-"
|
||||
elif [[ ${hasWget} == "y" ]]; then
|
||||
runSsh "wget '${kexecUrl}' -O- | ${maybeSudo} tar -C /root/kexec -xvzf-"
|
||||
else
|
||||
curl --fail -Ss -L "${kexecUrl}" | runSsh "${maybeSudo} tar -C /root/kexec -xvzf-"
|
||||
fi
|
||||
|
||||
runSsh <<SSH
|
||||
TMPDIR=/root/kexec setsid ${maybeSudo} /root/kexec/kexec/run --kexec-extra-flags "${kexecExtraFlags}"
|
||||
SSH
|
||||
|
||||
# use the default SSH port to connect at this point
|
||||
for i in "${!sshArgs[@]}"; do
|
||||
if [[ ${sshArgs[i]} == "-p" ]]; then
|
||||
sshArgs[i + 1]=$postKexecSshPort
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# wait for machine to become unreachable.
|
||||
while runSshTimeout -- exit 0; do sleep 1; done
|
||||
|
||||
# After kexec we explicitly set the user to root@
|
||||
sshConnection="root@${sshHost}"
|
||||
|
||||
# waiting for machine to become available again
|
||||
until runSsh -o ConnectTimeout=10 -- exit 0; do sleep 5; done
|
||||
}
|
||||
|
||||
runDisko() {
|
||||
local diskoScript=$1
|
||||
for path in "${!diskEncryptionKeys[@]}"; do
|
||||
step "Uploading ${diskEncryptionKeys[$path]} to $path"
|
||||
runSsh "umask 077; mkdir -p \"$(dirname "$path")\"; cat > $path" <"${diskEncryptionKeys[$path]}"
|
||||
done
|
||||
if [[ -n ${diskoScript} ]]; then
|
||||
nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "$diskoScript"
|
||||
elif [[ ${buildOn} == "remote" ]]; then
|
||||
step Building disko script
|
||||
# We need to do a nix copy first because nix build doesn't have --no-check-sigs
|
||||
# Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359
|
||||
nixCopy --to "ssh://$sshConnection?$sshStoreSettings" "${flake}#${flakeAttr}.system.build.${diskoMode}Script" \
|
||||
--derivation --no-check-sigs
|
||||
# If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store`
|
||||
diskoScript=$(
|
||||
nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}" \
|
||||
--eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&$sshStoreSettings"
|
||||
)
|
||||
fi
|
||||
|
||||
step Formatting hard drive with disko
|
||||
runSsh "$diskoScript"
|
||||
}
|
||||
|
||||
nixosInstall() {
|
||||
local nixosSystem=$1
|
||||
if [[ -n ${nixosSystem} ]]; then
|
||||
step Uploading the system closure
|
||||
nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "$nixosSystem"
|
||||
elif [[ ${buildOn} == "remote" ]]; then
|
||||
step Building the system closure
|
||||
# We need to do a nix copy first because nix build doesn't have --no-check-sigs
|
||||
# Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359
|
||||
nixCopy --to "ssh://$sshConnection?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings" "${flake}#${flakeAttr}.system.build.toplevel" \
|
||||
--derivation --no-check-sigs
|
||||
# If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store`
|
||||
nixosSystem=$(
|
||||
nixBuild "${flake}#${flakeAttr}.system.build.toplevel" \
|
||||
--eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir%2Fnixos-anywhere&remote-store=local%3Froot=%2Fmnt&$sshStoreSettings"
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ -n ${extraFiles} ]]; then
|
||||
step Copying extra files
|
||||
tar -C "$extraFiles" -cpf- . | runSsh "tar -C /mnt -xf- --no-same-owner"
|
||||
|
||||
runSsh "chmod 755 /mnt" # tar also changes permissions of /mnt
|
||||
fi
|
||||
|
||||
if [[ ${#extraFilesOwnership[@]} -gt 0 ]]; then
|
||||
# shellcheck disable=SC2016
|
||||
printf "%s\n" "${!extraFilesOwnership[@]}" "${extraFilesOwnership[@]}" | pr -2t | runSsh 'while read file ownership; do chown -R "$ownership" "/mnt/$file"; done'
|
||||
fi
|
||||
|
||||
step Installing NixOS
|
||||
runSsh sh <<SSH
|
||||
set -eu ${enableDebug}
|
||||
# when running not in nixos we might miss this directory, but it's needed in the nixos chroot during installation
|
||||
export PATH="\$PATH:/run/current-system/sw/bin"
|
||||
|
||||
# needed for installation if initrd-secrets are used
|
||||
mkdir -p /mnt/tmp
|
||||
chmod 777 /mnt/tmp
|
||||
if [ ${copyHostKeys-n} = "y" ]; then
|
||||
# NB we copy host keys that are in turn copied by kexec installer.
|
||||
mkdir -m 755 -p /mnt/etc/ssh
|
||||
for p in /etc/ssh/ssh_host_*; do
|
||||
# Skip if the source file does not exist (i.e. glob did not match any files)
|
||||
# or the destination already exists (e.g. copied with --extra-files).
|
||||
if [ ! -e "\$p" ] || [ -e "/mnt/\$p" ]; then
|
||||
continue
|
||||
fi
|
||||
cp -a "\$p" "/mnt/\$p"
|
||||
done
|
||||
fi
|
||||
# https://stackoverflow.com/a/13864829
|
||||
if [ ! -z ${NIXOS_NO_CHECK+0} ]; then
|
||||
export NIXOS_NO_CHECK
|
||||
fi
|
||||
nixos-install --no-root-passwd --no-channel-copy --system "$nixosSystem"
|
||||
if [[ ${phases[reboot]} == 1 ]]; then
|
||||
if command -v zpool >/dev/null && [ "\$(zpool list)" != "no pools available" ]; then
|
||||
# we always want to export the zfs pools so people can boot from it without force import
|
||||
umount -Rv /mnt/
|
||||
swapoff -a
|
||||
zpool export -a || true
|
||||
fi
|
||||
nohup sh -c 'sleep 6 && reboot' >/dev/null &
|
||||
fi
|
||||
SSH
|
||||
|
||||
}
|
||||
|
||||
main() {
|
||||
parseArgs "$@"
|
||||
|
||||
if [[ ${vmTest} == y ]]; then
|
||||
if [[ ${hardwareConfigBackend} != "none" ]]; then
|
||||
abort "--vm-test is not supported with --generate-hardware-config. You need to generate the hardware configuration before you can run the VM test." >&2
|
||||
fi
|
||||
runVmTest
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ${buildOn} == "auto" ]]; then
|
||||
checkBuildLocally
|
||||
fi
|
||||
|
||||
# parse flake nixos-install style syntax, get the system attr
|
||||
if [[ -n ${flake} ]]; then
|
||||
if [[ ${buildOn} == "local" ]] && [[ ${hardwareConfigBackend} == "none" ]]; then
|
||||
if [[ ${phases[disko]} == 1 ]]; then
|
||||
diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}")
|
||||
fi
|
||||
if [[ ${phases[install]} == 1 ]]; then
|
||||
nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel")
|
||||
fi
|
||||
fi
|
||||
elif [[ -n ${diskoScript} ]] && [[ -n ${nixosSystem} ]]; then
|
||||
if [[ ! -e ${diskoScript} ]] || [[ ! -e ${nixosSystem} ]]; then
|
||||
abort "${diskoScript} and ${nixosSystem} must be existing store-paths"
|
||||
fi
|
||||
else
|
||||
abort "--flake or --store-paths must be set"
|
||||
fi
|
||||
|
||||
if [[ -n ${SSH_PRIVATE_KEY} ]] && [[ -z ${sshPrivateKeyFile} ]]; then
|
||||
# $sshKeyDir is getting deleted on trap EXIT
|
||||
sshPrivateKeyFile="$sshKeyDir/from-env"
|
||||
(
|
||||
umask 077
|
||||
printf '%s\n' "$SSH_PRIVATE_KEY" >"$sshPrivateKeyFile"
|
||||
)
|
||||
fi
|
||||
|
||||
sshSettings=$(ssh "${sshArgs[@]}" -G "${sshConnection}")
|
||||
sshUser=$(echo "$sshSettings" | awk '/^user / { print $2 }')
|
||||
sshHost=$(echo "$sshSettings" | awk '/^hostname / { print $2 }')
|
||||
|
||||
uploadSshKey
|
||||
|
||||
importFacts
|
||||
|
||||
if [[ ${hasTar-n} == "n" ]]; then
|
||||
abort "no tar command found, but required to unpack kexec tarball"
|
||||
fi
|
||||
|
||||
if [[ ${hasCpio-n} == "n" ]]; then
|
||||
abort "no cpio command found, but required to build the new initrd"
|
||||
fi
|
||||
|
||||
if [[ ${hasSetsid-n} == "n" ]]; then
|
||||
abort "no setsid command found, but required to run the kexec script under a new session"
|
||||
fi
|
||||
|
||||
maybeSudo=""
|
||||
if [[ ${hasSudo-n} == "y" ]]; then
|
||||
maybeSudo="sudo"
|
||||
elif [[ ${hasDoas-n} == "y" ]]; then
|
||||
maybeSudo="doas"
|
||||
fi
|
||||
|
||||
if [[ ${isOs} != "Linux" ]]; then
|
||||
abort "This script requires Linux as the operating system, but got $isOs"
|
||||
fi
|
||||
|
||||
if [[ ${phases[kexec]} == 1 ]]; then
|
||||
runKexec
|
||||
fi
|
||||
|
||||
if [[ ${hardwareConfigBackend} != "none" ]]; then
|
||||
generateHardwareConfig
|
||||
fi
|
||||
|
||||
# Before we do not have a valid hardware configuration we don't know the machine system
|
||||
if [[ ${buildOn} == "auto" ]]; then
|
||||
local remoteSystem
|
||||
remoteSystem=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features nix-command config show system)
|
||||
checkBuildLocally "${remoteSystem}"
|
||||
# if we cannot figure it out at this point, we will build on the remote host
|
||||
if [[ ${buildOn} == "auto" ]]; then
|
||||
buildOn=remote
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${buildOn} != "remote" ]] && [[ -n ${flake} ]] && [[ -z ${diskoScript} ]]; then
|
||||
if [[ ${phases[disko]} == 1 ]]; then
|
||||
diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoAttr}")
|
||||
fi
|
||||
if [[ ${phases[install]} == 1 ]]; then
|
||||
nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel")
|
||||
fi
|
||||
fi
|
||||
|
||||
# Installation will fail if non-root user is used for installer.
|
||||
# Switch to root user by copying authorized_keys.
|
||||
if [[ ${isInstaller} == "y" ]] && [[ ${sshUser} != "root" ]]; then
|
||||
# Allow copy to fail if authorized_keys does not exist, like if using /etc/ssh/authorized_keys.d/
|
||||
runSsh "${maybeSudo} mkdir -p /root/.ssh; ${maybeSudo} cp ~/.ssh/authorized_keys /root/.ssh || true"
|
||||
sshConnection="root@${sshHost}"
|
||||
fi
|
||||
|
||||
if [[ ${phases[disko]} == 1 ]]; then
|
||||
runDisko "$diskoScript"
|
||||
fi
|
||||
|
||||
if [[ ${phases[install]} == 1 ]]; then
|
||||
nixosInstall "$nixosSystem"
|
||||
fi
|
||||
|
||||
if [[ ${phases[reboot]} == 1 ]]; then
|
||||
step Waiting for the machine to become unreachable due to reboot
|
||||
while runSshTimeout -- exit 0; do sleep 1; done
|
||||
fi
|
||||
|
||||
step "Done!"
|
||||
}
|
||||
|
||||
main "$@"
|
|
@ -0,0 +1,21 @@
|
|||
# NixOS-Anywhere Terraform Modules Overview
|
||||
|
||||
The nixos-Anywhere terraform modules allow you to use Terraform for installing
|
||||
and updating NixOS. It simplifies the deployment process by integrating
|
||||
nixos-anywhere functionality.
|
||||
|
||||
Here's a brief overview of each module:
|
||||
|
||||
- **[All-in-One](all-in-one.md)**: This is a consolidated module that first
|
||||
installs NixOS using nixos-anywhere and then keeps it updated with
|
||||
nixos-rebuild. If you choose this, you won't need additional deployment tools
|
||||
like colmena.
|
||||
- **[Install](install.md)**: This module focuses solely on installing NixOS via
|
||||
nixos-anywhere.
|
||||
- **[NixOS-Rebuild](nixos-rebuild.md)**: Use this module to remotely update an
|
||||
existing NixOS machine using nixos-rebuild.
|
||||
- **[Nix-Build](nix-build.md)**: This is a handy helper module designed to build
|
||||
a flake attribute or an attribute from a nix file.
|
||||
|
||||
For detailed information and usage examples, click on the respective module
|
||||
links above.
|
|
@ -0,0 +1,235 @@
|
|||
# All-in-one
|
||||
|
||||
Combines the install and nixos-rebuild module in one interface to install NixOS
|
||||
with nixos-anywhere and then keep it up-to-date with nixos-rebuild.
|
||||
|
||||
## Example
|
||||
|
||||
```hcl
|
||||
locals {
|
||||
ipv4 = "192.0.2.1"
|
||||
}
|
||||
|
||||
module "deploy" {
|
||||
source = "github.com/nix-community/nixos-anywhere//terraform/all-in-one"
|
||||
# with flakes
|
||||
nixos_system_attr = ".#nixosConfigurations.mymachine.config.system.build.toplevel"
|
||||
nixos_partitioner_attr = ".#nixosConfigurations.mymachine.config.system.build.diskoScript"
|
||||
# without flakes
|
||||
# file can use (pkgs.nixos []) function from nixpkgs
|
||||
#file = "${path.module}/../.."
|
||||
#nixos_system_attr = "config.system.build.toplevel"
|
||||
#nixos_partitioner_attr = "config.system.build.diskoScript"
|
||||
|
||||
target_host = local.ipv4
|
||||
# when instance id changes, it will trigger a reinstall
|
||||
instance_id = local.ipv4
|
||||
# useful if something goes wrong
|
||||
# debug_logging = true
|
||||
# build the closure on the remote machine instead of locally
|
||||
# build_on_remote = true
|
||||
# script is below
|
||||
extra_files_script = "${path.module}/decrypt-ssh-secrets.sh"
|
||||
disk_encryption_key_scripts = [{
|
||||
path = "/tmp/secret.key"
|
||||
# script is below
|
||||
script = "${path.module}/decrypt-zfs-key.sh"
|
||||
}]
|
||||
# Optional, arguments passed to special_args here will be available from a NixOS module in this example the `terraform` argument:
|
||||
# { terraform, ... }: {
|
||||
# networking.interfaces.enp0s3.ipv4.addresses = [{ address = terraform.ip; prefixLength = 24; }];
|
||||
# }
|
||||
# Note that this will means that your NixOS configuration will always depend on terraform!
|
||||
# Skip to `Pass data persistently to the NixOS` for an alternative approach
|
||||
#special_args = {
|
||||
# terraform = {
|
||||
# ip = "192.0.2.0"
|
||||
# }
|
||||
#}
|
||||
}
|
||||
```
|
||||
|
||||
_Note:_ You need to mark scripts as executable (`chmod +x`)
|
||||
|
||||
### ./decrypt-ssh-secrets.sh
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
mkdir -p etc/ssh var/lib/secrets
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
umask 0177
|
||||
sops --extract '["initrd_ssh_key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >./var/lib/secrets/initrd_ssh_key
|
||||
|
||||
# restore umask
|
||||
umask 0022
|
||||
|
||||
for keyname in ssh_host_rsa_key ssh_host_rsa_key.pub ssh_host_ed25519_key ssh_host_ed25519_key.pub; do
|
||||
if [[ $keyname == *.pub ]]; then
|
||||
umask 0133
|
||||
else
|
||||
umask 0177
|
||||
fi
|
||||
sops --extract '["'$keyname'"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >"./etc/ssh/$keyname"
|
||||
done
|
||||
```
|
||||
|
||||
### ./decrypt-zfs-key.sh
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
cd "$SCRIPT_DIR"
|
||||
sops --extract '["zfs-key"]' --decrypt "$SCRIPT_DIR/secrets.yaml"
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [nixos-wiki setup](https://github.com/NixOS/nixos-wiki-infra/blob/main/terraform/nixos-wiki/main.tf)
|
||||
for hetzner-cloud
|
||||
|
||||
## Pass data persistently to the NixOS
|
||||
|
||||
This guide outlines how to pass data from Terraform to NixOS by generating a
|
||||
file during Terraform execution and including it in your NixOS configuration.
|
||||
This approach works well if your Terraform and NixOS configurations are stored
|
||||
in the same Git repository.
|
||||
|
||||
### Why Use This Method?
|
||||
|
||||
This method provides a straightforward way to transfer values from Terraform to
|
||||
NixOS without relying on special_args.
|
||||
|
||||
- **Advantages**:
|
||||
- You can continue to use nix build or nixos-rebuild to evaluate your
|
||||
configuration without interruption. Simplifies configuration management by
|
||||
centralizing state in a single repository.
|
||||
- **Disadvantages**:
|
||||
- Deploying new machines requires tracking additional state. Every time
|
||||
Terraform updates the JSON file, you'll need to commit these changes to your
|
||||
repository.
|
||||
|
||||
### Implementation
|
||||
|
||||
Add the following snippet to your Terraform configuration to create and manage a
|
||||
JSON file containing the necessary variables for NixOS. This file will be
|
||||
automatically added to your Git repository, ensuring the data persists.
|
||||
|
||||
Assuming you have your terraform and nixos configuration in the same git
|
||||
repository. You can use the following snippet to `git add` a file generated by
|
||||
`terraform` during execution to pass data from terraform to NixOS. These changes
|
||||
should be committed afterwards. This is an alternative over using
|
||||
`special_args`. Advantage: you can still use nix build or nixos-rebuild on your
|
||||
flake to evaluate your configuration. Disadvantage: Deploying new machines also
|
||||
means you need to track additional state and make additional commits whenever
|
||||
terraform updates the json file.
|
||||
|
||||
```hcl
|
||||
locals {
|
||||
nixos_vars_file = "nixos-vars.json" # Path to the JSON file containing NixOS variables
|
||||
nixos_vars = {
|
||||
ip = "192.0.2.0" # Replace with actual variables
|
||||
}
|
||||
}
|
||||
resource "local_file" "nixos_vars" {
|
||||
content = jsonencode(local.nixos_vars) # Converts variables to JSON
|
||||
filename = local.nixos_vars_file # Specifies the output file path
|
||||
file_permission = "600"
|
||||
|
||||
# Automatically adds the generated file to Git
|
||||
provisioner "local-exec" {
|
||||
interpreter = ["bash", "-c"]
|
||||
command = "git add -f '${local.nixos_vars_file}'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After applying the Terraform changes, ensure you commit the updated
|
||||
`nixos-vars.json` file to your Git repository:
|
||||
|
||||
```bash
|
||||
git commit -m "Update NixOS variables from Terraform"
|
||||
```
|
||||
|
||||
You can import this json file into your configuration like this:
|
||||
|
||||
```nix
|
||||
let
|
||||
nixosVars = builtins.fromJSON (builtins.readFile ./nixos-vars.json);
|
||||
in
|
||||
{
|
||||
# Example usage of imported variables
|
||||
networking.hostName = "example-machine";
|
||||
networking.interfaces.eth0.ipv4.addresses = [
|
||||
{
|
||||
address = nixosVars.ip; # Use the IP from nixos-vars.json
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
<!-- BEGIN_TF_DOCS -->
|
||||
|
||||
## Requirements
|
||||
|
||||
No requirements.
|
||||
|
||||
## Providers
|
||||
|
||||
No providers.
|
||||
|
||||
## Modules
|
||||
|
||||
| Name | Source | Version |
|
||||
| -------------------------------------------------------------------------------------- | ---------------- | ------- |
|
||||
| <a name="module_install"></a> [install](#module_install) | ../install | n/a |
|
||||
| <a name="module_nixos-rebuild"></a> [nixos-rebuild](#module_nixos-rebuild) | ../nixos-rebuild | n/a |
|
||||
| <a name="module_partitioner-build"></a> [partitioner-build](#module_partitioner-build) | ../nix-build | n/a |
|
||||
| <a name="module_system-build"></a> [system-build](#module_system-build) | ../nix-build | n/a |
|
||||
|
||||
## Resources
|
||||
|
||||
No resources.
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | :------: |
|
||||
| <a name="input_debug_logging"></a> [debug\_logging](#input_debug_logging) | Enable debug logging | `bool` | `false` | no |
|
||||
| <a name="input_deployment_ssh_key"></a> [deployment\_ssh\_key](#input_deployment_ssh_key) | Content of private key used to deploy to the target\_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable | `string` | `null` | no |
|
||||
| <a name="input_disk_encryption_key_scripts"></a> [disk\_encryption\_key\_scripts](#input_disk_encryption_key_scripts) | Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system | <pre>list(object({<br> path = string<br> script = string<br> }))</pre> | `[]` | no |
|
||||
| <a name="input_extra_environment"></a> [extra\_environment](#input_extra_environment) | Extra environment variables to be set during installation. This can be useful to set extra variables for the extra\_files\_script or disk\_encryption\_key\_scripts | `map(string)` | `{}` | no |
|
||||
| <a name="input_extra_files_script"></a> [extra\_files\_script](#input_extra_files_script) | A script that should place files in the current directory that will be copied to the targets / directory | `string` | `null` | no |
|
||||
| <a name="input_file"></a> [file](#input_file) | Nix file containing the nixos\_system\_attr and nixos\_partitioner\_attr. Use this if you are not using flake | `string` | `null` | no |
|
||||
| <a name="input_install_port"></a> [install\_port](#input_install_port) | SSH port used to connect to the target\_host, before installing NixOS. If null than the value of `target_port` is used | `string` | `null` | no |
|
||||
| <a name="input_install_ssh_key"></a> [install\_ssh\_key](#input_install_ssh_key) | Content of private key used to connect to the target\_host during initial installation | `string` | `null` | no |
|
||||
| <a name="input_install_user"></a> [install\_user](#input_install_user) | SSH user used to connect to the target\_host, before installing NixOS. If null than the value of `target_host` is used | `string` | `null` | no |
|
||||
| <a name="input_instance_id"></a> [instance\_id](#input_instance_id) | The instance id of the target\_host, used to track when to reinstall the machine | `string` | `null` | no |
|
||||
| <a name="input_kexec_tarball_url"></a> [kexec\_tarball\_url](#input_kexec_tarball_url) | NixOS kexec installer tarball url | `string` | `null` | no |
|
||||
| <a name="input_nix_options"></a> [nix\_options](#input_nix_options) | the options of nix | `map(string)` | `{}` | no |
|
||||
| <a name="input_nixos_facter_path"></a> [nixos\_facter\_path](#input_nixos_facter_path) | Path to which to write a `facter.json` generated by `nixos-facter`. | `string` | `""` | no |
|
||||
| <a name="input_nixos_generate_config_path"></a> [nixos\_generate\_config\_path](#input_nixos_generate_config_path) | Path to which to write a `hardware-configuration.nix` generated by `nixos-generate-config`. | `string` | `""` | no |
|
||||
| <a name="input_nixos_partitioner_attr"></a> [nixos\_partitioner\_attr](#input_nixos_partitioner_attr) | Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. `config.system.build.diskNoDeps` is provided by the disko nixos module | `string` | n/a | yes |
|
||||
| <a name="input_nixos_system_attr"></a> [nixos\_system\_attr](#input_nixos_system_attr) | The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes | `string` | n/a | yes |
|
||||
| <a name="input_no_reboot"></a> [no\_reboot](#input_no_reboot) | DEPRECATED: Use `phases` instead. Do not reboot after installation | `bool` | `false` | no |
|
||||
| <a name="input_phases"></a> [phases](#input_phases) | Phases to run. See `nixos-anywhere --help` for more information | `set(string)` | <pre>[<br> "kexec",<br> "disko",<br> "install",<br> "reboot"<br>]</pre> | no |
|
||||
| <a name="input_special_args"></a> [special\_args](#input_special_args) | A map exposed as NixOS's `specialArgs` thru a file. | `any` | `{}` | no |
|
||||
| <a name="input_build_on_remote"></a> [build\_on\_remote](#input_build_on_remote) | Build the closure on the remote machine instead of building it locally and copying it over | `bool` | `false` | no |
|
||||
| <a name="input_stop_after_disko"></a> [stop\_after\_disko](#input_stop_after_disko) | DEPRECATED: Use `phases` instead. Exit after disko formatting | `bool` | `false` | no |
|
||||
| <a name="input_target_host"></a> [target\_host](#input_target_host) | DNS host to deploy to | `string` | n/a | yes |
|
||||
| <a name="input_target_port"></a> [target\_port](#input_target_port) | SSH port used to connect to the target\_host after installing NixOS. If install\_port is not set than this port is also used before installing. | `number` | `22` | no |
|
||||
| <a name="input_target_user"></a> [target\_user](#input_target_user) | SSH user used to connect to the target\_host after installing NixOS. If install\_user is not set than this user is also used before installing. | `string` | `"root"` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
| ----------------------------------------------------- | ----------- |
|
||||
| <a name="output_result"></a> [result](#output_result) | n/a |
|
||||
|
||||
<!-- END_TF_DOCS -->
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue