From 6ff3994dbb9b44a919ded00882db9b57f92fe228 Mon Sep 17 00:00:00 2001
From: notgne2
Date: Sat, 7 Nov 2020 11:56:22 -0700
Subject: Greatly expand documentation
---
README.md | 79 ++++++++++++++++++++++++----
flake.nix | 2 +-
interface.json | 117 ++++++++++++++++++++++++++++++++++++++++++
interface.json.license | 3 ++
interface/README.md | 39 --------------
interface/deploy.json | 117 ------------------------------------------
interface/deploy.json.license | 3 --
7 files changed, 190 insertions(+), 170 deletions(-)
create mode 100644 interface.json
create mode 100644 interface.json.license
delete mode 100644 interface/README.md
delete mode 100644 interface/deploy.json
delete mode 100644 interface/deploy.json.license
diff --git a/README.md b/README.md
index c7bb5a3..21638d9 100644
--- a/README.md
+++ b/README.md
@@ -38,9 +38,11 @@ This is the core of how `deploy-rs` was designed, any number of these can run on
# A derivation containing your required software, and a script to activate it in `${path}/activate`
# For ease of use, `deploy-rs` provides a function to easy all this required activation script to any derivation
+ # Both the working directory and `$PROFILE` will point to `profilePath`
path = deploy-rs.lib.x86_64-linux.setActivate pkgs.hello "./bin/hello";
# An optional path to where your profile should be installed to, this is useful if you want to use a common profile name across multiple users, but would have conflicts in your node's profile list.
+ # This will default to `"/nix/var/nix/profiles/$PROFILE_NAME` if `user` is root (see: generic options), and `/nix/var/nix/profiles/per-user/$USER/$PROFILE_NAME` if it is not.
profilePath = "/nix/var/nix/profiles/per-user/someuser/someprofile";
# ...generic options... (see lower section)
@@ -57,11 +59,13 @@ This defines a single node/server, and the profiles you intend it to run.
hostname = "my.server.gov";
# An optional list containing the order you want profiles to be deployed.
+ # This will take effect whenever you run `deploy` without specifying a profile, causing it to deploy every profile automatically.
profilesOrder = [ "something" "system" ];
profiles = {
- system = {}; # Definition shown above
- something = {}; # Definition shown above
+ # Definition format shown above
+ system = {};
+ something = {};
};
# ...generic options... (see lower section)
@@ -75,8 +79,9 @@ This is the top level attribute containing all of the options for this tool
```nix
{
nodes = {
- my-node = {}; # Definition shown above
- another-node = {}; # Definition shown above
+ # Definition format shown above
+ my-node = {};
+ another-node = {};
};
# ...generic options... (see lower section)
@@ -89,15 +94,69 @@ This is a set of options that can be put in any of the above definitions, with t
```nix
{
- sshUser = "admin"; # This is the user that deploy-rs will use when connecting
- user = "root"; # This is the user that the profile will be deployed to (will use sudo if not the same as above)
- sshOpts = [ "-p" "2121" ]; # These are arguments that will be passed to SSH
- fastConnection = false; # Fast connection to the node. If this is true, copy the whole closure instead of letting the node substitute
- autoRollback = true; # If the previous profile should be re-activated if activation fails
+ # This is the user that deploy-rs will use when connecting.
+ # This will default to your own username if not specified anywhere
+ sshUser = "admin";
+
+ # This is the user that the profile will be deployed to (will use sudo if not the same as above).
+ # If `sshUser` is specified, this will be the default (though it will _not_ default to your own username)
+ user = "root";
+
+ # This is an optional list of arguments that will be passed to SSH.
+ sshOpts = [ "-p" "2121" ];
+
+ # Fast connection to the node. If this is true, copy the whole closure instead of letting the node substitute.
+ # This defaults to `false`
+ fastConnection = false;
+
+ # If the previous profile should be re-activated if activation fails.
+ # this defaults to `true`
+ autoRollback = true;
+
+ # If the node should wait for `deploy` to connect for a second time after activation, to confirm the server has not been ruined.
+ # This defaults to `false`, though it is strongly recommend you activate it if you value safety
+ magicRollback = true;
+
+ # The path which deploy-rs will use for temporary files, this is currently only used by `magicRollback` to create an inotify watcher in
+ # If not specified, this will default to `/tmp/deploy-rs`
+ # (if `magicRollback` is in use, this _must_ be writable by `user`)
+ tempPath = "/home/someuser/.deploy-rs";
+}
+```
+
+### Putting it together
+
+`deploy-rs` is designed to be used with Nix flakes (this currently requires an unstable version of Nix to work with). There is a Flake-less mode of operation which will automatically be used if your available Nix version does not support flakes, however you will likely want to use a flake anyway, just with `flake-compat` (see [this wiki page](https://nixos.wiki/wiki/Flakes) for usage).
+
+`deploy-rs` also outputs a `lib` attribute, with tools used to make your definitions simpler and safer, including `deploy-rs.lib.${system}.setActivate` (see prior section "Profile"), and `deploy-rs.lib.${system}.deployChecks` which will let `nix flake check` ensure your deployment is defined correctly.
+
+A basic example of a flake that works with `deploy-rs` and deploys a simple NixOS configuration could look like this
+
+```nix
+{
+ description = "Deployment for my server cluster";
+
+ # For accessing `deploy-rs`'s utility Nix functions
+ inputs.deploy-rs.url = "github:serokell/deploy-rs";
+
+ outputs = { self, nixpkgs, deploy-rs }: {
+ nixosConfigurations.some-random-system = nixpkgs.lib.nixosSystem {
+ system = "x86_64-linux";
+ modules = [ ./some-random-system/configuration.nix ];
+ };
+
+ deploy.nodes.some-random-system.profiles.system = {
+ user = "root";
+ path = deploy-rs.lib.x86_64-linux.setActivate self.nixosConfigurations.some-random-system.config.system.build.toplevel "./bin/switch-to-configuration switch";
+ };
+ };
+
+ # This is highly advised, and will prevent many possible mistakes
+ checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
}
```
-A stronger definition of the schema is in the [interface directory](./interface), and full working examples Nix expressions/configurations are in the [examples folder](./examples).
+There are full working deploy-rs Nix expressions in the [examples folder](./examples), and there is a JSON schema [here](./interface.json) which is used internally by the `deployChecks` mentioned above to validate your expressions.
## Idea
diff --git a/flake.nix b/flake.nix
index 597092c..81a639e 100644
--- a/flake.nix
+++ b/flake.nix
@@ -57,7 +57,7 @@
checks = {
schema = deploy: pkgs.runCommandNoCC "jsonschema-deploy-system" { } ''
- ${pkgs.python3.pkgs.jsonschema}/bin/jsonschema -i ${pkgs.writeText "deploy.json" (builtins.toJSON deploy)} ${./interface/deploy.json} && touch $out
+ ${pkgs.python3.pkgs.jsonschema}/bin/jsonschema -i ${pkgs.writeText "deploy.json" (builtins.toJSON deploy)} ${./interface.json} && touch $out
'';
activate = deploy:
diff --git a/interface.json b/interface.json
new file mode 100644
index 0000000..fa45e50
--- /dev/null
+++ b/interface.json
@@ -0,0 +1,117 @@
+{
+ "$schema": "http://json-schema.org/draft/2019-09/schema#",
+ "title": "Deploy",
+ "description": "Matches a correct deploy attribute of a flake",
+ "definitions": {
+ "generic_settings": {
+ "type": "object",
+ "properties": {
+ "sshUser": {
+ "type": "string"
+ },
+ "user": {
+ "type": "string"
+ },
+ "sshOpts": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "fastConnection": {
+ "type": "boolean"
+ },
+ "autoRollback": {
+ "type": "boolean"
+ },
+ "magicRollback": {
+ "type": "boolean"
+ },
+ "confirmTimeout": {
+ "type": "integer"
+ },
+ "tempPath": {
+ "type": "string"
+ }
+ }
+ },
+ "node_settings": {
+ "type": "object",
+ "properties": {
+ "hostname": {
+ "type": "string"
+ },
+ "profilesOrder": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "uniqueItems": true
+ },
+ "profiles": {
+ "type": "object",
+ "patternProperties": {
+ "[A-z][A-z0-9_-]*": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/generic_settings"
+ },
+ {
+ "$ref": "#/definitions/profile_settings"
+ }
+ ]
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "required": [
+ "hostname"
+ ]
+ },
+ "profile_settings": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "bootstrap": {
+ "type": "string"
+ },
+ "profilePath": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "path"
+ ]
+ }
+ },
+ "type": "object",
+ "allOf": [
+ {
+ "$ref": "#/definitions/generic_settings"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "nodes": {
+ "type": "object",
+ "patternProperties": {
+ "[A-z][A-z0-9_-]*": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/generic_settings"
+ },
+ {
+ "$ref": "#/definitions/node_settings"
+ }
+ ]
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/interface.json.license b/interface.json.license
new file mode 100644
index 0000000..9e9897d
--- /dev/null
+++ b/interface.json.license
@@ -0,0 +1,3 @@
+SPDX-FileCopyrightText: 2020 Serokell
+
+SPDX-License-Identifier: MPL-2.0
\ No newline at end of file
diff --git a/interface/README.md b/interface/README.md
deleted file mode 100644
index f61a69f..0000000
--- a/interface/README.md
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-A flake must have a `deploy` output with the following structure:
-
-```
-deploy
-├──
-└── nodes
- ├──
- │ ├──
- │ ├── hostname
- │ ├── profilesOrder
- │ └── profiles
- │ ├──
- │ │ ├──
- │ │ ├── bootstrap
- │ │ ├── profilePath
- │ │ └── path
- │ └── ...
- └── ...
-```
-
-Where `` are all optional and can be one or multiple of:
-
-- `sshUser` -- user to connect as
-- `user` -- user to install and activate profiles with
-- `sshOpts` -- options passed to `nix copy` and `ssh`
-- `fastConnection` -- whether the connection from this host to the target one is fast (if it is, don't substitute on target and copy the entire closure) [default: `false`]
-- `autoRollback` -- whether to roll back when the deployment fails [default: `false`]
-
-A formal definition for the structure can be found in [the JSON schema](./deploy.json)
-
-For every profile of every node, arguments are merged with `` taking precedence over `` and `` taking precedence over top-level.
-
-Certain read values can be overridden by supplying flags to the deploy binary, for example `deploy --auto-rollback true .` will enable automatic rollback for all nodes being deployed to, regardless of settings.
\ No newline at end of file
diff --git a/interface/deploy.json b/interface/deploy.json
deleted file mode 100644
index fa45e50..0000000
--- a/interface/deploy.json
+++ /dev/null
@@ -1,117 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft/2019-09/schema#",
- "title": "Deploy",
- "description": "Matches a correct deploy attribute of a flake",
- "definitions": {
- "generic_settings": {
- "type": "object",
- "properties": {
- "sshUser": {
- "type": "string"
- },
- "user": {
- "type": "string"
- },
- "sshOpts": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "fastConnection": {
- "type": "boolean"
- },
- "autoRollback": {
- "type": "boolean"
- },
- "magicRollback": {
- "type": "boolean"
- },
- "confirmTimeout": {
- "type": "integer"
- },
- "tempPath": {
- "type": "string"
- }
- }
- },
- "node_settings": {
- "type": "object",
- "properties": {
- "hostname": {
- "type": "string"
- },
- "profilesOrder": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "uniqueItems": true
- },
- "profiles": {
- "type": "object",
- "patternProperties": {
- "[A-z][A-z0-9_-]*": {
- "allOf": [
- {
- "$ref": "#/definitions/generic_settings"
- },
- {
- "$ref": "#/definitions/profile_settings"
- }
- ]
- }
- },
- "additionalProperties": false
- }
- },
- "required": [
- "hostname"
- ]
- },
- "profile_settings": {
- "type": "object",
- "properties": {
- "path": {
- "type": "string"
- },
- "bootstrap": {
- "type": "string"
- },
- "profilePath": {
- "type": "string"
- }
- },
- "required": [
- "path"
- ]
- }
- },
- "type": "object",
- "allOf": [
- {
- "$ref": "#/definitions/generic_settings"
- },
- {
- "type": "object",
- "properties": {
- "nodes": {
- "type": "object",
- "patternProperties": {
- "[A-z][A-z0-9_-]*": {
- "allOf": [
- {
- "$ref": "#/definitions/generic_settings"
- },
- {
- "$ref": "#/definitions/node_settings"
- }
- ]
- }
- },
- "additionalProperties": false
- }
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/interface/deploy.json.license b/interface/deploy.json.license
deleted file mode 100644
index 9e9897d..0000000
--- a/interface/deploy.json.license
+++ /dev/null
@@ -1,3 +0,0 @@
-SPDX-FileCopyrightText: 2020 Serokell
-
-SPDX-License-Identifier: MPL-2.0
\ No newline at end of file
--
cgit v1.2.3