mirror of
https://github.com/serokell/deploy-rs.git
synced 2024-09-17 13:37:39 +03:00
Add interface with json schema, fix flake-less issues, put setActivate and jsonSchema check in flake lib
This commit is contained in:
parent
5674670a59
commit
7c00fd2761
@ -1,6 +1,73 @@
|
||||
{
|
||||
"nodes": {
|
||||
"deploy-rs": {
|
||||
"inputs": {
|
||||
"naersk": "naersk",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"utils": "utils"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1601668691,
|
||||
"narHash": "sha256-1mWf71DPRNgTIUKJ4Dy+CjoyZo4JkPdrwjYJy2UzqZE=",
|
||||
"type": "git",
|
||||
"url": "file:///home/notgne2/Dev/Serokell/deploy-rs"
|
||||
},
|
||||
"original": {
|
||||
"owner": "serokell",
|
||||
"repo": "deploy-rs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1597138680,
|
||||
"narHash": "sha256-3pDN/W17wjVDbrkgo60xQSb24+QAPQ7ulsUq5atNni0=",
|
||||
"owner": "nmattia",
|
||||
"repo": "naersk",
|
||||
"rev": "529e910a3f423a8211f8739290014b754b2555b6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nmattia",
|
||||
"ref": "master",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1601091160,
|
||||
"narHash": "sha256-26UI9LGjRO8Sv253zJZkoapP260QkJPQ2+vRyC1i+kI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2768436826543af2b1540e4fe6b5afa15850e155",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1600387253,
|
||||
"narHash": "sha256-WtdpHuiunPF9QMlcXrWJkESuIjSSjP9WMOKvYQS/D7M=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "72b9660dc18ba347f7cd41a9504fc181a6d87dc3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1592491430,
|
||||
"narHash": "sha256-7WNpr16iUyjG4caad137nCqxXNTdct202jy05lslZXA=",
|
||||
@ -16,7 +83,23 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
"deploy-rs": "deploy-rs",
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"locked": {
|
||||
"lastModified": 1600209923,
|
||||
"narHash": "sha256-zoOWauTliFEjI++esk6Jzk7QO5EKpddWXQm9yQK24iM=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "3cd06d3c1df6879c9e41cb2c33113df10566c760",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5,7 +5,9 @@
|
||||
{
|
||||
description = "Deploy GNU hello to localhost";
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
inputs.deploy-rs.url = "github:serokell/deploy-rs";
|
||||
|
||||
outputs = { self, nixpkgs, deploy-rs }:
|
||||
let
|
||||
setActivate = base: activate: nixpkgs.legacyPackages.x86_64-linux.symlinkJoin {
|
||||
name = ("activatable-" + base.name);
|
||||
@ -29,16 +31,10 @@
|
||||
hostname = "localhost";
|
||||
profiles.hello = {
|
||||
user = "balsoft";
|
||||
path = setActivate nixpkgs.legacyPackages.x86_64-linux.hello "./bin/hello";
|
||||
path = deploy-rs.lib.x86_64-linux.setActivate nixpkgs.legacyPackages.x86_64-linux.hello "./bin/hello";
|
||||
};
|
||||
};
|
||||
checks = builtins.mapAttrs
|
||||
(_: pkgs: {
|
||||
jsonschema = pkgs.runCommandNoCC "jsonschema-deploy-simple" { }
|
||||
"${pkgs.python3.pkgs.jsonschema}/bin/jsonschema -i ${
|
||||
pkgs.writeText "deploy.json" (builtins.toJSON self.deploy)
|
||||
} ${../../interface/deploy.json} && touch $out";
|
||||
})
|
||||
nixpkgs.legacyPackages;
|
||||
|
||||
checks = { "x86_64-linux" = { jsonSchema = deploy-rs.lib.x86_64-linux.checkSchema self.deploy; }; };
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,73 @@
|
||||
{
|
||||
"nodes": {
|
||||
"deploy-rs": {
|
||||
"inputs": {
|
||||
"naersk": "naersk",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"utils": "utils"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1601668691,
|
||||
"narHash": "sha256-HvzPMsgSOQfCRoPtkwLRv09CkNjOsLHjcZtyHF+8Zbs=",
|
||||
"type": "git",
|
||||
"url": "file:///home/notgne2/Dev/Serokell/deploy-rs"
|
||||
},
|
||||
"original": {
|
||||
"owner": "serokell",
|
||||
"repo": "deploy-rs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1597138680,
|
||||
"narHash": "sha256-3pDN/W17wjVDbrkgo60xQSb24+QAPQ7ulsUq5atNni0=",
|
||||
"owner": "nmattia",
|
||||
"repo": "naersk",
|
||||
"rev": "529e910a3f423a8211f8739290014b754b2555b6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nmattia",
|
||||
"ref": "master",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1601091160,
|
||||
"narHash": "sha256-26UI9LGjRO8Sv253zJZkoapP260QkJPQ2+vRyC1i+kI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2768436826543af2b1540e4fe6b5afa15850e155",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1600387253,
|
||||
"narHash": "sha256-WtdpHuiunPF9QMlcXrWJkESuIjSSjP9WMOKvYQS/D7M=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "72b9660dc18ba347f7cd41a9504fc181a6d87dc3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1592491430,
|
||||
"narHash": "sha256-7WNpr16iUyjG4caad137nCqxXNTdct202jy05lslZXA=",
|
||||
@ -16,7 +83,23 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
"deploy-rs": "deploy-rs",
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"locked": {
|
||||
"lastModified": 1600209923,
|
||||
"narHash": "sha256-zoOWauTliFEjI++esk6Jzk7QO5EKpddWXQm9yQK24iM=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "3cd06d3c1df6879c9e41cb2c33113df10566c760",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5,65 +5,42 @@
|
||||
{
|
||||
description = "Deploy a full system with hello service as a separate profile";
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
setActivate = base: activate: nixpkgs.legacyPackages.x86_64-linux.symlinkJoin {
|
||||
name = ("activatable-" + base.name);
|
||||
paths = [
|
||||
base
|
||||
(nixpkgs.legacyPackages.x86_64-linux.writeTextFile {
|
||||
name = base.name + "-activate-path";
|
||||
text = ''
|
||||
#!${nixpkgs.legacyPackages.x86_64-linux.runtimeShell}
|
||||
${activate}
|
||||
'';
|
||||
executable = true;
|
||||
destination = "/activate";
|
||||
})
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
nixosConfigurations.example-nixos-system = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [ ./configuration.nix ];
|
||||
};
|
||||
inputs.deploy-rs.url = "github:serokell/deploy-rs";
|
||||
|
||||
nixosConfigurations.bare = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules =
|
||||
[ ./bare.nix "${nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix" ];
|
||||
};
|
||||
outputs = { self, nixpkgs, deploy-rs }: {
|
||||
nixosConfigurations.example-nixos-system = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [ ./configuration.nix ];
|
||||
};
|
||||
|
||||
# This is the application we actually want to run
|
||||
defaultPackage.x86_64-linux = import ./hello.nix nixpkgs;
|
||||
nixosConfigurations.bare = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules =
|
||||
[ ./bare.nix "${nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix" ];
|
||||
};
|
||||
|
||||
deploy.nodes.example = {
|
||||
sshOpts = [ "-p" "2221" ];
|
||||
hostname = "localhost";
|
||||
fastConnection = true;
|
||||
profiles = {
|
||||
system = {
|
||||
sshUser = "admin";
|
||||
path =
|
||||
setActivate self.nixosConfigurations.example-nixos-system.config.system.build.toplevel "./bin/switch-to-configuration switch";
|
||||
user = "root";
|
||||
};
|
||||
hello = {
|
||||
sshUser = "hello";
|
||||
path = setActivate self.defaultPackage.x86_64-linux "./bin/activate";
|
||||
user = "hello";
|
||||
};
|
||||
# This is the application we actually want to run
|
||||
defaultPackage.x86_64-linux = import ./hello.nix nixpkgs;
|
||||
|
||||
deploy.nodes.example = {
|
||||
sshOpts = [ "-p" "2221" ];
|
||||
hostname = "localhost";
|
||||
fastConnection = true;
|
||||
profiles = {
|
||||
system = {
|
||||
sshUser = "admin";
|
||||
path =
|
||||
deploy-rs.lib.x86_64-linux.setActivate self.nixosConfigurations.example-nixos-system.config.system.build.toplevel "./bin/switch-to-configuration switch";
|
||||
user = "root";
|
||||
};
|
||||
hello = {
|
||||
sshUser = "hello";
|
||||
path = deploy-rs.lib.x86_64-linux.setActivate self.defaultPackage.x86_64-linux "./bin/activate";
|
||||
user = "hello";
|
||||
};
|
||||
};
|
||||
|
||||
checks = builtins.mapAttrs
|
||||
(_: pkgs: {
|
||||
jsonschema = pkgs.runCommandNoCC "jsonschema-deploy-system" { }
|
||||
"${pkgs.python3.pkgs.jsonschema}/bin/jsonschema -i ${
|
||||
pkgs.writeText "deploy.json" (builtins.toJSON self.deploy)
|
||||
} ${../../interface/deploy.json} && touch $out";
|
||||
})
|
||||
nixpkgs.legacyPackages;
|
||||
};
|
||||
|
||||
checks = { "x86_64-linux" = { jsonSchema = deploy-rs.lib.x86_64-linux.checkSchema self.deploy; }; };
|
||||
};
|
||||
}
|
||||
|
25
flake.nix
25
flake.nix
@ -14,12 +14,35 @@
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
naersk-lib = pkgs.callPackage naersk { };
|
||||
in {
|
||||
setActivate = base: activate: pkgs.symlinkJoin {
|
||||
name = ("activatable-" + base.name);
|
||||
paths = [
|
||||
base
|
||||
(pkgs.writeTextFile {
|
||||
name = base.name + "-activate-path";
|
||||
text = ''
|
||||
#!${pkgs.runtimeShell}
|
||||
${activate}
|
||||
'';
|
||||
executable = true;
|
||||
destination = "/activate";
|
||||
})
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
defaultPackage = naersk-lib.buildPackage ./.;
|
||||
|
||||
defaultApp = {
|
||||
type = "app";
|
||||
program = "${self.defaultPackage."${system}"}/bin/deploy";
|
||||
};
|
||||
|
||||
lib = {
|
||||
inherit setActivate;
|
||||
|
||||
checkSchema = 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";
|
||||
};
|
||||
});
|
||||
}
|
||||
|
32
interface/README.md
Normal file
32
interface/README.md
Normal file
@ -0,0 +1,32 @@
|
||||
A flake must have a `deploy` output with the following structure:
|
||||
|
||||
```
|
||||
deploy
|
||||
├── <generic args>
|
||||
└── nodes
|
||||
├── <NODE>
|
||||
│ ├── <generic args>
|
||||
│ ├── hostname
|
||||
│ └── profiles
|
||||
│ ├── <PROFILE>
|
||||
│ │ ├── <generic args>
|
||||
│ │ ├── bootstrap
|
||||
│ │ └── path
|
||||
│ └── <PROFILE>...
|
||||
└── <NODE>...
|
||||
|
||||
```
|
||||
|
||||
Where `<generic args>` 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 `<PROFILE>` taking precedence over `<NODE>` and `<NODE>` taking precedence over top-level.
|
||||
|
||||
Values can be overridden for all the profiles deployed by setting environment variables with the same names as the profile, for example `sshUser=foobar nix run github:serokell/deploy .` will connect to all nodes as `foobar@<NODE>.hostname`.
|
103
interface/deploy.json
Normal file
103
interface/deploy.json
Normal file
@ -0,0 +1,103 @@
|
||||
{
|
||||
"$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"
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_settings": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"hostname": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"hostname"
|
||||
]
|
||||
},
|
||||
"profile_settings": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"bootstrap": {
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"profiles": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"[A-z][A-z0-9_-]*": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/generic_settings"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/profile_settings"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -10,6 +10,7 @@ use tokio::process::Command;
|
||||
use merge::Merge;
|
||||
|
||||
extern crate pretty_env_logger;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
@ -177,12 +178,14 @@ async fn get_deployment_data(
|
||||
|
||||
let mut c = match supports_flakes {
|
||||
true => Command::new("nix"),
|
||||
false => Command::new("nix-instanciate"),
|
||||
false => Command::new("nix-instantiate"),
|
||||
};
|
||||
|
||||
let mut build_command = match supports_flakes {
|
||||
true => {
|
||||
c.arg("eval").arg("--json").arg(format!("{}#deploy", repo))
|
||||
c.arg("eval")
|
||||
.arg("--json")
|
||||
.arg(format!("{}#deploy", repo))
|
||||
}
|
||||
false => {
|
||||
c
|
||||
@ -190,7 +193,7 @@ async fn get_deployment_data(
|
||||
.arg("--read-write-mode")
|
||||
.arg("--json")
|
||||
.arg("--eval")
|
||||
.arg("--E")
|
||||
.arg("-E")
|
||||
.arg(format!("let r = import {}/.; in if builtins.isFunction r then (r {{}}).deploy else r.deploy", repo))
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user