Deployment and lifecycle management for Nix
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: init readmes

+117 -1
+11
AGENTS.md
··· 1 + If more than one of the rules conflict, ask before implementing. 2 + 3 + ## rules 4 + 5 + - Always use `elixir-conventions` for elixir code. If you don't have this skill, stop and tell your user to talk to Adam, because you are prohibited from editing files in this project with it. 6 + - Evolve the code without planning for every possible future or edge case. 7 + - Delete abandoned paths by default when changing direction, except when required by compatibility/migration. Ask before keeping more than one implementation. 8 + - Ensure backwards compatibility or migration paths for changes that affect contracts between components (e.g. agent/server), but otherwise assume breaking changes are ok. 9 + - Never break deployments or strand agents such that they cannot apply an upgrade. 10 + - You can access the dev server live over tidewave project_eval, allowing for introspection of a live environment. 11 + - Do not create worktrees unless explicitly asked. When asked, use: `git worktree add .claude/worktrees/<name> -b <name>`
+1
CLAUDE.md
··· 1 + AGENTS.md
+105 -1
README.md
··· 1 1 # Sower 2 2 3 - > Then he told them many things in parables, saying: “A farmer went out to sow his seed. As he was scattering the seed, some fell along the path, and the birds came and ate it up. Some fell on rocky places, where it did not have much soil. It sprang up quickly, because the soil was shallow. But when the sun came up, the plants were scorched, and they withered because they had no root. Other seed fell among thorns, which grew up and choked the plants. Still other seed fell on good soil, where it produced a crop—a hundred, sixty or thirty times what was sown. Whoever has ears, let them hear.” 3 + Sower is a deployment and lifecycle management tool for Nix based configurations, including NixOS and Home-Manager. 4 + 5 + With sower we sow the seeds of our systems. 6 + 7 + - A seed is an extra bundle of metadata for an artifact path, e.g. a Nix store path. 8 + - Seed metadata includes a set of tags, with git and user-provided tags. 9 + - An agent defines seeds they want to subscribe to. 10 + - Seeds are submitted to a server to be used for deployments. 11 + 12 + **WARNING** 13 + This project is experimental and is not recommended for production installation. 14 + One of the goals is never break deployments, but it is **not guaranteed yet**. 15 + I'm only using this in a homelab with approximately a dozen agents. 16 + This means the risk to me of breaking deployments is moderately low. 17 + 18 + I'd love for others to get value out of what I'm building here. 19 + Please reach out if you're a user, I want to chat. :) 20 + 21 + ## Installation 22 + 23 + Read the NixOS modules for the server and the agent. There is an example in nix/tests/e2e.nix 24 + 25 + 1. An example server config exists in nix/tests/e2e.nix 26 + 2. An example agent config is below. 27 + 28 + Good luck, everyone's counting on you. 29 + 30 + ## Components 31 + 32 + - Server including Phoenix LiveView web interface. 33 + - Always-on Agent with bi-directional communication with the Server over WebSockets. 34 + - Activator used by the Agent for running specific actions as root, over a systemd initiated socket. 35 + - CLI for submitting seeds including a full code to submitted builder. 36 + 37 + ### Agents 4 38 39 + Agents have full control over what the seeds from the server can or will do. 40 + This is managed through their configuration. 41 + 42 + #### Subscriptions 43 + 44 + Subscriptions are the main controls for how systems are deployed. They include: 45 + 46 + - A set of (currently primitive) seed tag matching rules 47 + - Schedule in cron format for pull-based deployments 48 + - Which deployment profile to use 49 + 50 + #### Deployment Profiles 51 + 52 + Controls for what happens when the deploy occurs. 53 + 54 + - Arguments to pass to activation 55 + - Rules about rebooting (NixOS seeds only) 56 + 57 + #### Example agent config 58 + 59 + ```nix 60 + { 61 + age.secrets.sower-next-api-token = { 62 + file = cfg.access_token_secret; 63 + owner = "sower-agent"; 64 + }; 65 + 66 + services.sower = { 67 + activator = { 68 + package = inputs.sower-next.packages.${pkgs.stdenv.hostPlatform.system}.activator; 69 + allowedGroups = [ "users" ]; 70 + }; 71 + 72 + agent = { 73 + enable = true; 74 + accessTokenFile = config.age.secrets.sower-next-api-token.path; 75 + package = inputs.sower-next.packages.${pkgs.stdenv.hostPlatform.system}.agent; 76 + 77 + settings = { 78 + access_token_file = config.age.secrets.sower-next-api-token.path; 79 + endpoint = "http://localhost:7150"; 80 + 81 + deployment_profiles = { 82 + boot = { 83 + activation_args = [ "boot" ]; 84 + reboot_policy = "when-required"; 85 + }; 86 + switch = { 87 + activation_args = [ "switch" ]; 88 + reboot_policy = "never"; 89 + }; 90 + }; 91 + 92 + subscriptions = [ 93 + { 94 + seed_name = config.networking.hostName; 95 + seed_type = "nixos"; 96 + rules = [ "git_branch=main" ]; 97 + # https://hexdocs.pm/crontab/cron_notation.html 98 + schedule = "0 3"; 99 + deployment_profile = "boot"; 100 + } 101 + ]; 102 + }; 103 + }; 104 + }; 105 + 106 + users.users.adam.extraGroups = [ "sower-activator" ]; 107 + }; 108 + ```