- Notifications
You must be signed in to change notification settings - Fork69
DBCDK/morph
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Morph is a tool for managing existing NixOS hosts - basically a fancy wrapper aroundnix-build,nix copy,nix-env,/nix/store/.../bin/switch-to-configuration,scp and more.Morph supports updating multiple hosts in a row, and with support for health checks makes it fairly safe to do so.
- multi host support
- health checks
- no state
Morph requiresnix (at least v2),ssh andscp to be available on$PATH.It should work on any modern Linux distribution, but NixOS is the only one we test on.
Pre-built binaries are not provided, since we install morph through an overlay.
The easiest way to get morph up and running is to fork this repository and runnix-build, which should result in a store path containing the morph binary.Consider checking out a specific tag, or at least pin the version of morph you're using somehow.
All commands support a--help flag;morph --help as of v1.0.0:
$ morph --helpusage: morph [<flags>] <command> [<args> ...]NixOS host managerFlags: --help Show context-sensitive help (also try --help-long and --help-man). --version Show application version. --dry-run Don't do anything, just eval and print changesCommands: help [<command>...] Show help. build [<flags>] <deployment> Evaluate and build deployment configuration to the local Nix store push [<flags>] <deployment> Build and transfer items from the local Nix store to target machines deploy [<flags>] <deployment> <switch-action> Build, push and activate new configuration on machines according to switch-action check-health [<flags>] <deployment> Run health checks upload-secrets [<flags>] <deployment> Upload secrets exec [<flags>] <deployment> <command>... Execute arbitrary commands on machinesNotably,morph deploy requires a<switch-action>.The switch-action must be one ofdry-activate,test,switch orboot corresponding tonixos-rebuild arguments of the same name.Refer to theNixOS manual for a detailed description of switch-actions.
For help on this and other commands, runmorph <cmd> --help.
Example deployments can be found in theexamples directory, and built as follows:
$ morph build examples/simple.nixSelected 2/2 hosts (name filter:-0, limits:-0): 0: db01 (secrets: 0, health checks: 0) 1: web01 (secrets: 0, health checks: 0)<probably lots of nix-build output>/nix/store/grvny5ga2i6jdxjjbh2ipdz7h50swi1n-morphnix result path:/nix/store/grvny5ga2i6jdxjjbh2ipdz7h50swi1n-morphThe result path is written twice, which is a bit silly, but the reason is that only the result path is written to stdout, and everything else (includingnix-build output) is redirected to stderr.This makes it easy to use morph for scripting, e.g. if one want to build using morph and thennix copy the result path somewhere else.
Note thatexamples/simple.nix contain two different hosts definitions, and a lot of copy paste.All the usual nix tricks can of course be used to avoid duplication.
Hosts can be deployed with thedeploy command as follows:morph deploy examples/simple.nix (this will fail without modifyingexamples/simple.nix).
All hosts defined in a deployment file is returned to morph as a list of hosts, which can be manipulated with the following flags:
--on globcan be used to select hosts by name, with support for glob patterns--limit nputs an upper limit on the number of hosts--skip nignore the firstnhosts--every nselects every n'th host, useful for e.g. selecting all even (or odd) numbered hosts
(all relevant commands should already support these flags.)
The ordering currently can't be changed, but should be deterministic because of nix.
Most commands output a header like this:
Selected 4/17 hosts (name filter:-6, limits:-7): 0: foo-p02 (secrets: 0, health checks: 1) 1: foo-p05 (secrets: 0, health checks: 1) 2: foo-p08 (secrets: 0, health checks: 1) 3: foo-p11 (secrets: 0, health checks: 1)The output is pretty self explanatory, except probably for the last bit of the first line.name filter shows the change in number of hosts after glob matching on the hosts name, andlimits shows the change after applying--limit,--skip and--every.
Each host can be tagged with an arbitrary amount of tags, which can be used to select and sort hosts.
To tag a host, use thedeployment.tags option, e.g.deployment.tags = [ "prod" "master" "rack-17" ]. Hosts can now be selected with the--tagged option, e.g.--tagged="prod,master" will only select hosts taggedbothprodandmaster.
To sort hosts based on tags, use thenetwork.ordering.tags option, e.g.network.ordering.tags = [ "master" "slave"]. This ordering can be changed at runtime using the--order-by-tags option, eg.--order-by-tags="slave,master" (this also works whennetwork.ordering.tags isn't defined). Hosts without matching tags will end up at the end of the list.
Morph supports the following (optional) environment variables:
SSH_IDENTITY_FILEthe (local) path to the SSH private key file that should be usedSSH_USERspecifies the user that should be used to connect to the remote systemSSH_SKIP_HOST_KEY_CHECKif set disables host key verificationSSH_CONFIG_FILEallows to change the location of the ~/.ssh/config fileMORPH_NIX_EVAL_CMDmorph will invoke this command instead of default: "nix-instantiate" on PATHMORPH_NIX_BUILD_CMDmorph will invoke this command instead of default: "nix-build" on PATHMORPH_NIX_SHELL_CMDmorph will invoke this command instead of default: "nix-shell" on PATHMORPH_NIX_EVAL_MACHINESpath to a custom eval-machines.nix. Defaults to the eval-machines.nix bundled with morph
Files can be uploaded without ever ending up in the nix store, by specifying each file as a secret. This will use scp for copying a local file to the remote host.
Seeexamples/secrets.nix or the type definitions indata/options.nix.
To upload secrets, use themorph upload-secrets subcommand, or pass--upload-secrets tomorph deploy.
Note:Morph will automatically create directories parent tosecret.Destination if they don't exist.New dirs will be owned by root:root and have mode 755 (drwxr-xr-x).Automatic directory creation can be disabled by settingsecret.mkDirs = false.
Morph has support for two types of health checks:
- command based health checks, which are run on the target host (success defined as exit code == 0)
- HTTP based health checks, which are run from the host Morph is running on (success defined as HTTP response codes in the 2xx range)
Seeexamples/healthchecks.nix for an example.
There are no guarantees about the order health checks are run in, so if you need something complex you should write a script for it (e.g. usingpkgs.writeScript).Health checks will be repeated until success, and the interval can be configured with theperiod option (seedata/options.nix for details).
It is currently possible to have expressions like"test \"$(systemctl list-units --failed --no-legend --no-pager |wc -l)\" -eq 0" (count number of failed systemd units, fail if non-zero) as the first argument in a cmd-healthcheck. This works, but is discouraged, and might break at any time.
Morph supports running checks before changing the target host (note: files will still be pushed to the host).These checks work exactly like health checks, which means they will run forever until they have all succeeded.This is anexperimental feature that is very likely to change in the future. Comments and feedback welcome :).
Pre-deploy checks can be defined usingdeployment.preDeployChecks.
nix.conf-options: The "network"-attrset supports a sub-attrset named "nixConfig". Options configured here will pass--option <name> <value> to all nix commands.Note: these options apply to an entire deployment and arenot configurable on per-host basis.The default is an empty set, meaning that the nix configuration is inherited from the build environment. Seeman nix.conf.
network.buildShellBy passing--allow-build-shell and settingnetwork.buildShell to a nix-shell compatible derivation (eg.pkgs.mkShell ...), it's possible to make morph execute builds from within the defined shell. This makes it possible to have arbitrary dependencies available during the build, say for use with nix build hooks. Be aware that the shell can potentially execute any command on the local system.
special deployment options:
(per-host granularity)
buildOnly makes morph skip the "push" and "switch" steps for the given host, even if "morph deploy" or "morph push" is executed. (default: false)
substituteOnDestination Sets the--substitute-on-destination flag on nix copy, allowing for the deployment target to use substitutes. Seenix copy --help. (default: false)
Example usage ofnixConfig and deployment module options:
network = { nixConfig = { "extra-sandbox-paths" = "/foo/bar"; };};machine1 = { ... }: { deployment.buildOnly = true;};machine2 = { ... }: { deployment.substituteOnDestination = true;};mutually recursive configurationsEach host's configuration has access to anodes argument, which contains the compiled configurations of all hosts.
machine1 = { nodes, ... }: { hostnames.machine2 = (builtins.head nodes.machine2.networking.interfaces.foo.ipv4.addresses).address; networking.interfaces.foo.ipv4.addresses = [ { address = "10.0.0.10"; prefixLength = 32; } ];}machine2 = { nodes, ... }: { hostnames.machine1 = (builtins.head nodes.machine1.networking.interfaces.foo.ipv4.addresses).address; networking.interfaces.foo.ipv4.addresses = [ { address = "10.0.0.20"; prefixLength = 32; } ];}All commands mentioned below is available in the nix-shell, if you runnix-shell with working dir = project root. The includedshell.nix uses the latestnixos-unstable from GitHub by default, but you can override this by passing in another, eg.nix-shell --arg nixpkgs '<nixpkgs>' for your$NIX_PATH nixpkgs.
From withinnix-shell,go get -u updates all go modules. Remember to update thevendorSha256 in./default.nix
$nix-build --arg nixpkgs "builtins.fetchTarball https://github.com/NixOS/nixpkgs/archive/<rev>.tar.gz"
We needed a tool for managing our NixOS servers, and ended up writing one ourself. This is it. We use it on a daily basis to build and deploy our NixOS fleet, and when we need a feature we add it.
Morph is by no means done. The CLI UI might (and probably will) change once in a while.The code is written by humans with an itch to scratch, and we're discussing a complete rewrite (so feel free to complain about the source code since we don't like it either).It probably wont accidentally switch your local machine, so you should totally try it out, but do consider pinning to a specific git revision.
About
NixOS deployment tool
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.