···78## [Unreleased] - yyyy-mm-dd
900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010## [0.4.0] - 2025-07-10
1112### Added
1314- Nodes may now fail without stopping the entire hive from continuing. A summary
15 of errors will be presented at the end of the apply process.
16-- Wire will now ping the node before it proceeds executing.
17-- Wire will now properly respect `deployment.target.hosts`.
18-- Wire will now attempt each target host in order until a valid one is found.
1920### Changed
2122-- Wire now directly evaluates your hive instead of shipping extra nix code along with its binary.
23 You must now use `outputs.makeHive { ... }` instead of a raw attribute.
24 This can be obtained with npins or a flake input.
25- The expected flake output name has changed from `outputs.colmena` to `outputs.wire`.
···33### Changed
3435- Dependency Updates.
36-- Wire now compiles and includes key agents for multiple architectures, currently only linux.
37- There is a new package output, `wire-small`, for testing purposes.
38 It only compiles the key agent for the host that builds `wire-small`.
39- `--no-progress` now defaults to true if stdin does not refer to a tty (unix pipelines, in CI).
40-- Added an error for the internal hive evluation parse failure.
41- The `inspect` command now has `show` as an alias.
42- Remove `log` command as there are currently no plans to implement the feature
43- The `completions` command is now hidden from the help page
4445### Fixed
4647-- A non-existant key owner user/group would not default to gid/uid `0`.
48- Keys can now be deployed to localhost.
4950## [0.2.0] - 2025-04-21
···78## [Unreleased] - yyyy-mm-dd
910+## [v1.1.1] - 2025-01-05
11+12+### Fixed
13+14+- Fix a bug where wire was attempting to SSH to the local machine when `buildOnTarget` &
15+ `allowLocalDeployment` where true.
16+17+## [v1.1.0] - 2025-12-31
18+19+### Added
20+21+- Add a `--substitute-on-destination` argument.
22+- Add the `meta.nodeSpecialArgs` meta option.
23+- Add `wire build`, a new command to build nodes offline.
24+ It is distinct from `wire apply build`, as it will not ping
25+ or push the result, making it useful for CI.
26+27+### Changed
28+29+- Build store paths will be output to stdout
30+31+### Fixed
32+33+- Fix invalidated caches not actually returning `None`.
34+35+## [v1.0.0] - 2025-12-17
36+37+### Added
38+39+- SIGINT signal handling.
40+41+### Changed
42+43+- Invalidate caches that reference garbage collected paths.
44+45+### Fixed
46+47+- Fix key filtering logic.
48+49+## [v1.0.0-beta.0] - 2025-12-02
50+51+### Added
52+53+- Implement `meta.nodeNixpkgs`.
54+- Add caching of hive evaluation for flakes.
55+56+### Changed
57+58+- Run tests against 25.11.
59+60+## [v1.0.0-alpha.1] - 2025-11-24
61+62+### Added
63+64+- Add `--handle-unreachable`. You can use `--handle-unreachable ignore` to
65+ ignore unreachable nodes in the status of the deployment.
66+- Add a basic progress bar.
67+68+### Changed
69+70+- Revert "Wire will now attempt to use SSH ControlMaster by default.".
71+- Change the `show` subcommand to look nicer now.
72+- Change the `build` step to always build remotely when the node is
73+ going to be applied locally.
74+75+## [v1.0.0-alpha.0] - 2025-10-22
76+77+### Added
78+79+- Add `--ssh-accept-host` argument.
80+- Add `--on -` syntax to the `--on` argument.
81+ Passing `-` will now read additional apply targets from stdin.
82+- Add `{key.name}-key.{path,service}` systemd units.
83+- Added `--flake` argument as an alias for `--path`.
84+- A terminal bell will be output if a sudo / ssh prompt is ever printed.
85+- Added a real tutorial, and separated many how-to guides.
86+ The tutorial leads the user through creating and deploying a wire Hive.
87+- Add `config.nixpkgs.flake.source` by default if `meta.nixpkgs` ends
88+ with `-source` at priority 1000 (default).
89+90+### Fixed
91+92+- Fix bug where `--non-interactive` was inversed.
93+- Fix a bug where `./result` links where being created.
94+- Fix passing `sources.nixpkgs` directly from npins to `meta.nixpkgs`.
95+- Fix nodes that will be applied locally running the `push` and `cleanup`
96+ steps.
97+98+### Changed
99+100+- Improve logging from interactive commands (absence of `--non-interactive`).
101+- Changed `--path` argument to support flakerefs (`github:foo/bar`,
102+ `git+file:///...`, `https://.../main.tar.gz`, etc).
103+- Changed SSH arguments to use ControlMaster by default.
104+- Compile-out logs with level `tracing_level::TRACE` in release builds.
105+- Improve aata integrity of keys.
106+- Unknown SSH keys will be immediately rejected unless `--ssh-accept-host` is passed.
107+- Changed evaluation to be ran in parallel with other steps until
108+ the .drv is required.
109+110+## [0.5.0] - 2025-09-18
111+112+### Added
113+114+- Added `--reboot`. wire will wait for the node to reconnect after rebooting.
115+ wire will refuse to reboot localhost. Keys post-activation will be applied
116+ after rebooting!
117+- Most errors now have error codes and documentation links.
118+- Added the global flag `--non-interactive`.
119+- wire now creates its own PTY to interface with openssh's PTY to allow for
120+ interactive sudo authentication on both remote and local targets.
121+122+ Using a wheel user as `deployment.target.user` is no longer necessary
123+ (if you like entering your password a lot).
124+125+ A non-wheel user combined with `--non-interactive` will likely fail.
126+127+- Added `deployment.keys.environment` to give key commands environment variables.
128+129+### Changed
130+131+- `wire inspect/show --json` will no longer use a pretty print.
132+- wire will now wait for the node to reconnect if activation failed (excluding
133+ dry-activate).
134+- Nix logs with the `Talkative` and `Chatty` level have been moved to
135+ `tracing_level::TRACE`.
136+- Error messages have been greatly improved.
137+138+### Fixed
139+140+- Some bugs to do with step execution were fixed.
141+142## [0.4.0] - 2025-07-10
143144### Added
145146- Nodes may now fail without stopping the entire hive from continuing. A summary
147 of errors will be presented at the end of the apply process.
148+- wire will now ping the node before it proceeds executing.
149+- wire will now properly respect `deployment.target.hosts`.
150+- wire will now attempt each target host in order until a valid one is found.
151152### Changed
153154+- wire now directly evaluates your hive instead of shipping extra nix code along with its binary.
155 You must now use `outputs.makeHive { ... }` instead of a raw attribute.
156 This can be obtained with npins or a flake input.
157- The expected flake output name has changed from `outputs.colmena` to `outputs.wire`.
···165### Changed
166167- Dependency Updates.
168+- wire now compiles and includes key agents for multiple architectures, currently only linux.
169- There is a new package output, `wire-small`, for testing purposes.
170 It only compiles the key agent for the host that builds `wire-small`.
171- `--no-progress` now defaults to true if stdin does not refer to a tty (unix pipelines, in CI).
172+- Added an error for the internal hive evaluation parse failure.
173- The `inspect` command now has `show` as an alias.
174- Remove `log` command as there are currently no plans to implement the feature
175- The `completions` command is now hidden from the help page
176177### Fixed
178179+- A non-existent key owner user/group would not default to gid/uid `0`.
180- Keys can now be deployed to localhost.
181182## [0.2.0] - 2025-04-21
···1+ GNU AFFERO GENERAL PUBLIC LICENSE
2+ Version 3, 19 November 2007
3+4+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
5+ Everyone is permitted to copy and distribute verbatim copies
6+ of this license document, but changing it is not allowed.
7+8+ Preamble
9+10+ The GNU Affero General Public License is a free, copyleft license for
11+software and other kinds of works, specifically designed to ensure
12+cooperation with the community in the case of network server software.
13+14+ The licenses for most software and other practical works are designed
15+to take away your freedom to share and change the works. By contrast,
16+our General Public Licenses are intended to guarantee your freedom to
17+share and change all versions of a program--to make sure it remains free
18+software for all its users.
19+20+ When we speak of free software, we are referring to freedom, not
21+price. Our General Public Licenses are designed to make sure that you
22+have the freedom to distribute copies of free software (and charge for
23+them if you wish), that you receive source code or can get it if you
24+want it, that you can change the software or use pieces of it in new
25+free programs, and that you know you can do these things.
26+27+ Developers that use our General Public Licenses protect your rights
28+with two steps: (1) assert copyright on the software, and (2) offer
29+you this License which gives you legal permission to copy, distribute
30+and/or modify the software.
31+32+ A secondary benefit of defending all users' freedom is that
33+improvements made in alternate versions of the program, if they
34+receive widespread use, become available for other developers to
35+incorporate. Many developers of free software are heartened and
36+encouraged by the resulting cooperation. However, in the case of
37+software used on network servers, this result may fail to come about.
38+The GNU General Public License permits making a modified version and
39+letting the public access it on a server without ever releasing its
40+source code to the public.
41+42+ The GNU Affero General Public License is designed specifically to
43+ensure that, in such cases, the modified source code becomes available
44+to the community. It requires the operator of a network server to
45+provide the source code of the modified version running there to the
46+users of that server. Therefore, public use of a modified version, on
47+a publicly accessible server, gives the public access to the source
48+code of the modified version.
49+50+ An older license, called the Affero General Public License and
51+published by Affero, was designed to accomplish similar goals. This is
52+a different license, not a version of the Affero GPL, but Affero has
53+released a new version of the Affero GPL which permits relicensing under
54+this license.
55+56+ The precise terms and conditions for copying, distribution and
57+modification follow.
58+59+ TERMS AND CONDITIONS
60+61+ 0. Definitions.
62+63+ "This License" refers to version 3 of the GNU Affero General Public License.
64+65+ "Copyright" also means copyright-like laws that apply to other kinds of
66+works, such as semiconductor masks.
67+68+ "The Program" refers to any copyrightable work licensed under this
69+License. Each licensee is addressed as "you". "Licensees" and
70+"recipients" may be individuals or organizations.
71+72+ To "modify" a work means to copy from or adapt all or part of the work
73+in a fashion requiring copyright permission, other than the making of an
74+exact copy. The resulting work is called a "modified version" of the
75+earlier work or a work "based on" the earlier work.
76+77+ A "covered work" means either the unmodified Program or a work based
78+on the Program.
79+80+ To "propagate" a work means to do anything with it that, without
81+permission, would make you directly or secondarily liable for
82+infringement under applicable copyright law, except executing it on a
83+computer or modifying a private copy. Propagation includes copying,
84+distribution (with or without modification), making available to the
85+public, and in some countries other activities as well.
86+87+ To "convey" a work means any kind of propagation that enables other
88+parties to make or receive copies. Mere interaction with a user through
89+a computer network, with no transfer of a copy, is not conveying.
90+91+ An interactive user interface displays "Appropriate Legal Notices"
92+to the extent that it includes a convenient and prominently visible
93+feature that (1) displays an appropriate copyright notice, and (2)
94+tells the user that there is no warranty for the work (except to the
95+extent that warranties are provided), that licensees may convey the
96+work under this License, and how to view a copy of this License. If
97+the interface presents a list of user commands or options, such as a
98+menu, a prominent item in the list meets this criterion.
99+100+ 1. Source Code.
101+102+ The "source code" for a work means the preferred form of the work
103+for making modifications to it. "Object code" means any non-source
104+form of a work.
105+106+ A "Standard Interface" means an interface that either is an official
107+standard defined by a recognized standards body, or, in the case of
108+interfaces specified for a particular programming language, one that
109+is widely used among developers working in that language.
110+111+ The "System Libraries" of an executable work include anything, other
112+than the work as a whole, that (a) is included in the normal form of
113+packaging a Major Component, but which is not part of that Major
114+Component, and (b) serves only to enable use of the work with that
115+Major Component, or to implement a Standard Interface for which an
116+implementation is available to the public in source code form. A
117+"Major Component", in this context, means a major essential component
118+(kernel, window system, and so on) of the specific operating system
119+(if any) on which the executable work runs, or a compiler used to
120+produce the work, or an object code interpreter used to run it.
121+122+ The "Corresponding Source" for a work in object code form means all
123+the source code needed to generate, install, and (for an executable
124+work) run the object code and to modify the work, including scripts to
125+control those activities. However, it does not include the work's
126+System Libraries, or general-purpose tools or generally available free
127+programs which are used unmodified in performing those activities but
128+which are not part of the work. For example, Corresponding Source
129+includes interface definition files associated with source files for
130+the work, and the source code for shared libraries and dynamically
131+linked subprograms that the work is specifically designed to require,
132+such as by intimate data communication or control flow between those
133+subprograms and other parts of the work.
134+135+ The Corresponding Source need not include anything that users
136+can regenerate automatically from other parts of the Corresponding
137+Source.
138+139+ The Corresponding Source for a work in source code form is that
140+same work.
141+142+ 2. Basic Permissions.
143+144+ All rights granted under this License are granted for the term of
145+copyright on the Program, and are irrevocable provided the stated
146+conditions are met. This License explicitly affirms your unlimited
147+permission to run the unmodified Program. The output from running a
148+covered work is covered by this License only if the output, given its
149+content, constitutes a covered work. This License acknowledges your
150+rights of fair use or other equivalent, as provided by copyright law.
151+152+ You may make, run and propagate covered works that you do not
153+convey, without conditions so long as your license otherwise remains
154+in force. You may convey covered works to others for the sole purpose
155+of having them make modifications exclusively for you, or provide you
156+with facilities for running those works, provided that you comply with
157+the terms of this License in conveying all material for which you do
158+not control copyright. Those thus making or running the covered works
159+for you must do so exclusively on your behalf, under your direction
160+and control, on terms that prohibit them from making any copies of
161+your copyrighted material outside their relationship with you.
162+163+ Conveying under any other circumstances is permitted solely under
164+the conditions stated below. Sublicensing is not allowed; section 10
165+makes it unnecessary.
166+167+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168+169+ No covered work shall be deemed part of an effective technological
170+measure under any applicable law fulfilling obligations under article
171+11 of the WIPO copyright treaty adopted on 20 December 1996, or
172+similar laws prohibiting or restricting circumvention of such
173+measures.
174+175+ When you convey a covered work, you waive any legal power to forbid
176+circumvention of technological measures to the extent such circumvention
177+is effected by exercising rights under this License with respect to
178+the covered work, and you disclaim any intention to limit operation or
179+modification of the work as a means of enforcing, against the work's
180+users, your or third parties' legal rights to forbid circumvention of
181+technological measures.
182+183+ 4. Conveying Verbatim Copies.
184+185+ You may convey verbatim copies of the Program's source code as you
186+receive it, in any medium, provided that you conspicuously and
187+appropriately publish on each copy an appropriate copyright notice;
188+keep intact all notices stating that this License and any
189+non-permissive terms added in accord with section 7 apply to the code;
190+keep intact all notices of the absence of any warranty; and give all
191+recipients a copy of this License along with the Program.
192+193+ You may charge any price or no price for each copy that you convey,
194+and you may offer support or warranty protection for a fee.
195+196+ 5. Conveying Modified Source Versions.
197+198+ You may convey a work based on the Program, or the modifications to
199+produce it from the Program, in the form of source code under the
200+terms of section 4, provided that you also meet all of these conditions:
201+202+ a) The work must carry prominent notices stating that you modified
203+ it, and giving a relevant date.
204+205+ b) The work must carry prominent notices stating that it is
206+ released under this License and any conditions added under section
207+ 7. This requirement modifies the requirement in section 4 to
208+ "keep intact all notices".
209+210+ c) You must license the entire work, as a whole, under this
211+ License to anyone who comes into possession of a copy. This
212+ License will therefore apply, along with any applicable section 7
213+ additional terms, to the whole of the work, and all its parts,
214+ regardless of how they are packaged. This License gives no
215+ permission to license the work in any other way, but it does not
216+ invalidate such permission if you have separately received it.
217+218+ d) If the work has interactive user interfaces, each must display
219+ Appropriate Legal Notices; however, if the Program has interactive
220+ interfaces that do not display Appropriate Legal Notices, your
221+ work need not make them do so.
222+223+ A compilation of a covered work with other separate and independent
224+works, which are not by their nature extensions of the covered work,
225+and which are not combined with it such as to form a larger program,
226+in or on a volume of a storage or distribution medium, is called an
227+"aggregate" if the compilation and its resulting copyright are not
228+used to limit the access or legal rights of the compilation's users
229+beyond what the individual works permit. Inclusion of a covered work
230+in an aggregate does not cause this License to apply to the other
231+parts of the aggregate.
232+233+ 6. Conveying Non-Source Forms.
234+235+ You may convey a covered work in object code form under the terms
236+of sections 4 and 5, provided that you also convey the
237+machine-readable Corresponding Source under the terms of this License,
238+in one of these ways:
239+240+ a) Convey the object code in, or embodied in, a physical product
241+ (including a physical distribution medium), accompanied by the
242+ Corresponding Source fixed on a durable physical medium
243+ customarily used for software interchange.
244+245+ b) Convey the object code in, or embodied in, a physical product
246+ (including a physical distribution medium), accompanied by a
247+ written offer, valid for at least three years and valid for as
248+ long as you offer spare parts or customer support for that product
249+ model, to give anyone who possesses the object code either (1) a
250+ copy of the Corresponding Source for all the software in the
251+ product that is covered by this License, on a durable physical
252+ medium customarily used for software interchange, for a price no
253+ more than your reasonable cost of physically performing this
254+ conveying of source, or (2) access to copy the
255+ Corresponding Source from a network server at no charge.
256+257+ c) Convey individual copies of the object code with a copy of the
258+ written offer to provide the Corresponding Source. This
259+ alternative is allowed only occasionally and noncommercially, and
260+ only if you received the object code with such an offer, in accord
261+ with subsection 6b.
262+263+ d) Convey the object code by offering access from a designated
264+ place (gratis or for a charge), and offer equivalent access to the
265+ Corresponding Source in the same way through the same place at no
266+ further charge. You need not require recipients to copy the
267+ Corresponding Source along with the object code. If the place to
268+ copy the object code is a network server, the Corresponding Source
269+ may be on a different server (operated by you or a third party)
270+ that supports equivalent copying facilities, provided you maintain
271+ clear directions next to the object code saying where to find the
272+ Corresponding Source. Regardless of what server hosts the
273+ Corresponding Source, you remain obligated to ensure that it is
274+ available for as long as needed to satisfy these requirements.
275+276+ e) Convey the object code using peer-to-peer transmission, provided
277+ you inform other peers where the object code and Corresponding
278+ Source of the work are being offered to the general public at no
279+ charge under subsection 6d.
280+281+ A separable portion of the object code, whose source code is excluded
282+from the Corresponding Source as a System Library, need not be
283+included in conveying the object code work.
284+285+ A "User Product" is either (1) a "consumer product", which means any
286+tangible personal property which is normally used for personal, family,
287+or household purposes, or (2) anything designed or sold for incorporation
288+into a dwelling. In determining whether a product is a consumer product,
289+doubtful cases shall be resolved in favor of coverage. For a particular
290+product received by a particular user, "normally used" refers to a
291+typical or common use of that class of product, regardless of the status
292+of the particular user or of the way in which the particular user
293+actually uses, or expects or is expected to use, the product. A product
294+is a consumer product regardless of whether the product has substantial
295+commercial, industrial or non-consumer uses, unless such uses represent
296+the only significant mode of use of the product.
297+298+ "Installation Information" for a User Product means any methods,
299+procedures, authorization keys, or other information required to install
300+and execute modified versions of a covered work in that User Product from
301+a modified version of its Corresponding Source. The information must
302+suffice to ensure that the continued functioning of the modified object
303+code is in no case prevented or interfered with solely because
304+modification has been made.
305+306+ If you convey an object code work under this section in, or with, or
307+specifically for use in, a User Product, and the conveying occurs as
308+part of a transaction in which the right of possession and use of the
309+User Product is transferred to the recipient in perpetuity or for a
310+fixed term (regardless of how the transaction is characterized), the
311+Corresponding Source conveyed under this section must be accompanied
312+by the Installation Information. But this requirement does not apply
313+if neither you nor any third party retains the ability to install
314+modified object code on the User Product (for example, the work has
315+been installed in ROM).
316+317+ The requirement to provide Installation Information does not include a
318+requirement to continue to provide support service, warranty, or updates
319+for a work that has been modified or installed by the recipient, or for
320+the User Product in which it has been modified or installed. Access to a
321+network may be denied when the modification itself materially and
322+adversely affects the operation of the network or violates the rules and
323+protocols for communication across the network.
324+325+ Corresponding Source conveyed, and Installation Information provided,
326+in accord with this section must be in a format that is publicly
327+documented (and with an implementation available to the public in
328+source code form), and must require no special password or key for
329+unpacking, reading or copying.
330+331+ 7. Additional Terms.
332+333+ "Additional permissions" are terms that supplement the terms of this
334+License by making exceptions from one or more of its conditions.
335+Additional permissions that are applicable to the entire Program shall
336+be treated as though they were included in this License, to the extent
337+that they are valid under applicable law. If additional permissions
338+apply only to part of the Program, that part may be used separately
339+under those permissions, but the entire Program remains governed by
340+this License without regard to the additional permissions.
341+342+ When you convey a copy of a covered work, you may at your option
343+remove any additional permissions from that copy, or from any part of
344+it. (Additional permissions may be written to require their own
345+removal in certain cases when you modify the work.) You may place
346+additional permissions on material, added by you to a covered work,
347+for which you have or can give appropriate copyright permission.
348+349+ Notwithstanding any other provision of this License, for material you
350+add to a covered work, you may (if authorized by the copyright holders of
351+that material) supplement the terms of this License with terms:
352+353+ a) Disclaiming warranty or limiting liability differently from the
354+ terms of sections 15 and 16 of this License; or
355+356+ b) Requiring preservation of specified reasonable legal notices or
357+ author attributions in that material or in the Appropriate Legal
358+ Notices displayed by works containing it; or
359+360+ c) Prohibiting misrepresentation of the origin of that material, or
361+ requiring that modified versions of such material be marked in
362+ reasonable ways as different from the original version; or
363+364+ d) Limiting the use for publicity purposes of names of licensors or
365+ authors of the material; or
366+367+ e) Declining to grant rights under trademark law for use of some
368+ trade names, trademarks, or service marks; or
369+370+ f) Requiring indemnification of licensors and authors of that
371+ material by anyone who conveys the material (or modified versions of
372+ it) with contractual assumptions of liability to the recipient, for
373+ any liability that these contractual assumptions directly impose on
374+ those licensors and authors.
375+376+ All other non-permissive additional terms are considered "further
377+restrictions" within the meaning of section 10. If the Program as you
378+received it, or any part of it, contains a notice stating that it is
379+governed by this License along with a term that is a further
380+restriction, you may remove that term. If a license document contains
381+a further restriction but permits relicensing or conveying under this
382+License, you may add to a covered work material governed by the terms
383+of that license document, provided that the further restriction does
384+not survive such relicensing or conveying.
385+386+ If you add terms to a covered work in accord with this section, you
387+must place, in the relevant source files, a statement of the
388+additional terms that apply to those files, or a notice indicating
389+where to find the applicable terms.
390+391+ Additional terms, permissive or non-permissive, may be stated in the
392+form of a separately written license, or stated as exceptions;
393+the above requirements apply either way.
394+395+ 8. Termination.
396+397+ You may not propagate or modify a covered work except as expressly
398+provided under this License. Any attempt otherwise to propagate or
399+modify it is void, and will automatically terminate your rights under
400+this License (including any patent licenses granted under the third
401+paragraph of section 11).
402+403+ However, if you cease all violation of this License, then your
404+license from a particular copyright holder is reinstated (a)
405+provisionally, unless and until the copyright holder explicitly and
406+finally terminates your license, and (b) permanently, if the copyright
407+holder fails to notify you of the violation by some reasonable means
408+prior to 60 days after the cessation.
409+410+ Moreover, your license from a particular copyright holder is
411+reinstated permanently if the copyright holder notifies you of the
412+violation by some reasonable means, this is the first time you have
413+received notice of violation of this License (for any work) from that
414+copyright holder, and you cure the violation prior to 30 days after
415+your receipt of the notice.
416+417+ Termination of your rights under this section does not terminate the
418+licenses of parties who have received copies or rights from you under
419+this License. If your rights have been terminated and not permanently
420+reinstated, you do not qualify to receive new licenses for the same
421+material under section 10.
422+423+ 9. Acceptance Not Required for Having Copies.
424+425+ You are not required to accept this License in order to receive or
426+run a copy of the Program. Ancillary propagation of a covered work
427+occurring solely as a consequence of using peer-to-peer transmission
428+to receive a copy likewise does not require acceptance. However,
429+nothing other than this License grants you permission to propagate or
430+modify any covered work. These actions infringe copyright if you do
431+not accept this License. Therefore, by modifying or propagating a
432+covered work, you indicate your acceptance of this License to do so.
433+434+ 10. Automatic Licensing of Downstream Recipients.
435+436+ Each time you convey a covered work, the recipient automatically
437+receives a license from the original licensors, to run, modify and
438+propagate that work, subject to this License. You are not responsible
439+for enforcing compliance by third parties with this License.
440+441+ An "entity transaction" is a transaction transferring control of an
442+organization, or substantially all assets of one, or subdividing an
443+organization, or merging organizations. If propagation of a covered
444+work results from an entity transaction, each party to that
445+transaction who receives a copy of the work also receives whatever
446+licenses to the work the party's predecessor in interest had or could
447+give under the previous paragraph, plus a right to possession of the
448+Corresponding Source of the work from the predecessor in interest, if
449+the predecessor has it or can get it with reasonable efforts.
450+451+ You may not impose any further restrictions on the exercise of the
452+rights granted or affirmed under this License. For example, you may
453+not impose a license fee, royalty, or other charge for exercise of
454+rights granted under this License, and you may not initiate litigation
455+(including a cross-claim or counterclaim in a lawsuit) alleging that
456+any patent claim is infringed by making, using, selling, offering for
457+sale, or importing the Program or any portion of it.
458+459+ 11. Patents.
460+461+ A "contributor" is a copyright holder who authorizes use under this
462+License of the Program or a work on which the Program is based. The
463+work thus licensed is called the contributor's "contributor version".
464+465+ A contributor's "essential patent claims" are all patent claims
466+owned or controlled by the contributor, whether already acquired or
467+hereafter acquired, that would be infringed by some manner, permitted
468+by this License, of making, using, or selling its contributor version,
469+but do not include claims that would be infringed only as a
470+consequence of further modification of the contributor version. For
471+purposes of this definition, "control" includes the right to grant
472+patent sublicenses in a manner consistent with the requirements of
473+this License.
474+475+ Each contributor grants you a non-exclusive, worldwide, royalty-free
476+patent license under the contributor's essential patent claims, to
477+make, use, sell, offer for sale, import and otherwise run, modify and
478+propagate the contents of its contributor version.
479+480+ In the following three paragraphs, a "patent license" is any express
481+agreement or commitment, however denominated, not to enforce a patent
482+(such as an express permission to practice a patent or covenant not to
483+sue for patent infringement). To "grant" such a patent license to a
484+party means to make such an agreement or commitment not to enforce a
485+patent against the party.
486+487+ If you convey a covered work, knowingly relying on a patent license,
488+and the Corresponding Source of the work is not available for anyone
489+to copy, free of charge and under the terms of this License, through a
490+publicly available network server or other readily accessible means,
491+then you must either (1) cause the Corresponding Source to be so
492+available, or (2) arrange to deprive yourself of the benefit of the
493+patent license for this particular work, or (3) arrange, in a manner
494+consistent with the requirements of this License, to extend the patent
495+license to downstream recipients. "Knowingly relying" means you have
496+actual knowledge that, but for the patent license, your conveying the
497+covered work in a country, or your recipient's use of the covered work
498+in a country, would infringe one or more identifiable patents in that
499+country that you have reason to believe are valid.
500+501+ If, pursuant to or in connection with a single transaction or
502+arrangement, you convey, or propagate by procuring conveyance of, a
503+covered work, and grant a patent license to some of the parties
504+receiving the covered work authorizing them to use, propagate, modify
505+or convey a specific copy of the covered work, then the patent license
506+you grant is automatically extended to all recipients of the covered
507+work and works based on it.
508+509+ A patent license is "discriminatory" if it does not include within
510+the scope of its coverage, prohibits the exercise of, or is
511+conditioned on the non-exercise of one or more of the rights that are
512+specifically granted under this License. You may not convey a covered
513+work if you are a party to an arrangement with a third party that is
514+in the business of distributing software, under which you make payment
515+to the third party based on the extent of your activity of conveying
516+the work, and under which the third party grants, to any of the
517+parties who would receive the covered work from you, a discriminatory
518+patent license (a) in connection with copies of the covered work
519+conveyed by you (or copies made from those copies), or (b) primarily
520+for and in connection with specific products or compilations that
521+contain the covered work, unless you entered into that arrangement,
522+or that patent license was granted, prior to 28 March 2007.
523+524+ Nothing in this License shall be construed as excluding or limiting
525+any implied license or other defenses to infringement that may
526+otherwise be available to you under applicable patent law.
527+528+ 12. No Surrender of Others' Freedom.
529+530+ If conditions are imposed on you (whether by court order, agreement or
531+otherwise) that contradict the conditions of this License, they do not
532+excuse you from the conditions of this License. If you cannot convey a
533+covered work so as to satisfy simultaneously your obligations under this
534+License and any other pertinent obligations, then as a consequence you may
535+not convey it at all. For example, if you agree to terms that obligate you
536+to collect a royalty for further conveying from those to whom you convey
537+the Program, the only way you could satisfy both those terms and this
538+License would be to refrain entirely from conveying the Program.
539+540+ 13. Remote Network Interaction; Use with the GNU General Public License.
541+542+ Notwithstanding any other provision of this License, if you modify the
543+Program, your modified version must prominently offer all users
544+interacting with it remotely through a computer network (if your version
545+supports such interaction) an opportunity to receive the Corresponding
546+Source of your version by providing access to the Corresponding Source
547+from a network server at no charge, through some standard or customary
548+means of facilitating copying of software. This Corresponding Source
549+shall include the Corresponding Source for any work covered by version 3
550+of the GNU General Public License that is incorporated pursuant to the
551+following paragraph.
552+553+ Notwithstanding any other provision of this License, you have
554+permission to link or combine any covered work with a work licensed
555+under version 3 of the GNU General Public License into a single
556+combined work, and to convey the resulting work. The terms of this
557+License will continue to apply to the part which is the covered work,
558+but the work with which it is combined will remain governed by version
559+3 of the GNU General Public License.
560+561+ 14. Revised Versions of this License.
562+563+ The Free Software Foundation may publish revised and/or new versions of
564+the GNU Affero General Public License from time to time. Such new versions
565+will be similar in spirit to the present version, but may differ in detail to
566+address new problems or concerns.
567+568+ Each version is given a distinguishing version number. If the
569+Program specifies that a certain numbered version of the GNU Affero General
570+Public License "or any later version" applies to it, you have the
571+option of following the terms and conditions either of that numbered
572+version or of any later version published by the Free Software
573+Foundation. If the Program does not specify a version number of the
574+GNU Affero General Public License, you may choose any version ever published
575+by the Free Software Foundation.
576+577+ If the Program specifies that a proxy can decide which future
578+versions of the GNU Affero General Public License can be used, that proxy's
579+public statement of acceptance of a version permanently authorizes you
580+to choose that version for the Program.
581+582+ Later license versions may give you additional or different
583+permissions. However, no additional obligations are imposed on any
584+author or copyright holder as a result of your choosing to follow a
585+later version.
586+587+ 15. Disclaimer of Warranty.
588+589+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597+598+ 16. Limitation of Liability.
599+600+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608+SUCH DAMAGES.
609+610+ 17. Interpretation of Sections 15 and 16.
611+612+ If the disclaimer of warranty and limitation of liability provided
613+above cannot be given local legal effect according to their terms,
614+reviewing courts shall apply local law that most closely approximates
615+an absolute waiver of all civil liability in connection with the
616+Program, unless a warranty or assumption of liability accompanies a
617+copy of the Program in return for a fee.
618+619+ END OF TERMS AND CONDITIONS
620+621+ How to Apply These Terms to Your New Programs
622+623+ If you develop a new program, and you want it to be of the greatest
624+possible use to the public, the best way to achieve this is to make it
625+free software which everyone can redistribute and change under these terms.
626+627+ To do so, attach the following notices to the program. It is safest
628+to attach them to the start of each source file to most effectively
629+state the exclusion of warranty; and each file should have at least
630+the "copyright" line and a pointer to where the full notice is found.
631+632+ <one line to give the program's name and a brief idea of what it does.>
633+ Copyright (C) <year> <name of author>
634+635+ This program is free software: you can redistribute it and/or modify
636+ it under the terms of the GNU Affero General Public License as published
637+ by the Free Software Foundation, either version 3 of the License, or
638+ (at your option) any later version.
639+640+ This program is distributed in the hope that it will be useful,
641+ but WITHOUT ANY WARRANTY; without even the implied warranty of
642+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643+ GNU Affero General Public License for more details.
644+645+ You should have received a copy of the GNU Affero General Public License
646+ along with this program. If not, see <https://www.gnu.org/licenses/>.
647+648+Also add information on how to contact you by electronic and paper mail.
649+650+ If your software can interact with users remotely through a computer
651+network, you should also make sure that it provides a way for users to
652+get its source. For example, if your program is a web application, its
653+interface could display a "Source" link that leads users to an archive
654+of the code. There are many ways you could offer source, and different
655+solutions will be better for different programs; see section 13 for the
656+specific requirements.
657+658+ You should also get your employer (if you work as a programmer) or school,
659+if any, to sign a "copyright disclaimer" for the program, if necessary.
660+For more information on this, and how to apply and follow the GNU AGPL, see
661+<https://www.gnu.org/licenses/>.
···1[workspace]
2-members = ["wire/key_agent", "wire/lib", "wire/cli"]
3resolver = "2"
4-package.edition = "2021"
5-package.version = "0.4.0"
67[workspace.metadata.crane]
8name = "wire"
00000000910[workspace.dependencies]
11-clap = { version = "4.5.40", features = ["derive", "string", "cargo"] }
12-clap-verbosity-flag = "3.0.3"
13-serde = { version = "1.0.219", features = ["derive", "rc"] }
14-serde_json = { version = "1.0.140" }
15-tokio = { version = "1.45.1", features = ["full"] }
16-tracing = "0.1.41"
17-tracing-indicatif = "0.3.9"
18tracing-log = "0.2.0"
19-tracing-subscriber = "0.3.19"
20im = { version = "15.1.0", features = ["serde"] }
21-anyhow = "1.0.98"
22prost = "0.14.1"
23-nix = { version = "0.30.1", features = ["user"] }
0000000000000000000000
···1[workspace]
2+members = ["crates/key_agent", "crates/core", "crates/cli"]
3resolver = "2"
4+package.edition = "2024"
5+package.version = "1.1.1"
67[workspace.metadata.crane]
8name = "wire"
9+10+[workspace.lints.clippy]
11+pedantic = { level = "deny", priority = -1 }
12+missing_const_for_fn = "deny"
13+14+# annoying to deal with
15+missing_errors_doc = "allow"
16+missing_panics_doc = "allow"
1718[workspace.dependencies]
19+futures-util = { version = "0.3.31", features = ["sink", "std"] }
20+clap = { version = "4.5.51", features = ["derive", "string", "cargo"] }
21+clap-verbosity-flag = "3.0.4"
22+serde = { version = "1.0.228", features = ["derive", "rc"] }
23+tokio = { version = "1.48.0", features = ["full"] }
24+tracing = { version = "0.1.41", features = ["release_max_level_debug"] }
025tracing-log = "0.2.0"
26+tracing-subscriber = "0.3.20"
27im = { version = "15.1.0", features = ["serde"] }
28+anyhow = "1.0.100"
29prost = "0.14.1"
30+nix = { version = "0.30.1", features = ["user", "poll", "term"] }
31+miette = { version = "7.6.0", features = ["fancy"] }
32+thiserror = "2.0.17"
33+sha2 = "0.10.9"
34+tokio-util = { version = "0.7.17", features = ["codec"] }
35+base64 = "0.22.1"
36+nix-compat = { git = "https://git.snix.dev/snix/snix.git", features = [
37+ "serde",
38+ "flakeref",
39+] }
40+# simd-json = { version = "0.17.0", features = [
41+# "serde_impl",
42+# # swar-number-parsing is disabled because nix never outputs
43+# # floats.
44+# # "swar-number-parsing",
45+# "runtime-detection",
46+# "hints",
47+# ] }
48+serde_json = { version = "1.0.145" }
49+owo-colors = { version = "4.2.3", features = ["supports-colors"] }
50+51+[profile.dev.package.sqlx-macros]
52+opt-level = 3
-661
LICENSE
···1- GNU AFFERO GENERAL PUBLIC LICENSE
2- Version 3, 19 November 2007
3-4- Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
5- Everyone is permitted to copy and distribute verbatim copies
6- of this license document, but changing it is not allowed.
7-8- Preamble
9-10- The GNU Affero General Public License is a free, copyleft license for
11-software and other kinds of works, specifically designed to ensure
12-cooperation with the community in the case of network server software.
13-14- The licenses for most software and other practical works are designed
15-to take away your freedom to share and change the works. By contrast,
16-our General Public Licenses are intended to guarantee your freedom to
17-share and change all versions of a program--to make sure it remains free
18-software for all its users.
19-20- When we speak of free software, we are referring to freedom, not
21-price. Our General Public Licenses are designed to make sure that you
22-have the freedom to distribute copies of free software (and charge for
23-them if you wish), that you receive source code or can get it if you
24-want it, that you can change the software or use pieces of it in new
25-free programs, and that you know you can do these things.
26-27- Developers that use our General Public Licenses protect your rights
28-with two steps: (1) assert copyright on the software, and (2) offer
29-you this License which gives you legal permission to copy, distribute
30-and/or modify the software.
31-32- A secondary benefit of defending all users' freedom is that
33-improvements made in alternate versions of the program, if they
34-receive widespread use, become available for other developers to
35-incorporate. Many developers of free software are heartened and
36-encouraged by the resulting cooperation. However, in the case of
37-software used on network servers, this result may fail to come about.
38-The GNU General Public License permits making a modified version and
39-letting the public access it on a server without ever releasing its
40-source code to the public.
41-42- The GNU Affero General Public License is designed specifically to
43-ensure that, in such cases, the modified source code becomes available
44-to the community. It requires the operator of a network server to
45-provide the source code of the modified version running there to the
46-users of that server. Therefore, public use of a modified version, on
47-a publicly accessible server, gives the public access to the source
48-code of the modified version.
49-50- An older license, called the Affero General Public License and
51-published by Affero, was designed to accomplish similar goals. This is
52-a different license, not a version of the Affero GPL, but Affero has
53-released a new version of the Affero GPL which permits relicensing under
54-this license.
55-56- The precise terms and conditions for copying, distribution and
57-modification follow.
58-59- TERMS AND CONDITIONS
60-61- 0. Definitions.
62-63- "This License" refers to version 3 of the GNU Affero General Public License.
64-65- "Copyright" also means copyright-like laws that apply to other kinds of
66-works, such as semiconductor masks.
67-68- "The Program" refers to any copyrightable work licensed under this
69-License. Each licensee is addressed as "you". "Licensees" and
70-"recipients" may be individuals or organizations.
71-72- To "modify" a work means to copy from or adapt all or part of the work
73-in a fashion requiring copyright permission, other than the making of an
74-exact copy. The resulting work is called a "modified version" of the
75-earlier work or a work "based on" the earlier work.
76-77- A "covered work" means either the unmodified Program or a work based
78-on the Program.
79-80- To "propagate" a work means to do anything with it that, without
81-permission, would make you directly or secondarily liable for
82-infringement under applicable copyright law, except executing it on a
83-computer or modifying a private copy. Propagation includes copying,
84-distribution (with or without modification), making available to the
85-public, and in some countries other activities as well.
86-87- To "convey" a work means any kind of propagation that enables other
88-parties to make or receive copies. Mere interaction with a user through
89-a computer network, with no transfer of a copy, is not conveying.
90-91- An interactive user interface displays "Appropriate Legal Notices"
92-to the extent that it includes a convenient and prominently visible
93-feature that (1) displays an appropriate copyright notice, and (2)
94-tells the user that there is no warranty for the work (except to the
95-extent that warranties are provided), that licensees may convey the
96-work under this License, and how to view a copy of this License. If
97-the interface presents a list of user commands or options, such as a
98-menu, a prominent item in the list meets this criterion.
99-100- 1. Source Code.
101-102- The "source code" for a work means the preferred form of the work
103-for making modifications to it. "Object code" means any non-source
104-form of a work.
105-106- A "Standard Interface" means an interface that either is an official
107-standard defined by a recognized standards body, or, in the case of
108-interfaces specified for a particular programming language, one that
109-is widely used among developers working in that language.
110-111- The "System Libraries" of an executable work include anything, other
112-than the work as a whole, that (a) is included in the normal form of
113-packaging a Major Component, but which is not part of that Major
114-Component, and (b) serves only to enable use of the work with that
115-Major Component, or to implement a Standard Interface for which an
116-implementation is available to the public in source code form. A
117-"Major Component", in this context, means a major essential component
118-(kernel, window system, and so on) of the specific operating system
119-(if any) on which the executable work runs, or a compiler used to
120-produce the work, or an object code interpreter used to run it.
121-122- The "Corresponding Source" for a work in object code form means all
123-the source code needed to generate, install, and (for an executable
124-work) run the object code and to modify the work, including scripts to
125-control those activities. However, it does not include the work's
126-System Libraries, or general-purpose tools or generally available free
127-programs which are used unmodified in performing those activities but
128-which are not part of the work. For example, Corresponding Source
129-includes interface definition files associated with source files for
130-the work, and the source code for shared libraries and dynamically
131-linked subprograms that the work is specifically designed to require,
132-such as by intimate data communication or control flow between those
133-subprograms and other parts of the work.
134-135- The Corresponding Source need not include anything that users
136-can regenerate automatically from other parts of the Corresponding
137-Source.
138-139- The Corresponding Source for a work in source code form is that
140-same work.
141-142- 2. Basic Permissions.
143-144- All rights granted under this License are granted for the term of
145-copyright on the Program, and are irrevocable provided the stated
146-conditions are met. This License explicitly affirms your unlimited
147-permission to run the unmodified Program. The output from running a
148-covered work is covered by this License only if the output, given its
149-content, constitutes a covered work. This License acknowledges your
150-rights of fair use or other equivalent, as provided by copyright law.
151-152- You may make, run and propagate covered works that you do not
153-convey, without conditions so long as your license otherwise remains
154-in force. You may convey covered works to others for the sole purpose
155-of having them make modifications exclusively for you, or provide you
156-with facilities for running those works, provided that you comply with
157-the terms of this License in conveying all material for which you do
158-not control copyright. Those thus making or running the covered works
159-for you must do so exclusively on your behalf, under your direction
160-and control, on terms that prohibit them from making any copies of
161-your copyrighted material outside their relationship with you.
162-163- Conveying under any other circumstances is permitted solely under
164-the conditions stated below. Sublicensing is not allowed; section 10
165-makes it unnecessary.
166-167- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168-169- No covered work shall be deemed part of an effective technological
170-measure under any applicable law fulfilling obligations under article
171-11 of the WIPO copyright treaty adopted on 20 December 1996, or
172-similar laws prohibiting or restricting circumvention of such
173-measures.
174-175- When you convey a covered work, you waive any legal power to forbid
176-circumvention of technological measures to the extent such circumvention
177-is effected by exercising rights under this License with respect to
178-the covered work, and you disclaim any intention to limit operation or
179-modification of the work as a means of enforcing, against the work's
180-users, your or third parties' legal rights to forbid circumvention of
181-technological measures.
182-183- 4. Conveying Verbatim Copies.
184-185- You may convey verbatim copies of the Program's source code as you
186-receive it, in any medium, provided that you conspicuously and
187-appropriately publish on each copy an appropriate copyright notice;
188-keep intact all notices stating that this License and any
189-non-permissive terms added in accord with section 7 apply to the code;
190-keep intact all notices of the absence of any warranty; and give all
191-recipients a copy of this License along with the Program.
192-193- You may charge any price or no price for each copy that you convey,
194-and you may offer support or warranty protection for a fee.
195-196- 5. Conveying Modified Source Versions.
197-198- You may convey a work based on the Program, or the modifications to
199-produce it from the Program, in the form of source code under the
200-terms of section 4, provided that you also meet all of these conditions:
201-202- a) The work must carry prominent notices stating that you modified
203- it, and giving a relevant date.
204-205- b) The work must carry prominent notices stating that it is
206- released under this License and any conditions added under section
207- 7. This requirement modifies the requirement in section 4 to
208- "keep intact all notices".
209-210- c) You must license the entire work, as a whole, under this
211- License to anyone who comes into possession of a copy. This
212- License will therefore apply, along with any applicable section 7
213- additional terms, to the whole of the work, and all its parts,
214- regardless of how they are packaged. This License gives no
215- permission to license the work in any other way, but it does not
216- invalidate such permission if you have separately received it.
217-218- d) If the work has interactive user interfaces, each must display
219- Appropriate Legal Notices; however, if the Program has interactive
220- interfaces that do not display Appropriate Legal Notices, your
221- work need not make them do so.
222-223- A compilation of a covered work with other separate and independent
224-works, which are not by their nature extensions of the covered work,
225-and which are not combined with it such as to form a larger program,
226-in or on a volume of a storage or distribution medium, is called an
227-"aggregate" if the compilation and its resulting copyright are not
228-used to limit the access or legal rights of the compilation's users
229-beyond what the individual works permit. Inclusion of a covered work
230-in an aggregate does not cause this License to apply to the other
231-parts of the aggregate.
232-233- 6. Conveying Non-Source Forms.
234-235- You may convey a covered work in object code form under the terms
236-of sections 4 and 5, provided that you also convey the
237-machine-readable Corresponding Source under the terms of this License,
238-in one of these ways:
239-240- a) Convey the object code in, or embodied in, a physical product
241- (including a physical distribution medium), accompanied by the
242- Corresponding Source fixed on a durable physical medium
243- customarily used for software interchange.
244-245- b) Convey the object code in, or embodied in, a physical product
246- (including a physical distribution medium), accompanied by a
247- written offer, valid for at least three years and valid for as
248- long as you offer spare parts or customer support for that product
249- model, to give anyone who possesses the object code either (1) a
250- copy of the Corresponding Source for all the software in the
251- product that is covered by this License, on a durable physical
252- medium customarily used for software interchange, for a price no
253- more than your reasonable cost of physically performing this
254- conveying of source, or (2) access to copy the
255- Corresponding Source from a network server at no charge.
256-257- c) Convey individual copies of the object code with a copy of the
258- written offer to provide the Corresponding Source. This
259- alternative is allowed only occasionally and noncommercially, and
260- only if you received the object code with such an offer, in accord
261- with subsection 6b.
262-263- d) Convey the object code by offering access from a designated
264- place (gratis or for a charge), and offer equivalent access to the
265- Corresponding Source in the same way through the same place at no
266- further charge. You need not require recipients to copy the
267- Corresponding Source along with the object code. If the place to
268- copy the object code is a network server, the Corresponding Source
269- may be on a different server (operated by you or a third party)
270- that supports equivalent copying facilities, provided you maintain
271- clear directions next to the object code saying where to find the
272- Corresponding Source. Regardless of what server hosts the
273- Corresponding Source, you remain obligated to ensure that it is
274- available for as long as needed to satisfy these requirements.
275-276- e) Convey the object code using peer-to-peer transmission, provided
277- you inform other peers where the object code and Corresponding
278- Source of the work are being offered to the general public at no
279- charge under subsection 6d.
280-281- A separable portion of the object code, whose source code is excluded
282-from the Corresponding Source as a System Library, need not be
283-included in conveying the object code work.
284-285- A "User Product" is either (1) a "consumer product", which means any
286-tangible personal property which is normally used for personal, family,
287-or household purposes, or (2) anything designed or sold for incorporation
288-into a dwelling. In determining whether a product is a consumer product,
289-doubtful cases shall be resolved in favor of coverage. For a particular
290-product received by a particular user, "normally used" refers to a
291-typical or common use of that class of product, regardless of the status
292-of the particular user or of the way in which the particular user
293-actually uses, or expects or is expected to use, the product. A product
294-is a consumer product regardless of whether the product has substantial
295-commercial, industrial or non-consumer uses, unless such uses represent
296-the only significant mode of use of the product.
297-298- "Installation Information" for a User Product means any methods,
299-procedures, authorization keys, or other information required to install
300-and execute modified versions of a covered work in that User Product from
301-a modified version of its Corresponding Source. The information must
302-suffice to ensure that the continued functioning of the modified object
303-code is in no case prevented or interfered with solely because
304-modification has been made.
305-306- If you convey an object code work under this section in, or with, or
307-specifically for use in, a User Product, and the conveying occurs as
308-part of a transaction in which the right of possession and use of the
309-User Product is transferred to the recipient in perpetuity or for a
310-fixed term (regardless of how the transaction is characterized), the
311-Corresponding Source conveyed under this section must be accompanied
312-by the Installation Information. But this requirement does not apply
313-if neither you nor any third party retains the ability to install
314-modified object code on the User Product (for example, the work has
315-been installed in ROM).
316-317- The requirement to provide Installation Information does not include a
318-requirement to continue to provide support service, warranty, or updates
319-for a work that has been modified or installed by the recipient, or for
320-the User Product in which it has been modified or installed. Access to a
321-network may be denied when the modification itself materially and
322-adversely affects the operation of the network or violates the rules and
323-protocols for communication across the network.
324-325- Corresponding Source conveyed, and Installation Information provided,
326-in accord with this section must be in a format that is publicly
327-documented (and with an implementation available to the public in
328-source code form), and must require no special password or key for
329-unpacking, reading or copying.
330-331- 7. Additional Terms.
332-333- "Additional permissions" are terms that supplement the terms of this
334-License by making exceptions from one or more of its conditions.
335-Additional permissions that are applicable to the entire Program shall
336-be treated as though they were included in this License, to the extent
337-that they are valid under applicable law. If additional permissions
338-apply only to part of the Program, that part may be used separately
339-under those permissions, but the entire Program remains governed by
340-this License without regard to the additional permissions.
341-342- When you convey a copy of a covered work, you may at your option
343-remove any additional permissions from that copy, or from any part of
344-it. (Additional permissions may be written to require their own
345-removal in certain cases when you modify the work.) You may place
346-additional permissions on material, added by you to a covered work,
347-for which you have or can give appropriate copyright permission.
348-349- Notwithstanding any other provision of this License, for material you
350-add to a covered work, you may (if authorized by the copyright holders of
351-that material) supplement the terms of this License with terms:
352-353- a) Disclaiming warranty or limiting liability differently from the
354- terms of sections 15 and 16 of this License; or
355-356- b) Requiring preservation of specified reasonable legal notices or
357- author attributions in that material or in the Appropriate Legal
358- Notices displayed by works containing it; or
359-360- c) Prohibiting misrepresentation of the origin of that material, or
361- requiring that modified versions of such material be marked in
362- reasonable ways as different from the original version; or
363-364- d) Limiting the use for publicity purposes of names of licensors or
365- authors of the material; or
366-367- e) Declining to grant rights under trademark law for use of some
368- trade names, trademarks, or service marks; or
369-370- f) Requiring indemnification of licensors and authors of that
371- material by anyone who conveys the material (or modified versions of
372- it) with contractual assumptions of liability to the recipient, for
373- any liability that these contractual assumptions directly impose on
374- those licensors and authors.
375-376- All other non-permissive additional terms are considered "further
377-restrictions" within the meaning of section 10. If the Program as you
378-received it, or any part of it, contains a notice stating that it is
379-governed by this License along with a term that is a further
380-restriction, you may remove that term. If a license document contains
381-a further restriction but permits relicensing or conveying under this
382-License, you may add to a covered work material governed by the terms
383-of that license document, provided that the further restriction does
384-not survive such relicensing or conveying.
385-386- If you add terms to a covered work in accord with this section, you
387-must place, in the relevant source files, a statement of the
388-additional terms that apply to those files, or a notice indicating
389-where to find the applicable terms.
390-391- Additional terms, permissive or non-permissive, may be stated in the
392-form of a separately written license, or stated as exceptions;
393-the above requirements apply either way.
394-395- 8. Termination.
396-397- You may not propagate or modify a covered work except as expressly
398-provided under this License. Any attempt otherwise to propagate or
399-modify it is void, and will automatically terminate your rights under
400-this License (including any patent licenses granted under the third
401-paragraph of section 11).
402-403- However, if you cease all violation of this License, then your
404-license from a particular copyright holder is reinstated (a)
405-provisionally, unless and until the copyright holder explicitly and
406-finally terminates your license, and (b) permanently, if the copyright
407-holder fails to notify you of the violation by some reasonable means
408-prior to 60 days after the cessation.
409-410- Moreover, your license from a particular copyright holder is
411-reinstated permanently if the copyright holder notifies you of the
412-violation by some reasonable means, this is the first time you have
413-received notice of violation of this License (for any work) from that
414-copyright holder, and you cure the violation prior to 30 days after
415-your receipt of the notice.
416-417- Termination of your rights under this section does not terminate the
418-licenses of parties who have received copies or rights from you under
419-this License. If your rights have been terminated and not permanently
420-reinstated, you do not qualify to receive new licenses for the same
421-material under section 10.
422-423- 9. Acceptance Not Required for Having Copies.
424-425- You are not required to accept this License in order to receive or
426-run a copy of the Program. Ancillary propagation of a covered work
427-occurring solely as a consequence of using peer-to-peer transmission
428-to receive a copy likewise does not require acceptance. However,
429-nothing other than this License grants you permission to propagate or
430-modify any covered work. These actions infringe copyright if you do
431-not accept this License. Therefore, by modifying or propagating a
432-covered work, you indicate your acceptance of this License to do so.
433-434- 10. Automatic Licensing of Downstream Recipients.
435-436- Each time you convey a covered work, the recipient automatically
437-receives a license from the original licensors, to run, modify and
438-propagate that work, subject to this License. You are not responsible
439-for enforcing compliance by third parties with this License.
440-441- An "entity transaction" is a transaction transferring control of an
442-organization, or substantially all assets of one, or subdividing an
443-organization, or merging organizations. If propagation of a covered
444-work results from an entity transaction, each party to that
445-transaction who receives a copy of the work also receives whatever
446-licenses to the work the party's predecessor in interest had or could
447-give under the previous paragraph, plus a right to possession of the
448-Corresponding Source of the work from the predecessor in interest, if
449-the predecessor has it or can get it with reasonable efforts.
450-451- You may not impose any further restrictions on the exercise of the
452-rights granted or affirmed under this License. For example, you may
453-not impose a license fee, royalty, or other charge for exercise of
454-rights granted under this License, and you may not initiate litigation
455-(including a cross-claim or counterclaim in a lawsuit) alleging that
456-any patent claim is infringed by making, using, selling, offering for
457-sale, or importing the Program or any portion of it.
458-459- 11. Patents.
460-461- A "contributor" is a copyright holder who authorizes use under this
462-License of the Program or a work on which the Program is based. The
463-work thus licensed is called the contributor's "contributor version".
464-465- A contributor's "essential patent claims" are all patent claims
466-owned or controlled by the contributor, whether already acquired or
467-hereafter acquired, that would be infringed by some manner, permitted
468-by this License, of making, using, or selling its contributor version,
469-but do not include claims that would be infringed only as a
470-consequence of further modification of the contributor version. For
471-purposes of this definition, "control" includes the right to grant
472-patent sublicenses in a manner consistent with the requirements of
473-this License.
474-475- Each contributor grants you a non-exclusive, worldwide, royalty-free
476-patent license under the contributor's essential patent claims, to
477-make, use, sell, offer for sale, import and otherwise run, modify and
478-propagate the contents of its contributor version.
479-480- In the following three paragraphs, a "patent license" is any express
481-agreement or commitment, however denominated, not to enforce a patent
482-(such as an express permission to practice a patent or covenant not to
483-sue for patent infringement). To "grant" such a patent license to a
484-party means to make such an agreement or commitment not to enforce a
485-patent against the party.
486-487- If you convey a covered work, knowingly relying on a patent license,
488-and the Corresponding Source of the work is not available for anyone
489-to copy, free of charge and under the terms of this License, through a
490-publicly available network server or other readily accessible means,
491-then you must either (1) cause the Corresponding Source to be so
492-available, or (2) arrange to deprive yourself of the benefit of the
493-patent license for this particular work, or (3) arrange, in a manner
494-consistent with the requirements of this License, to extend the patent
495-license to downstream recipients. "Knowingly relying" means you have
496-actual knowledge that, but for the patent license, your conveying the
497-covered work in a country, or your recipient's use of the covered work
498-in a country, would infringe one or more identifiable patents in that
499-country that you have reason to believe are valid.
500-501- If, pursuant to or in connection with a single transaction or
502-arrangement, you convey, or propagate by procuring conveyance of, a
503-covered work, and grant a patent license to some of the parties
504-receiving the covered work authorizing them to use, propagate, modify
505-or convey a specific copy of the covered work, then the patent license
506-you grant is automatically extended to all recipients of the covered
507-work and works based on it.
508-509- A patent license is "discriminatory" if it does not include within
510-the scope of its coverage, prohibits the exercise of, or is
511-conditioned on the non-exercise of one or more of the rights that are
512-specifically granted under this License. You may not convey a covered
513-work if you are a party to an arrangement with a third party that is
514-in the business of distributing software, under which you make payment
515-to the third party based on the extent of your activity of conveying
516-the work, and under which the third party grants, to any of the
517-parties who would receive the covered work from you, a discriminatory
518-patent license (a) in connection with copies of the covered work
519-conveyed by you (or copies made from those copies), or (b) primarily
520-for and in connection with specific products or compilations that
521-contain the covered work, unless you entered into that arrangement,
522-or that patent license was granted, prior to 28 March 2007.
523-524- Nothing in this License shall be construed as excluding or limiting
525-any implied license or other defenses to infringement that may
526-otherwise be available to you under applicable patent law.
527-528- 12. No Surrender of Others' Freedom.
529-530- If conditions are imposed on you (whether by court order, agreement or
531-otherwise) that contradict the conditions of this License, they do not
532-excuse you from the conditions of this License. If you cannot convey a
533-covered work so as to satisfy simultaneously your obligations under this
534-License and any other pertinent obligations, then as a consequence you may
535-not convey it at all. For example, if you agree to terms that obligate you
536-to collect a royalty for further conveying from those to whom you convey
537-the Program, the only way you could satisfy both those terms and this
538-License would be to refrain entirely from conveying the Program.
539-540- 13. Remote Network Interaction; Use with the GNU General Public License.
541-542- Notwithstanding any other provision of this License, if you modify the
543-Program, your modified version must prominently offer all users
544-interacting with it remotely through a computer network (if your version
545-supports such interaction) an opportunity to receive the Corresponding
546-Source of your version by providing access to the Corresponding Source
547-from a network server at no charge, through some standard or customary
548-means of facilitating copying of software. This Corresponding Source
549-shall include the Corresponding Source for any work covered by version 3
550-of the GNU General Public License that is incorporated pursuant to the
551-following paragraph.
552-553- Notwithstanding any other provision of this License, you have
554-permission to link or combine any covered work with a work licensed
555-under version 3 of the GNU General Public License into a single
556-combined work, and to convey the resulting work. The terms of this
557-License will continue to apply to the part which is the covered work,
558-but the work with which it is combined will remain governed by version
559-3 of the GNU General Public License.
560-561- 14. Revised Versions of this License.
562-563- The Free Software Foundation may publish revised and/or new versions of
564-the GNU Affero General Public License from time to time. Such new versions
565-will be similar in spirit to the present version, but may differ in detail to
566-address new problems or concerns.
567-568- Each version is given a distinguishing version number. If the
569-Program specifies that a certain numbered version of the GNU Affero General
570-Public License "or any later version" applies to it, you have the
571-option of following the terms and conditions either of that numbered
572-version or of any later version published by the Free Software
573-Foundation. If the Program does not specify a version number of the
574-GNU Affero General Public License, you may choose any version ever published
575-by the Free Software Foundation.
576-577- If the Program specifies that a proxy can decide which future
578-versions of the GNU Affero General Public License can be used, that proxy's
579-public statement of acceptance of a version permanently authorizes you
580-to choose that version for the Program.
581-582- Later license versions may give you additional or different
583-permissions. However, no additional obligations are imposed on any
584-author or copyright holder as a result of your choosing to follow a
585-later version.
586-587- 15. Disclaimer of Warranty.
588-589- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597-598- 16. Limitation of Liability.
599-600- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608-SUCH DAMAGES.
609-610- 17. Interpretation of Sections 15 and 16.
611-612- If the disclaimer of warranty and limitation of liability provided
613-above cannot be given local legal effect according to their terms,
614-reviewing courts shall apply local law that most closely approximates
615-an absolute waiver of all civil liability in connection with the
616-Program, unless a warranty or assumption of liability accompanies a
617-copy of the Program in return for a fee.
618-619- END OF TERMS AND CONDITIONS
620-621- How to Apply These Terms to Your New Programs
622-623- If you develop a new program, and you want it to be of the greatest
624-possible use to the public, the best way to achieve this is to make it
625-free software which everyone can redistribute and change under these terms.
626-627- To do so, attach the following notices to the program. It is safest
628-to attach them to the start of each source file to most effectively
629-state the exclusion of warranty; and each file should have at least
630-the "copyright" line and a pointer to where the full notice is found.
631-632- <one line to give the program's name and a brief idea of what it does.>
633- Copyright (C) <year> <name of author>
634-635- This program is free software: you can redistribute it and/or modify
636- it under the terms of the GNU Affero General Public License as published
637- by the Free Software Foundation, either version 3 of the License, or
638- (at your option) any later version.
639-640- This program is distributed in the hope that it will be useful,
641- but WITHOUT ANY WARRANTY; without even the implied warranty of
642- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643- GNU Affero General Public License for more details.
644-645- You should have received a copy of the GNU Affero General Public License
646- along with this program. If not, see <https://www.gnu.org/licenses/>.
647-648-Also add information on how to contact you by electronic and paper mail.
649-650- If your software can interact with users remotely through a computer
651-network, you should also make sure that it provides a way for users to
652-get its source. For example, if your program is a web application, its
653-interface could display a "Source" link that leads users to an archive
654-of the code. There are many ways you could offer source, and different
655-solutions will be better for different programs; see section 13 for the
656-specific requirements.
657-658- You should also get your employer (if you work as a programmer) or school,
659-if any, to sign a "copyright disclaimer" for the program, if necessary.
660-For more information on this, and how to apply and follow the GNU AGPL, see
661-<https://www.gnu.org/licenses/>.
···1-# wire
2-3-
4-
5-
67wire is a tool to deploy nixos systems. its usage is inspired by colmena however it is not a fork.
89-Read the [The Guide](https://wire.althaea.zone/guide/wire.html), or continue reading this readme for development information.
10-11-## Tree Layout
12-13-```
14-wire
15-โโโ wire
16-โ โโโ lib
17-โ โ โโโ Rust library containing business logic, consumed by `wire`
18-โ โโโ cli
19-โ โ โโโ Rust binary, using `lib`
20-โ โโโ key_agent
21-โ โโโ Rust binary ran on a target node. recieves key file bytes and metadata w/ protobuf over SSH stdin
22-โโโ doc
23-โ โโโ a [vitepress](https://vitepress.dev/) site
24-โโโ runtime
25-โ โโโ Nix files used during runtime to evaluate nodes
26-โโโtests
27- โโโ Directories used during cargo & NixOS VM testing
28-```
2930## Development
3132Please use `nix develop` for access to the development environment and to ensure
33your changes are ran against the defined git hooks. For simplicity, you may wish
34to use [direnv](https://github.com/direnv/direnv).
35-36-### Testing
37-38-#### dhat profiling
39-40-```sh
41-$ just build-dhat
42-```
43-44-#### Testing
45-46-```sh
47-$ cargo test
48-$ nix flake check
49-```
···1+
2+
3+
0045wire is a tool to deploy nixos systems. its usage is inspired by colmena however it is not a fork.
67+Read the [The Tutorial](https://wire.althaea.zone/tutorial/overview.html), [Guides](https://wire.althaea.zone/guides/installation.html), or continue reading this readme for development information.
000000000000000000089## Development
1011Please use `nix develop` for access to the development environment and to ensure
12your changes are ran against the defined git hooks. For simplicity, you may wish
13to use [direnv](https://github.com/direnv/direnv).
000000000000000
···1+// SPDX-License-Identifier: AGPL-3.0-or-later
2+// Copyright 2024-2025 wire Contributors
3+4+pub mod activate;
5+pub mod build;
6+pub mod cleanup;
7+pub mod evaluate;
8+pub mod keys;
9+pub mod ping;
10+pub mod push;
···1----
2-comment: true
3-title: Getting Started
4-description: Getting started with Wire Tool!
5----
6-7-# {{ $frontmatter.title }}
8-9-## Installation
10-11-Wire can be heavy to compile. You should enable the substituter `wires.cachix.org`.
12-13-::: code-group
14-15-<<< @/snippets/getting-started/cache.nix [module.nix]
16-<<< @/snippets/getting-started/nix.conf
17-18-:::
19-20-### Supported Nix & NixOS versions
21-22-Wire is currently _tested_ against `unstable`, `24.11` and `25.05`.
23-For each channel, it is tested against the given channel's `pkgs.lix`.
24-25-There is currently a bug when our VM tests are ran with nixcpp. Nixcpp will try
26-to download a file in a network sandbox, whereas Lix will not. We don't know
27-how to solve it. Please see [#126](https://github.com/wires-org/wire/issues/126)
28-29-### NixOS / Home Manager
30-31-::: code-group
32-33-<<< @/snippets/getting-started/nixos.flake.nix [flake.nix (NixOS)]
34-<<< @/snippets/getting-started/hm.flake.nix [flake.nix (Home Manager)]
35-<<< @/snippets/getting-started/configuration.nix
36-<<< @/snippets/getting-started/home.nix
37-38-:::
39-40-## Your First Hive
41-42-Wire groups your machines into _nodes_, which are NixOS configurations with
43-additional information for deployment. Start by creating a `hive.nix` in the same directory as your
44-`configuration.nix`.
45-46-::: info
47-48-To include wire in these examples, we are using
49-[npins](https://github.com/andir/npins). To create this setup you
50-would run `npins add github wires-org wire`.
51-52-:::
53-54-A `hive.nix` is an attribute set with NixOS configurations, each with a unique
55-name. Add a node for your local machine:
56-57-```nix:line-numbers [hive.nix]
58-let
59- sources = import ./npins;
60- wire = import sources.wire;
61-in wire.makeHive {
62- meta.nixpkgs = import sources.nixpkgs { };
63-64- my-local-machine = {
65- imports = [./configuration.nix];
66-67- # If you don't know, find this value by running
68- # `nix eval --expr 'builtins.currentSystem' --impure`
69- nixpkgs.hostPlatform = "x86_64-linux";
70- };
71-}
72-```
73-74-Now, assuming your host machine is currently `my-local-machine`, simply running
75-[`wire apply`](/reference/cli.html#wire-apply) will evaluate, build, and
76-activate your system, which would be the equivalent of `nixos-rebuild switch`.
77-78-```sh
79-wire apply switch -v
80-```
81-82-### A Remote Machine
83-84-Lets add another node to your hive! This one is an example of a remote machine.
85-86-```nix:line-numbers [hive.nix]
87-let
88- sources = import ./npins;
89- wire = import sources.wire;
90-in wire.makeHive {
91- meta.nixpkgs = import sources.nixpkgs { };
92-93- my-local-machine = {
94- imports = [./local-machine/configuration.nix];
95- nixpkgs.hostPlatform = "x86_64-linux";
96- };
97-98- my-remote-machine = {
99- deployment = {
100- # buildOnTarget defaults to `false`, enable this
101- # if the machine is strong enough to build itself.
102- buildOnTarget = true;
103- target = {
104- # Some IP or host that this node is reachable by ssh under,
105- # defaults to "my-remote-machine" (node name).
106- host = "10.1.1.2";
107- # A user you can non-interactively login through ssh by,
108- # defaults to "root".
109- user = "root";
110- };
111- };
112- imports = [./remote-machine/configuration.nix];
113- nixpkgs.hostPlatform = "x86_64-linux";
114- };
115-}
116-```
117-118-> [!TIP]
119-> Read more options in [the reference](/reference/module#deployment-target) to adjust options such as
120-> ssh port.
121-122-To deploy the node `my-remote-machine`, lets use `wire apply` again. Wire will
123-apply both nodes in the hive at once, one local and one remote:
124-125-```sh
126-wire apply switch -v
127-```
···1----
2-comment: true
3-title: hive.default
4-description: Deduplicate options with default node configuration.
5----
6-7-# `{{ $frontmatter.title }}`
8-9-{{ $frontmatter.description }}
10-11-## Introduction
12-13-At the top level of a hive wire reserves the `defaults` attribute. It's applied
14-to every node.
15-16-::: warning
17-18-`defaults` must not rely on modules that a node imports, but a
19-node may rely on modules that default imports.
20-21-:::
22-23-```nix:line-numbers [hive.nix]
24-let
25- sources = import ./npins;
26- wire = import sources.wire;
27-in wire.makeHive {
28- meta.nixpkgs = import sources.nixpkgs { };
29-30- defaults = {
31- # name of the node that defaults is being applied to
32- name,
33- # attribute set of all nodes
34- nodes,
35- ...
36- }: {
37- import = [
38- ./default-module.nix
39-40- # module that is imported for all nodes
41- some-flake.nixosModules.default
42- ];
43-44- # default configuration
45- # may or may not utilise `name` or `nodes`
46- };
47-48- node-a = {
49- # some config
50- };
51-52- node-b = {
53- # some more config
54- };
55-}
56-```
···1----
2-comment: true
3-title: Secret Management
4-description: Keys, files, and other out-of-store paths with Wire Tool.
5----
6-7-# {{ $frontmatter.title }}
8-9-{{ $frontmatter.description }}
10-11-## Introduction
12-13-Wire Tool is very unopinionated as to how you encrypt your secrets, Wire only
14-handles pushing and setting up permissions of your key files.
15-16-The `source` of your key can be a literal string (unencrypted), a path
17-(unencrypted), or a command that wire runs to evaluate the key. Programs that
18-work well with wire keys include:
19-20-- GPG
21-- [Age](https://github.com/FiloSottile/age)
22-- Anything that non-interactively decrypts to `stdout`.
23-24-### A Trivial "Key"
25-26-```nix:line-numbers [hive.nix]
27-let
28- sources = import ./npins;
29- wire = import sources.wire;
30-in wire.makeHive {
31- meta.nixpkgs = import sources.nixpkgs { };
32-33- node-1 = {
34- deployment.key."file.txt" = {
35- source = ''
36- Hello World!
37- '';
38- };
39- };
40-}
41-```
42-43-```sh
44-[user@node-1]$ cat /run/keys/file.txt
45-Hello World!
46-```
47-48-### Encrypting with GPG
49-50-```nix:line-numbers [hive.nix]
51-let
52- sources = import ./npins;
53- wire = import sources.wire;
54-in wire.makeHive {
55- meta.nixpkgs = import sources.nixpkgs { };
56-57- node-1 = {
58- deployment.key."file.txt" = {
59- source = [
60- "gpg"
61- "--decrypt"
62- "${./secrets/file.txt.gpg}"
63- ];
64- };
65- };
66-}
67-```
68-69-```sh
70-[user@node-1]$ cat /run/keys/file.txt
71-Hello World!
72-```
73-74-### A Plain Text File
75-76-```nix:line-numbers [hive.nix]
77-let
78- sources = import ./npins;
79- wire = import sources.wire;
80-in wire.makeHive {
81- meta.nixpkgs = import sources.nixpkgs { };
82-83- node-1 = {
84- deployment.key."file.txt" = {
85- # using this syntax will enter the file into the store, readable by
86- # anyone!
87- source = ./file.txt;
88- };
89- };
90-}
91-```
92-93-## Persistence
94-95-Wire defaults `destDir` to `/run/keys`. `/run/` is held in memory and will not
96-persist past reboot. Change
97-[`deployment.key.<name>.destDir`](/reference/module#deployment-keys-name-destdir)
98-to something like `/etc/keys` if you need secrets every time the machine boots.
99-100-## Upload Order
101-102-By default Wire will upload keys before the system is activated. You can
103-force Wire to upload the key after the system is activated by setting
104-[`deployment.keys.<name>.uploadAt`](/reference/module#deployment-keys-name-uploadat)
105-to `post-activation`.
106-107-## Permissions and Ownership
108-109-Wire secrets are owned by user & group `root` (`0600`). You can change these
110-with the `user` and `group` option.
111-112-```nix:line-numbers [hive.nix]
113-let
114- sources = import ./npins;
115- wire = import sources.wire;
116-in wire.makeHive {
117- meta.nixpkgs = import sources.nixpkgs { };
118-119- node-1 = {
120- deployment.key."file.txt" = {
121- source = [
122- "gpg"
123- "--decrypt"
124- "${./secrets/file.txt.gpg}"
125- ];
126-127- user = "my-user";
128- group = "my-group";
129- };
130- };
131-}
132-```
133-134-## Further Examples
135-136-### Using Keys With Services
137-138-You can access the full absolute path of any key with
139-`config.deployment.keys.<name>.path` (auto-generated and read-only).
140-Here's an example with the Tailscale service:
141-142-```nix:line-numbers [hive.nix]
143-let
144- sources = import ./npins;
145- wire = import sources.wire;
146-in wire.makeHive {
147- meta.nixpkgs = import sources.nixpkgs { };
148-149- node-1 = {config, ...}: {
150- services.tailscale = {
151- enable = true;
152- # use deployment key path directly
153- authKeyFile = config.deployment.keys."tailscale.key".path;
154- };
155-156- deployment.keys."tailscale.key" = {
157- keyCommand = ["gpg" "--decrypt" "${./secrets/tailscale.key.gpg}"];
158- };
159- };
160-}
161-```
162-163-### Scoping a Key to a service account
164-165-Additionally you can scope the key to the user that the service runs under, to
166-further reduce duplication using the `config` argument. Here's an example of
167-providing a certificate that is only readable by the caddy service.
168-169-```nix:line-numbers [hive.nix]
170-let
171- sources = import ./npins;
172- wire = import sources.wire;
173-in wire.makeHive {
174- meta.nixpkgs = import sources.nixpkgs { };
175-176- some-web-server = {config, ...}: {
177- deployment.keys."some.host.pem" = {
178- keyCommand = ["gpg" "--decrypt" "${./some.host.pem.gpg}"];
179- destDir = "/etc/keys";
180-181- # inherit the user and group that caddy runs under
182- # the key will only readable by the caddy service
183- inherit (config.services.caddy) user group;
184- };
185-186- # ^^ repeat for `some.host.key`
187-188- services.caddy = {
189- virtualHosts."https://some.host".extraConfig = ''
190- tls ${config.deployment.keys."some.host.pem".path} ${config.deployment.keys."some.host.key".path}
191- '';
192- };
193- };
194-}
195-```
···1-# Magic Rollback
2-3-Magic Rollback is unimplemented.
···000
-32
doc/guide/parallelism.md
···1----
2-comment: true
3-title: Parallelism
4-description: A deeper dive into parallelism with Wire Tool.
5----
6-7-# {{ $frontmatter.title }}
8-9-{{ $frontmatter.description }}
10-11-## Controlling CPU Usage
12-13-Wire evaluates, builds, pushes, and deploys each node completely independently
14-from each other. Internally Wire calls this process a "node execution".
15-16-The default number of parallel _node executions_ is `10`, which can be
17-controlled with the `-p` / `--parallel` argument.
18-19-```sh
20-wire apply -p <NUMBER>
21-```
22-23-## Interaction with Nix's `max-jobs`
24-25-Nix has an overall derivation build limit and core limit.
26-If executing a node fills Nix's `max-jobs` all other nodes will bottleneck. You
27-should read [the relevant
28-documentation](https://nix.dev/manual/nix/2.28/advanced-topics/cores-vs-jobs) to fine tune these settings.
29-30-When a Node is built remotely due to
31-[`deployment.buildOnTarget`](/reference/module.html#deployment-buildontarget)
32-that node will not push up the _local machine's_ max-jobs limit.
···1----
2-comment: true
3-title: Targeting Nodes
4-description: Tags, nodes, and how to target them with Wire Tool.
5----
6-7-# {{ $frontmatter.title }}
8-9-{{ $frontmatter.description }}
10-11-## The Basics
12-13-Nodes can have _tags_, which allows you to easily target multiple, related
14-nodes for deployment.
15-16-```nix:line-numbers [hive.nix]
17-let
18- sources = import ./npins;
19- wire = import sources.wire;
20-in wire.makeHive {
21- meta.nixpkgs = import sources.nixpkgs { };
22-23- node-1 = {
24- # ...
25- deployment.tags = ["cloud"];
26- };
27- node-2 = {
28- # ...
29- deployment.tags = ["cloud", "virtual"];
30- };
31- node-3 = {
32- # ...
33- deployment.tags = ["on-prem"];
34- };
35- node-4 = {
36- # ...
37- deployment.tags = ["virtual"];
38- };
39- node-5 = {
40- # Untagged
41- };
42-}
43-```
44-45-To target all nodes with a specific tag, prefix tags with an `@`.
46-For example, to deploy only nodes with the `cloud` tag, use
47-48-```sh
49-wire apply --on @cloud
50-```
51-52-## Further Examples
53-54-::: info
55-56-Other operations such as an `--ignore` argument are unimplemented as of wire `v0.2.0`.
57-58-:::
59-60-### Mixing Tags with Node Names
61-62-`--on` without an `@` prefix interprets as a literal node name. You can mix tags
63-and node names with `--on`:
64-65-```sh
66-wire apply --on @cloud node-5
67-```
68-69-This will deploy all nodes in `@cloud`, alongside the node `node-5`.
70-71-### Targeting Many Tags (Union)
72-73-You can specify many tags together:
74-75-```sh
76-wire apply --on @cloud @on-prem
77-```
78-79-This is a union between `@cloud` and `@on-prem`.
···1----
2-comment: true
3----
4-5-# What is Wire?
6-7-<p style="display: flex; gap: 8px">
8- <a href="https://github.com/wires-org/wire/actions/workflows/test.yml?query=branch%3Amain">
9- <img alt="Test Suite Status" src="https://img.shields.io/github/actions/workflow/status/wires-org/wire/test.yml?branch=main&style=flat-square&label=Test%20Suite">
10- </a>
11-12- <a href="https://github.com/wires-org/wire/actions/workflows/build.yml?query=branch%3Amain">
13- <img alt="Build Status" src="https://img.shields.io/github/actions/workflow/status/wires-org/wire/build.yml?branch=main&style=flat-square&label=Builds">
14- </a>
15-16- <a href="https://github.com/wires-org/wire/actions/workflows/pages.yml?query=branch%3Amain">
17- <img alt="Documentation Status" src="https://img.shields.io/github/actions/workflow/status/wires-org/wire/pages.yml?branch=main&style=flat-square&label=Documentation">
18- </a>
19-</p>
20-21-Wire is a tool to deploy NixOS systems. Its usage is inspired by [colmena](https://colmena.cli.rs/). In many places it's configuration attempts to remain a superset[^1] of colmena, however it is **not** a fork.
22-23-[^1]: A lot of your colmena module options will continue to work with wire, but wire has additional ergonomic changes you can take advantage of.
24-25-::: warning
26-Wire is alpha software, please use at your own risk. Many features listed in this documentation may not be complete / implemented.
27-:::
28-29-<div class="tip custom-block" style="padding-top: 8px">
30-31-Ready? Skip to the [Quickstart](./getting-started).
32-33-</div>
34-35-## Why Wire?
36-37-::: info
38-The following is the goal for a stable release and not fully implemented.
39-:::
40-41-| Features | Wire | Colmena |
42-| --------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------- |
43-| Secret Management | :white_check_mark: | :white_check_mark: |
44-| Parallel Evaluation | :white_check_mark: | [Experimental](https://colmena.cli.rs/unstable/features/parallelism.html#parallel-evaluation-experimental) |
45-| Node Tagging | :white_check_mark: | :white_check_mark: |
46-| `jq` pipeline support | :white_check_mark: | :x:[^2] |
47-| Magic Rollback | :white_check_mark: (Planned) | :x: |
48-49-[^2]: You need to write custom nix code to use Colmena hive metadata inside environments like CI pipelines, bash scripting, etc., which requires a knowledge of its internals.
···1+---
2+comment: true
3+title: Apply your Config
4+description: How to apply a node with wire.
5+---
6+7+# Apply your Config
8+9+{{ $frontmatter.description }}
10+11+## What does it mean to 'apply'?
12+13+Once you have created a hive, you can now "apply" your
14+configuration to nodes in your hive. Simply, "applying" is the term used by wire to describe **deploying the
15+config**.
16+17+::: info
18+Applying a node typically involves pushing keys,
19+evaluating the node's NixOS system, building the node's NixOS system, and running
20+`switch-to-configuration`, depending on which specific goal is used.
21+:::
22+23+The simplest way to apply is simply running:
24+25+```sh
26+$ wire apply switch
27+```
28+29+Which will `switch` to each node's NixOS system in your hive and push
30+secrets (the equivalent to `nixos-rebuild`'s `nixos-rebuild switch`).
31+32+## Apply goals
33+34+`wire apply` accepts a goal, which include verbs which will be familiar to
35+`nixos-rebuild` users such as `switch`, `boot`, and `test`, alongside additional verbs
36+like `keys` and `push`.
37+38+### `wire apply keys`
39+40+wire will push all deployment keys to nodes, and do nothing else. While running
41+this goal, option
42+[`deployment.keys.<name>.uploadAt`](/reference/module#deployment-keys-name-uploadat)
43+has no effect and all keys will be pushed. Read [the secret management guide](./keys)
44+to learn more about wire deployment keys.
45+46+### `wire apply push`
47+48+wire will "push" (equivalent to [`nix
49+copy`](https://nix.dev/manual/nix/2.18/command-ref/new-cli/nix3-copy)) the
50+`.drv` file that can produce the node's NixOS system when built.
51+52+### `wire apply build`
53+54+Sister to `wire apply push`, wire will build the
55+node's NixOS system and ensure the output path exists on the node. Depending on
56+[`deployment.buildOnTarget`](/reference/module#deployment-buildontarget), the
57+`.drv` file may be built on the machine invoking wire or the node itself.
58+59+### `wire apply [switch|boot|test|dry-activate]`
60+61+Type `wire apply --help` or
62+[read the reference](../reference/cli#wire-apply) to read more.
63+64+## Applying locally
65+66+If `deployment.allowLocalDeployment` is `true`, and the machine invoking wire's
67+host name is equivalent to a node's name, wire will apply that node to the local
68+machine. Goals like `push` and `build`, wont actually "push" anything as
69+the paths already exists on the local machine.
70+71+When applying to your local machine, wire can interactively run `sudo`!
72+wire will prompt for your password, meaning wire can be ran as any user in
73+the `wheel` group.
74+75+## Applying specific nodes
76+77+Use the `--on` argument to specify which nodes in your hive to apply:
78+79+```sh
80+$ wire apply --on node-a
81+```
82+83+Further examples, including how you can utilise tags, can be found on the [Targeting Nodes](./targeting) page.
+36
doc/guides/build-in-ci.md
···000000000000000000000000000000000000
···1+---
2+comment: true
3+title: Build in CI
4+---
5+6+# Build in CI
7+8+## The `wire build` command <Badge type="tip" text="^1.1.0" />
9+10+`wire build` builds nodes locally. It is distinct from
11+`wire apply build`, as it will not ping or push the result,
12+making it useful for CI.
13+14+It accepts the same `--on` argument as `wire apply` does.
15+16+## Partitioning builds
17+18+`wire build` accepts a `--partition` option inspired by
19+[cargo-nextest](https://nexte.st/docs/ci-features/partitioning/), which splits
20+selected nodes into buckets to be built separately.
21+22+It accepts values in the format `--partition current/total`, where 1 โค current โค total.
23+24+For example, these two commands will build the entire hive in two invocations:
25+26+```sh
27+wire build --partition 1/2
28+29+# later or synchronously:
30+31+wire build --partition 2/2
32+```
33+34+## Example: Build in Github Actions
35+36+<<< @/snippets/guides/example-action.yml [.github/workflows/build.yml]
+42
doc/guides/flakes/nixos-rebuild.md
···000000000000000000000000000000000000000000
···1+---
2+comment: true
3+title: Keep Using nixos-rebuild
4+description: How to combine outputs.nixosConfigurations with outputs.wire
5+---
6+7+# Keep Using nixos-rebuild
8+9+{{ $frontmatter.description }}
10+11+## An Example
12+13+You can provide `makeHive` with your `nixosConfigurations` with the `inherit`
14+nix keyword. `makeHive` will merge any nodes and nixosConfigurations that share
15+the same name together.
16+17+::: tip
18+You should include the wire module, which will provide the `deployment` options, even if nixos-rebuild can't directly use them.
19+:::
20+21+::: code-group
22+<<< @/snippets/getting-started/flake-merged.nix [flake.nix]
23+:::
24+25+Now, if we run `wire show`, you will see that wire only finds
26+the `nixosConfigurations`-es that also match a node in the hive.
27+`some-other-host` is not included in the hive unless specified in `makeHive`.
28+29+```
30+$ wire show
31+Node node-a (x86_64-linux):
32+33+ > Connection: {root@node-a:22}
34+ > Build remotely `deployment.buildOnTarget`: false
35+ > Local apply allowed `deployment.allowLocalDeployment`: true
36+37+Summary: 1 total node(s), totalling 0 keys (0 distinct).
38+Note: Listed connections are tried from Left to Right
39+40+```
41+42+This way, you can continue using `nixos-rebuild` and wire at the same time.
+40
doc/guides/flakes/overview.md
···0000000000000000000000000000000000000000
···1+---
2+comment: true
3+title: Use Flakes
4+description: How to output a hive from a flake.
5+---
6+7+# Use Flakes
8+9+{{ $frontmatter.description }}
10+11+## Output a hive
12+13+::: tip
14+If you have skipped ahead, please read the previous page to understand the
15+concept of a hive.
16+:::
17+18+You can use wire with a flake by outputting a hive with the `wire` flake output.
19+Just like when using a `hive.nix`, you must provide `meta.nixpkgs` which will
20+come from an input.
21+22+::: code-group
23+<<< @/snippets/getting-started/flake.nix [flake.nix]
24+:::
25+26+```
27+$ nix flake show
28+git+file:///some/path
29+โโโโwire: unknown
30+31+$ wire show
32+Node node-a (x86_64-linux):
33+34+ > Connection: {root@node-a:22}
35+ > Build remotely `deployment.buildOnTarget`: false
36+ > Local apply allowed `deployment.allowLocalDeployment`: true
37+38+Summary: 1 total node(s), totalling 0 keys (0 distinct).
39+Note: Listed connections are tried from Left to Right
40+```
···1+---
2+comment: true
3+title: Use hive.default
4+description: Deduplicate options with default node configuration.
5+---
6+7+# `Use hive.default`
8+9+{{ $frontmatter.description }}
10+11+## Introduction
12+13+At the top level of a hive wire reserves the `defaults` attribute. It's applied
14+to every node.
15+16+::: warning
17+18+`defaults` must not rely on modules that a node imports, but a
19+node may rely on modules that default imports.
20+21+:::
22+23+```nix:line-numbers [hive.nix]
24+let
25+ sources = import ./npins;
26+ wire = import sources.wire;
27+in wire.makeHive {
28+ meta.nixpkgs = import sources.nixpkgs { };
29+30+ defaults = {
31+ # name of the node that defaults is being applied to
32+ name,
33+ # attribute set of all nodes
34+ nodes,
35+ ...
36+ }: {
37+ import = [
38+ ./default-module.nix
39+40+ # module that is imported for all nodes
41+ some-flake.nixosModules.default
42+ ];
43+44+ # default configuration
45+ # may or may not utilise `name` or `nodes`
46+ };
47+48+ node-a = {
49+ # some config
50+ };
51+52+ node-b = {
53+ # some more config
54+ };
55+}
56+```
···1+---
2+comment: true
3+title: Install wire
4+description: How to install wire tool.
5+---
6+7+# Install wire
8+9+{{ $frontmatter.description }}
10+11+::: info
12+13+The `wire` binary and the `wire.makeHive` function are tightly coupled, so it is
14+recommended that you use the same version for both.
15+16+:::
17+18+It is recommended you stick to either using a tagged version of wire, or the `stable` branch which tracks the latest stable tag.
19+20+## Binary Cache
21+22+You should enable the [garnix binary cache](https://garnix.io/docs/caching) _before_
23+continuing otherwise you will be compiling from source:
24+25+::: code-group
26+<<< @/snippets/tutorial/cache.conf [nix.conf]
27+<<< @/snippets/tutorial/cache.nix [configuration.nix]
28+:::
29+30+## Installation through flakes
31+32+When using flakes, you should install wire through the same input you create
33+your hive from, sourced from the `stable` branch.
34+35+::: code-group
36+<<< @/snippets/guides/installation/flake.nix [flake.nix]
37+:::
38+39+## Installation through npins
40+41+With npins you may allow it to use release tags instead of the `stable`
42+branch.
43+44+Using npins specifically is not required, you can pin your sources in any way
45+you'd like, really.
46+47+```sh
48+$ npins add github forallsys wire --branch stable
49+```
50+51+Alternatively, you can use a tag instead:
52+53+```sh
54+$ npins add github forallsys wire --at v1.1.1
55+```
56+57+Then, use this pinned version of wire for both your `hive.nix` and `shell.nix`:
58+59+<<< @/snippets/guides/installation/shell.nix{8} [shell.nix]
60+<<< @/snippets/guides/installation/hive.nix [hive.nix]
···1+---
2+comment: true
3+title: Manage Secrets
4+description: Manage keys, secrets, files, and other out-of-store paths with wire Tool.
5+---
6+7+# Manage Secrets
8+9+{{ $frontmatter.description }}
10+11+## Introduction
12+13+wire Tool is very unopinionated as to how you encrypt your secrets, wire only
14+handles pushing and setting up permissions of your key files.
15+16+The `source` of your key can be a literal string (unencrypted), a path
17+(unencrypted), or a command that wire runs to evaluate the key. Programs that
18+work well with wire keys include:
19+20+- GPG
21+- [Age](https://github.com/FiloSottile/age)
22+- Anything that non-interactively decrypts to `stdout`.
23+24+### Prerequisites
25+26+wire uses a Rust binary to receive encrypted key data, so your deploying
27+user must be trusted or you must add garnix as a trusted public key:
28+29+```nix
30+{ config, ... }:
31+{
32+ nix.settings.trusted-users = [
33+ config.deployment.target.user # [!code ++]
34+ ];
35+}
36+```
37+38+Otherwise, you may see errors such as:
39+40+```
41+error: cannot add path '/nix/store/...-wire-tool-key_agent-x86_64-linux-...' because it lacks a signature by a trusted key
42+```
43+44+This is a requirement because `nix copy` is used to copy the binary.
45+As a benefit to this approach, key deployments are significantly faster!
46+47+### A Trivial "Key"
48+49+```nix:line-numbers [hive.nix]
50+let
51+ sources = import ./npins;
52+ wire = import sources.wire;
53+in wire.makeHive {
54+ meta.nixpkgs = import sources.nixpkgs { };
55+56+ node-1 = {
57+ deployment.key."file.txt" = {
58+ source = ''
59+ Hello World!
60+ '';
61+ };
62+ };
63+}
64+```
65+66+```sh
67+[user@node-1]$ cat /run/keys/file.txt
68+Hello World!
69+```
70+71+### Encrypting with GPG
72+73+```nix:line-numbers [hive.nix]
74+let
75+ sources = import ./npins;
76+ wire = import sources.wire;
77+in wire.makeHive {
78+ meta.nixpkgs = import sources.nixpkgs { };
79+80+ node-1 = {
81+ deployment.key."file.txt" = {
82+ source = [
83+ "gpg"
84+ "--decrypt"
85+ "${./secrets/file.txt.gpg}"
86+ ];
87+ };
88+ };
89+}
90+```
91+92+```sh
93+[user@node-1]$ cat /run/keys/file.txt
94+Hello World!
95+```
96+97+### Encrypting with KeepassXC
98+99+A simple example of extracting a KeepassXC attachment into a wire key.
100+You must pass the password through stdin as the command must be non-interactive.
101+Note that the `--stdout` is important as wire expects the command to output the key to stdout.
102+103+```nix:line-numbers [hive.nix]
104+let
105+ sources = import ./npins;
106+ wire = import sources.wire;
107+in wire.makeHive {
108+ meta.nixpkgs = import sources.nixpkgs { };
109+110+ node-1 = {
111+ deployment.key."file.txt" = {
112+ source = [
113+ "bash"
114+ "-c"
115+ ''cat ~/pass | keepassxc-cli attachment-export --stdout ~/.local/share/keepass/database.kdbx test 'file.txt'''
116+ ];
117+ };
118+ };
119+}
120+```
121+122+```sh
123+[user@node-1]$ cat /run/keys/file.txt
124+Hello World!
125+```
126+127+### A Plain Text File
128+129+```nix:line-numbers [hive.nix]
130+let
131+ sources = import ./npins;
132+ wire = import sources.wire;
133+in wire.makeHive {
134+ meta.nixpkgs = import sources.nixpkgs { };
135+136+ node-1 = {
137+ deployment.key."file.txt" = {
138+ # using this syntax will enter the file into the store, readable by
139+ # anyone!
140+ source = ./file.txt;
141+ };
142+ };
143+}
144+```
145+146+## Persistence
147+148+wire defaults `destDir` to `/run/keys`. `/run/` is held in memory and will not
149+persist past reboot. Change
150+[`deployment.key.<name>.destDir`](/reference/module#deployment-keys-name-destdir)
151+to something like `/etc/keys` if you need secrets every time the machine boots.
152+153+## Upload Order
154+155+By default wire will upload keys before the system is activated. You can
156+force wire to upload the key after the system is activated by setting
157+[`deployment.keys.<name>.uploadAt`](/reference/module#deployment-keys-name-uploadat)
158+to `post-activation`.
159+160+## Permissions and Ownership
161+162+wire secrets are owned by user & group `root` (`0600`). You can change these
163+with the `user` and `group` option.
164+165+```nix:line-numbers [hive.nix]
166+let
167+ sources = import ./npins;
168+ wire = import sources.wire;
169+in wire.makeHive {
170+ meta.nixpkgs = import sources.nixpkgs { };
171+172+ node-1 = {
173+ deployment.key."file.txt" = {
174+ source = [
175+ "gpg"
176+ "--decrypt"
177+ "${./secrets/file.txt.gpg}"
178+ ];
179+180+ user = "my-user";
181+ group = "my-group";
182+ };
183+ };
184+}
185+```
186+187+## Further Examples
188+189+### Using Keys With Services
190+191+You can access the full absolute path of any key with
192+`config.deployment.keys.<name>.path` (auto-generated and read-only).
193+194+Keys also have a `config.deployment.keys.<name>.service` property
195+(auto-generated and read-only), which represent systemd services that you can
196+`require`, telling systemd there is a hard-dependency on that key for the
197+service to run.
198+199+Here's an example with the Tailscale service:
200+201+```nix:line-numbers [hive.nix]
202+let
203+ sources = import ./npins;
204+ wire = import sources.wire;
205+in wire.makeHive {
206+ meta.nixpkgs = import sources.nixpkgs { };
207+208+ node-1 = {config, ...}: {
209+ services.tailscale = {
210+ enable = true;
211+ # use deployment key path directly
212+ authKeyFile = config.deployment.keys."tailscale.key".path;
213+ };
214+215+ deployment.keys."tailscale.key" = {
216+ keyCommand = ["gpg" "--decrypt" "${./secrets/tailscale.key.gpg}"];
217+ };
218+219+ # The service will not start unless the key exists.
220+ systemd.services.tailscaled-autoconnect.requires = [
221+ config.deployment.keys."tailscale.key".service
222+ ];
223+ };
224+}
225+```
226+227+### Scoping a Key to a service account
228+229+Additionally you can scope the key to the user that the service runs under, to
230+further reduce duplication using the `config` argument. Here's an example of
231+providing a certificate that is only readable by the caddy service.
232+233+```nix:line-numbers [hive.nix]
234+let
235+ sources = import ./npins;
236+ wire = import sources.wire;
237+in wire.makeHive {
238+ meta.nixpkgs = import sources.nixpkgs { };
239+240+ some-web-server = {config, ...}: {
241+ deployment.keys."some.host.pem" = {
242+ keyCommand = ["gpg" "--decrypt" "${./some.host.pem.gpg}"];
243+ destDir = "/etc/keys";
244+245+ # inherit the user and group that caddy runs under
246+ # the key will only readable by the caddy service
247+ inherit (config.services.caddy) user group;
248+ };
249+250+ # ^^ repeat for `some.host.key`
251+252+ services.caddy = {
253+ virtualHosts."https://some.host".extraConfig = ''
254+ tls ${config.deployment.keys."some.host.pem".path} ${config.deployment.keys."some.host.key".path}
255+ '';
256+ };
257+ };
258+}
259+```
···1+---
2+comment: true
3+title: Migrate to wire
4+description: How-to migrate from other tools to wire tool.
5+---
6+7+# Migrate to wire
8+9+{{ $frontmatter.description }}
10+11+Migrate from...
12+13+- [Colmena](#from-colmena)
14+- [`nixos-rebuild`](#from-nixos-rebuild)
15+16+## From Colmena
17+18+If you're familiar with colmena, wire will hopefully come quickly to you! (or,
19+atleast that was the intention when writing it!). There are a few changes you
20+should know:
21+22+- [You don't have to use a root user](/guides/non-root-user.html)
23+- `apply-local` does not exist, `apply` will apply locally when appropriate
24+- [Many options have been aliased to nicer names](/reference/module.html)
25+ (ie, `deployment.targetUser` <=> `deployment.target.user`)
26+- You may pass a list of hosts to `deployment.targetHost` (no more fiddling with
27+ your hive whenever DNS is down, for example)
28+- `--path` optionally takes a flakeref! You can pass `--path github:foo/bar`,
29+ `--path git+file:///...`, `--path https://.../main.tar.gz`, etc.
30+ (plain paths like `--path ~/my-hive` still work as always)
31+32+::: tip
33+You should also follow [installation](/guides/installation) to install the
34+binary.
35+:::
36+37+### Convert a Hive as a Flake
38+39+```nix [flake.nix]
40+{
41+ inputs = {
42+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
43+ colmena.url = "github:zhaofengli/colmena"; # [!code --]
44+ wire.url = "github:forallsys/wire/stable"; # [!code ++]
45+ };
46+ outputs =
47+ { nixpkgs, colmena, ... }:
48+ {
49+ colmenaHive = colmena.lib.makeHive { # [!code --]
50+ wire = wire.lib.makeHive { # [!code ++]
51+ # ..
52+ };
53+ };
54+}
55+```
56+57+### Convert a Hive with npins
58+59+::: tip
60+You should also follow [installation](/guides/installation) to setup
61+npins and install the binary.
62+:::
63+64+Unlike colmena, you must call `makeHive` directly even in non-flake hives.
65+66+```nix [hive.nix]
67+let
68+ sources = import ./npins;
69+ wire = import sources.wire;
70+in
71+{ # [!code --]
72+wire.makeHive { # [!code ++]
73+74+ meta.nixpkgs = <nixpkgs>; # [!code --]
75+ meta.nixpkgs = import sources.nixpkgs { }; # [!code ++]
76+77+ # ...
78+}
79+```
80+81+Replacing `<nixpkgs>` with a pinned source is optional, but you should
82+probably use one if you ask me \:)
83+84+## From `nixos-rebuild`
85+86+You can keep using `nixos-rebuild` alongside wire!
87+88+Follow the instructions in [the relevant page](/guides/flakes/nixos-rebuild.html).
···1+---
2+comment: true
3+title: Use a non-root user
4+description: Deploy without root permissions with wire.
5+---
6+7+# Use a non-root user
8+9+{{ $frontmatter.description }}
10+11+## Deploying User Requirements
12+13+For deployment commands to succeed, the user defined in `deployment.target.user` must meet the following criteria:
14+15+1. Essential Config
16+17+- **Sudo Access**: The user must be `wheel` (A sudo user)
18+- **SSH Key Authentication**: The user must be authenticated through SSH keys,
19+ and password-based SSH auth is not supported.
20+21+ **Why?** Wire can prompt you for your `sudo` password, but not your `ssh` password.
22+23+2. Deploying with Secrets
24+25+- **Trusted User**: The user must be listed in the `trusted-users` nix config.
26+27+ If the user is not trusted, wire will fail in the key deployment stage.
28+29+For setting up a trusted user, see [Manage Secrets - Prerequisites](/guides/keys.html#prerequisites).
30+31+## Changing the user
32+33+By default, the target is set to root:
34+35+```nix
36+{
37+ deployment.target.user = "root";
38+}
39+```
40+41+But it can be any user you want so long as it fits the requirements above.
42+43+```nix
44+{
45+ deployment.target.user = "root"; # [!code --]
46+ deployment.target.user = "deploy-user"; # [!code ++]
47+}
48+```
49+50+After this change, wire will prompt you for sudo authentication, and tell you
51+the exact command wire wants privileged:
52+53+```sh{6}
54+$ wire apply keys --on media
55+ INFO eval_hive: evaluating hive Flake("/path/to/hive")
56+...
57+ INFO media | step="Upload key @ NoFilter" progress="3/4"
58+deploy-user@node:22 | Authenticate for "sudo /nix/store/.../bin/key_agent":
59+[sudo] password for deploy-user:
60+```
61+62+## Using alternative privilege escalation
63+64+You may change the privilege escalation command with the
65+[deployment.privilegeEscalationCommand](/reference/module.html#deployment-privilegeescalationcommand)
66+option.
67+68+For example, doas:
69+70+```nix
71+{
72+ deployment.privilegeEscalationCommand = [
73+ "sudo" # [!code --]
74+ "--" # [!code --]
75+ "doas" # [!code ++]
76+ ];
77+}
78+```
+32
doc/guides/parallelism.md
···00000000000000000000000000000000
···1+---
2+comment: true
3+title: Use Parallelism
4+description: How to use parallelism with wire Tool.
5+---
6+7+# Use Parallelism
8+9+{{ $frontmatter.description }}
10+11+## Controlling CPU Usage
12+13+wire evaluates, builds, pushes, and deploys each node completely independently
14+from each other. Internally wire calls this process a "node execution".
15+16+The default number of parallel _node executions_ is `10`, which can be
17+controlled with the `-p` / `--parallel` argument.
18+19+```sh
20+$ wire apply -p <NUMBER>
21+```
22+23+## Interaction with Nix's `max-jobs`
24+25+Nix has an overall derivation build limit and core limit.
26+If executing a node fills Nix's `max-jobs` all other nodes will bottleneck. You
27+should read [the relevant
28+documentation](https://nix.dev/manual/nix/2.28/advanced-topics/cores-vs-jobs) to fine tune these settings.
29+30+When a Node is built remotely due to
31+[`deployment.buildOnTarget`](/reference/module.html#deployment-buildontarget)
32+that node will not push up the _local machine's_ max-jobs limit.
···1+---
2+comment: true
3+title: Target Nodes
4+description: Tags, nodes, and how to target them with wire Tool.
5+---
6+7+# Target Nodes
8+9+{{ $frontmatter.description }}
10+11+## Targeting Specific Nodes
12+13+`wire apply --on` without an `@` prefix interprets as a literal node name. For
14+example:
15+16+```sh
17+$ wire apply switch --on node-a,node-b
18+```
19+20+Will switch-to-configuration on node a, and node b.
21+22+## Reading from Stdin
23+24+Passing `--on -` will read whitespace-separated nodes and tags from stdin. This
25+can be combined with normal `--on` usage.
26+27+For example:
28+29+```sh
30+$ echo "node-a node-b" | wire apply --on @other --on -
31+```
32+33+Will apply on `node-a`, `node-b`, and all nodes with the tag `@other`.
34+35+## Tag Basics
36+37+Nodes can have _tags_, which allows you to easily target multiple, related
38+nodes for deployment.
39+40+```nix:line-numbers{9,13,17,21} [hive.nix]
41+let
42+ sources = import ./npins;
43+ wire = import sources.wire;
44+in wire.makeHive {
45+ meta.nixpkgs = import sources.nixpkgs { };
46+47+ node-1 = {
48+ # ...
49+ deployment.tags = ["cloud"];
50+ };
51+ node-2 = {
52+ # ...
53+ deployment.tags = ["cloud", "virtual"];
54+ };
55+ node-3 = {
56+ # ...
57+ deployment.tags = ["on-prem"];
58+ };
59+ node-4 = {
60+ # ...
61+ deployment.tags = ["virtual"];
62+ };
63+ node-5 = {
64+ # Untagged
65+ };
66+}
67+```
68+69+To target all nodes with a specific tag, prefix tags with an `@`.
70+For example, to deploy only nodes with the `cloud` tag, use
71+72+```sh
73+$ wire apply --on @cloud
74+```
75+76+## Further Examples
77+78+::: info
79+80+Other operations such as an `--ignore` argument are unimplemented as of wire `v0.2.0`.
81+82+:::
83+84+### Mixing Tags with Node Names
85+86+You can mix tags and node names with `--on`:
87+88+```sh
89+$ wire apply --on @cloud --on node-5
90+```
91+92+This will deploy all nodes in `@cloud`, alongside the node `node-5`.
93+94+### Targeting Many Tags (Union)
95+96+You can specify many tags together:
97+98+```sh
99+$ wire apply --on @cloud @on-prem
100+```
101+102+This is a union between `@cloud` and `@on-prem`.
···1+---
2+comment: true
3+title: Write a Hive
4+---
5+6+# Write a Hive
7+8+## Anatomy of a Hive
9+10+A "Hive" is the attribute set that you pass to `wire.makeHive`. It has the
11+following layout:
12+13+```nix
14+wire.makeHive {
15+ # `meta`
16+ # type: attrset
17+ meta = {
18+ # `meta.nixpkgs` tells wire how to get nixpkgs.
19+ # type: "A path or an instance of nixpkgs."
20+ nixpkgs = <nixpkgs>;
21+22+ # `meta.specialArgs` are specialArgs to pass to each node & default
23+ # type: attrset
24+ specialArgs = { };
25+26+ # `meta.nodeSpecialArgs` lets you override `meta.specialArgs` per-node.
27+ # type: attrset of attrset
28+ nodeSpecialArgs: = { };
29+30+ # `meta.nodeNixpkgs` lets you override nixpkgs per-node.
31+ # type: attrset of "A path or an instance of nixpkgs."
32+ nodeNixpkgs: = { };
33+ };
34+35+ # `defaults` is a module applied to every node
36+ # type: NixOS Module
37+ defaults = { ... }: { };
38+39+ # Any other attributes are nodes.
40+ <node-name> = { ... }: { };
41+}
42+```
43+44+### `<node-name>`
45+46+Other attributes are NixOs modules that describe a system. They automatically
47+have `defaults` and the wire NixOS module imported.
48+49+They also have the `name` and `nodes` attributes passed to them, `name` being a string of the nodes name, and `nodes` being an attribute set of every node in the hive.
50+51+### `meta`
52+53+There is more detailed information about `meta` in [the
54+reference](/reference/meta.html).
55+56+### `defaults`
57+58+De-duplicate options with default node configuration.
59+60+At the top level of a hive wire reserves the `defaults` attribute. It's applied
61+to every node.
62+63+## Example
64+65+There is more detailed information the special options for nodes [the
66+reference](/reference/module.html).
67+68+```nix:line-numbers [hive.nix]
69+{
70+ meta.nixpkgs = import some-sources-or-inputs.nixpkgs { };
71+72+ defaults = {
73+ # name of the node that defaults is being applied to
74+ name,
75+ # attribute set of all nodes
76+ nodes,
77+ pkgs,
78+ ...
79+ }: {
80+ import = [
81+ ./default-module.nix
82+83+ # module that is imported for all nodes
84+ some-flake.nixosModules.default
85+ ];
86+87+ # all nodes should include vim!
88+ environment.systemPackages [ pkgs.vim ];
89+ };
90+91+ node-a = {
92+ # name of the node that defaults is being applied to
93+ name,
94+ # attribute set of all nodes
95+ nodes,
96+ pkgs,
97+ ...
98+ }: {
99+ imports = [
100+ # import the hardware-config and all your extra stuff
101+ ./node-a
102+ ];
103+104+ deployment = {
105+ target.host = "192.0.2.1";
106+ tags = [ "x86" ];
107+ };
108+ };
109+110+ # as many nodes as you'd like...
111+112+ node-g = {
113+ # some more config
114+ };
115+}
116+```
+19-11
doc/index.md
···5hero:
6 name: wire
7 text: a tool to deploy nixos systems
8- # tagline: My great project tagline
9 actions:
10 - theme: brand
11- text: Read Guide
12- link: /guide/wire
00013 - theme: alt
14- text: Reference
15- link: /reference/cli
1617features:
18- - title: Parallelism
19- details: Build and deploy many nodes at once
20- - title: Secret management
21- details: Fast & Unopinionated secret management
22- - title: Node Tagging & CI Friendly
23- details: Pipe data through jq
00000024---
···5hero:
6 name: wire
7 text: a tool to deploy nixos systems
08 actions:
9 - theme: brand
10+ text: Read Tutorial
11+ link: /tutorial/overview
12+ - theme: alt
13+ text: How-to Guides
14+ link: /guides/installation
15 - theme: alt
16+ text: Sources
17+ link: https://github.com/forallsys/wire.git
1819features:
20+ - title: Deploy in Parallel
21+ details: Build and deploy many nodes at once.
22+ link: /guides/parallelism
23+ icon: ๐ฝ
24+ - title: Manage Secrets
25+ details: Fast & Unopinionated secret management. Bring your own GPG, Age, or any other encryption tool.
26+ link: /guides/keys
27+ icon: ๐
28+ - title: Deploy as Any User
29+ details: Non-root deployments and interactive authentication is fully supported.
30+ link: /guides/non-root-user
31+ icon: ๐งโ๐ป
32---
···1+---
2+comment: true
3+title: Error Codes
4+description: Most error codes and their associated documentation.
5+---
6+7+# Error Codes
8+9+{{ $frontmatter.description }}
+58-4
doc/reference/meta.md
···1---
2comment: true
3title: Meta Options
4-description: Wire hive meta options.
5---
67-# {{ $frontmatter.title }}
89{{ $frontmatter.description }}
10···1415_Type:_ A path or an instance of `nixpkgs`.
1617-_Default:_ `inputs.nixpkgs.outPath`
1819_Examples:_
20···4041::: tip
4243-Wire always passes `name` (name of the node)
44and `nodes` (attribute set of all nodes) as args, even if `meta.specialArgs =
45{ }`.
46···60 };
61}
62```
000000000000000000000000000000000000000000000000000000
···1---
2comment: true
3title: Meta Options
4+description: wire hive meta options.
5---
67+# Meta Options
89{{ $frontmatter.description }}
10···1415_Type:_ A path or an instance of `nixpkgs`.
1617+_Default:_ `null`
1819_Examples:_
20···4041::: tip
4243+wire always passes `name` (name of the node)
44and `nodes` (attribute set of all nodes) as args, even if `meta.specialArgs =
45{ }`.
46···60 };
61}
62```
63+64+## meta.nodeSpecialArgs
65+66+Extra `specialArgs` to override `meta.specialArgs` for each node
67+68+_Type:_ attribute set of attribute set
69+70+_Default:_ `{ }`
71+72+_Example:_
73+74+```nix
75+{
76+ meta.nodeSpecialArgs = {
77+ extra-property = "some-value";
78+ };
79+}
80+```
81+82+## meta.nodeNixpkgs
83+84+Per-node nixpkgs to override `meta.nixpkgs`.
85+86+See `meta.nixpkgs` examples for possible values.
87+88+_Type:_ attribute set of path or an instance of `nixpkgs`
89+90+_Default:_ `{ }`
91+92+_Example:_
93+94+```nix
95+{
96+ meta = {
97+ nixpkgs = import <nixpkgs> { };
98+99+ nodeNixpkgs = {
100+ node-b = import <special-nixpkgs> { };
101+ };
102+ };
103+104+ node-a =
105+ { pkgs, ... }:
106+ {
107+ # uses <nixpkgs> (meta.nixpkgs)
108+ };
109+110+ node-b =
111+ { pkgs, ... }:
112+ {
113+ # uses <special-nixpkgs> (meta.nodeNixpkgs.node-b)
114+ };
115+}
116+```
···1+---
2+comment: false
3+title: wire Tutorial Overview
4+description: In this tutorial we will create and deploy a wire Hive.
5+---
6+7+# wire Tutorial Overview
8+9+wire is a tool to deploy NixOS systems. Its usage is inspired by [colmena](https://colmena.cli.rs/). In many places it's configuration attempts to remain a superset[^1] of colmena, however it is **not** a fork.
10+11+[^1]: A lot of your colmena module options will continue to work with wire, but wire has additional ergonomic changes you can take advantage of.
12+13+---
14+15+In this tutorial we will create and deploy a wire Hive. Along the way we will
16+encounter [npins](https://github.com/andir/npins), simple NixOS
17+configurations, virtual machines, and deployment keys.
18+19+You'll need at least 10~ GB of free disk space to complete this tutorial.
20+21+<div class="tip custom-block" style="padding-top: 8px">
22+23+Ready? Skip to [Nix Setup](./part-one/nix-setup).
24+25+</div>
26+27+## What features does wire have?
28+29+| Features | wire | Colmena |
30+| ------------------------------------------------------------- | ------------------ | ------------------ |
31+| [Node Tagging](/guides/targeting.html#tag-basics) | :white_check_mark: | :white_check_mark: |
32+| [Secret Management](/guides/keys.html) | :white_check_mark: | :white_check_mark: |
33+| [Parallel Deployment](/guides/parallelism.html) | :white_check_mark: | :white_check_mark: |
34+| Remote Builds | :white_check_mark: | :white_check_mark: |
35+| [Key Services](/guides/keys.html#using-keys-with-services) | :white_check_mark: | :white_check_mark: |
36+| [Pipeline Support](/guides/targeting.html#reading-from-stdin) | :white_check_mark: | :x:[^2] |
37+| [Non-Root Deployments](/guides/non-root-user) | :white_check_mark: | :x:[^3] |
38+| `--path` accepts flakerefs | :white_check_mark: | :x: |
39+| REPL & Eval expressions | :x: | :white_check_mark: |
40+| Adhoc remote command execution[^4] | :x: | :white_check_mark: |
41+42+[^2]: You need to write custom nix code to use Colmena hive metadata inside environments like CI pipelines, bash scripting, etc., which requires a knowledge of its internals. Recently it agained the [eval feature](https://colmena.cli.rs/unstable/features/eval.html) which has improved the situation since wire was first started.
43+44+[^3]: See https://github.com/zhaofengli/colmena/issues/120
45+46+[^4]: wire lacks an equivalent to `colmena exec`.
···1+---
2+comment: true
3+title: Basic Hive & Deployment
4+description: Creating a basic hive and deploying changes to the virtual machine.
5+---
6+7+# Basic Hive & Deployment
8+9+{{ $frontmatter.description }}
10+11+## Editing `hive.nix`
12+13+Open a text editor and edit `hive.nix`. You should copy this example, which imports
14+the npins sources we added. It also calls `makeHive`, and gives wire `nixpkgs`
15+from npins as well.
16+17+```nix:line-numbers [hive.nix]
18+let
19+ # import npins sources
20+ sources = import ./npins;
21+ # import `wire` from npins sources
22+ wire = import sources.wire;
23+in
24+wire.makeHive {
25+ # give wire nixpkgs from npins
26+ meta.nixpkgs = import sources.nixpkgs { };
27+28+ # we'll edit this part
29+}
30+```
31+32+Lets check out what wire sees with `wire show`.
33+34+```sh
35+[nix-shell]$ wire show
36+ INFO eval_hive: evaluating hive HiveNix("/home/marsh/scratch/wire-tutorial/hive.nix")
37+ WARN use --json to output something scripting suitable
38+Summary: 0 total node(s), totalling 0 keys (0 distinct).
39+Note: Listed connections are tried from Left to Right
40+41+```
42+43+The line `nodes: {}` means there is no "nodes" in our hive.
44+45+## Adding The First Node
46+47+Lets add the virtual machine as a node to the hive with the name
48+`virtual-machine`. Additionally, we will add `deployment.target`, recalling we
49+forwarded sshd `virtual-machine:22` to the port `localhost:2222`:
50+51+```nix:line-numbers [hive.nix]
52+let
53+ sources = import ./npins;
54+ wire = import sources.wire;
55+in
56+wire.makeHive {
57+ meta.nixpkgs = import sources.nixpkgs { };
58+59+ virtual-machine = { pkgs, ... }: { # [!code ++]
60+ deployment.target = { # [!code ++]
61+ port = 2222; # [!code ++]
62+ hosts = [ "localhost" ]; # [!code ++]
63+ }; # [!code ++]
64+65+ nixpkgs.hostPlatform = "x86_64-linux"; # [!code ++]
66+ }; # [!code ++]
67+}
68+```
69+70+## A naive `wire apply`
71+72+If we tried to run `wire apply` on our hive at this stage, it likely won't work.
73+If you've used NixOS before, you'll notice that many important options are
74+missing. But let's try anyway:
75+76+```sh
77+[nix-shell]$ wire apply
78+ERROR apply{goal=Switch on=}:goal{node=virtual-machine}: lib::hive::node: Failed to execute `Evaluate the node`
79+Error: ร 1 node(s) failed to apply.
80+81+Error:
82+ ร node virtual-machine failed to apply
83+ โโโถ wire::Evaluate
84+ โ
85+ โ ร failed to evaluate `--file /home/marsh/scratch/wire-tutorial/hive.nix topLevels.virtual-machine` from the context
86+ โ โ of a hive.
87+ โ
88+ โฐโโถ nix --extra-experimental-features nix-command --extra-experimental-features flakes eval --json --file /home/marsh/scratch/
89+ wire-tutorial/hive.nix topLevels.virtual-machine --log-format internal-json failed (reason: known-status) with code 1 (last 20
90+ lines):
91+ error:
92+ โฆ while evaluating '(evaluateNode node).config.system.build.toplevel' to select 'drvPath' on it
93+ at /nix/store/5pfz0v479gnciac17rcqi2gwyz8pl4s0-source/runtime/evaluate.nix:65:23:
94+ 64|
95+ 65| getTopLevel = node: (evaluateNode node).config.system.build.toplevel.drvPath;
96+ | ^
97+ 66| in
98+99+ โฆ while calling the 'head' builtin
100+ at /nix/store/n3d1ricw0cb5jd8vvfym6ig0mw7x7sv9-source/lib/attrsets.nix:1701:13:
101+ 1700| if length values == 1 || pred here (elemAt values 1) (head values) then
102+ 1701| head values
103+ | ^
104+ 1702| else
105+106+ (stack trace truncated; use '--show-trace' to show the full trace)
107+108+ error:
109+ Failed assertions:
110+ - The โfileSystemsโ option does not specify your root file system.
111+ - You must set the option โboot.loader.grub.devicesโ or 'boot.loader.grub.mirroredBoots' to make the system bootable.
112+ trace: evaluation warning: system.stateVersion is not set, defaulting to 25.11. Read why this matters on https://nixos.org/
113+ manual/nixos/stable/options.html#opt-system.stateVersion.
114+115+```
116+117+The command complained about not defining any fileSystems or a boot loader.
118+The `${sources.nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix` imported in
119+`vm.nix` does
120+extra work to make our virtual machine work, which we are currently missing.
121+122+## Importing `vm.nix`
123+124+Lets import our `vm.nix` to this hive to fix our evaluation errors.
125+Additionally, add a new package such as `vim` to our configuration:
126+127+```nix:line-numbers [hive.nix]
128+let
129+ sources = import ./npins;
130+ wire = import sources.wire;
131+in
132+wire.makeHive {
133+ meta.nixpkgs = import sources.nixpkgs { };
134+135+ virtual-machine = { pkgs, ... }: {
136+ deployment.target = {
137+ port = 2222;
138+ hosts = [ "localhost" ];
139+ };
140+141+ imports = [ # [!code ++]
142+ ./vm.nix # [!code ++]
143+ ]; # [!code ++]
144+145+ environment.systemPackages = [ pkgs.vim ]; # [!code ++]
146+147+ nixpkgs.hostPlatform = "x86_64-linux";
148+ };
149+}
150+```
151+152+## Our first deploy
153+154+Trying our basic `wire apply` again with these changes:
155+156+```sh
157+[nix-shell]$ wire apply
158+...
159+ INFO lib::nix_log: stopping the following units: boot.mount
160+ INFO lib::nix_log: NOT restarting the following changed units: systemd-fsck@dev-disk-by\x2dlabel-ESP.service
161+ INFO lib::nix_log: activating the configuration...
162+ INFO lib::nix_log: setting up /etc...
163+ INFO lib::nix_log: restarting systemd...
164+ INFO lib::nix_log: reloading user units for root...
165+ INFO lib::nix_log: restarting sysinit-reactivation.target
166+ INFO lib::nix_log: reloading the following units: dbus.service
167+ INFO lib::nix_log: the following new units were started: boot.automount, sysinit-reactivation.target, systemd-tmpfiles-resetup.service
168+ INFO apply{goal=Switch on=}:goal{node=virtual-machines}: lib::hive::node: Executing step `Upload key @ PostActivation`
169+ INFO apply{goal=Switch on=}: wire::apply: Successfully applied goal to 1 node(s): [Name("virtual-machines")]
170+```
171+172+Now, lets confirm these changes were applied to the virtual machine by executing
173+`vim` in the virtual machine window:
174+175+```sh [Virtual Machine]
176+[root@wire-tutorial:~]# vim --version
177+VIM - Vi IMproved 9.1 (2024 Jan 02, compiled Jan 01 1980 00:00:00)
178+```
179+180+Nice! You successfully deployed a new NixOS configuration to a **remote host**!
181+182+::: info
183+This followed common steps of adding the node's `deployment.target` details and
184+importing it's pre-existing NixOS configuration (in this case, `vm.nix`), a
185+pattern you'll be using a lot if you chose to adopt wire.
186+:::
187+188+In the next section, we'll cover how to deploy secrets / keys to our remote node.
+40
doc/tutorial/part-one/nix-setup.md
···0000000000000000000000000000000000000000
···1+---
2+comment: true
3+title: Nix Setup
4+description: Installing npins, nix, and enabling the binary cache.
5+---
6+7+# Nix Setup
8+9+{{ $frontmatter.description }}
10+11+::: warning
12+This page is for the purposes for the **Tutorial**.
13+You should read [How-to Guides - Install wire](/guides/installation.html) for installing wire for
14+regular use.
15+:::
16+17+## Nix Installation
18+19+You should install nix if you do not have it on your system already.
20+There are detailed steps to installing Nix on [nix.dev](https://nix.dev/install-nix).
21+22+By the end of the installation, you should see something like this:
23+24+```sh
25+$ nix --version
26+nix (Nix) 2.11.0
27+```
28+29+## Binary Cache
30+31+Because wire can be heavy to compile, it is distributed with a [binary
32+cache](https://wiki.nixos.org/wiki/Binary_Cache).
33+34+You must enable the [garnix binary cache](https://garnix.io/docs/caching) or you
35+will be compiling everything from source:
36+37+::: code-group
38+<<< @/snippets/tutorial/cache.conf [nix.conf]
39+<<< @/snippets/tutorial/cache.nix [configuration.nix]
40+:::
···1+---
2+comment: true
3+title: Preparing Repo & Shell
4+description: Adding npins sources and a nix development shell.
5+---
6+7+# Preparing Repo & Shell
8+9+{{ $frontmatter.description }}
10+11+## Initialising with Git & `npins`
12+13+First, lets create an adhoc shell to bring these two tools into our $PATH.
14+15+```sh
16+$ nix-shell -p git npins
17+[nix-shell]$ git --version
18+git version 2.51.0
19+[nix-shell]$ npins --version
20+npins 0.3.1
21+```
22+23+Great! Now lets use Git & `npins` to create a new Git repo and initialise it.
24+`npins init` may take a while to download `nixpkgs`.
25+26+```sh
27+[nix-shell]$ git init wire-tutorial
28+Initialized empty Git repository in /home/.../wire-tutorial/.git/
29+[nix-shell]$ cd wire-tutorial/
30+[nix-shell]$ npins init
31+[INFO ] Welcome to npins!
32+[INFO ] Creating `npins` directory
33+[INFO ] Writing default.nix
34+[INFO ] Writing initial lock file (empty)
35+[INFO ] Successfully written initial files to 'npins/sources.json'.
36+```
37+38+This has created a pinned version of `nixpkgs` for us to use in our wire hive.
39+40+## Adding wire as a dependency
41+42+We can now need to tell `npins` to use `forallsys/wire` as a dependency.
43+44+```sh
45+[nix-shell]$ npins add github forallsys wire --branch stable
46+[INFO ] Adding 'wire' โฆ
47+ repository: https://github.com/forallsys/wire.git
48+ pre_releases: false
49+ submodules: false
50+ version: v0.4.0
51+ revision: f33d80c15b17c85d557d533441609a59a2210941
52+ hash: 0wgah341hvjpvppkgwjrj50rvzf56ccmjz720xsl3mw38h9nn6sr
53+ frozen: false
54+```
55+56+Great, now lets confirm the two dependencies we have added to this `npins`
57+project:
58+59+```sh
60+[nix-shell]$ npins show
61+nixpkgs: (git repository)
62+ repository: https://github.com/pkpbynum/nixpkgs.git
63+ branch: pb/disk-size-bootloader
64+ submodules: false
65+ revision: da2060bdc1c9bc35acc4eafa265ba6b6c64f9926
66+ url: https://github.com/pkpbynum/nixpkgs/archive/da2060bdc1c9bc35acc4eafa265ba6b6c64f9926.tar.gz
67+ hash: 0j07gvnm7c5mzw1313asa8limzbmsbnsd02dcw22ing8fg3vbb7g
68+ frozen: false
69+70+wire: (git release tag)
71+ repository: https://github.com/forallsys/wire.git
72+ pre_releases: false
73+ submodules: false
74+ version: v0.4.0
75+ revision: f33d80c15b17c85d557d533441609a59a2210941
76+ hash: 0wgah341hvjpvppkgwjrj50rvzf56ccmjz720xsl3mw38h9nn6sr
77+ frozen: false
78+```
79+80+## Creating a `shell.nix`
81+82+Open a text editor to edit `shell.nix` in the `wire-tutorial` directory.
83+84+```nix:line-numbers [shell.nix]
85+let
86+ sources = import ./npins;
87+ pkgs = import sources.nixpkgs { };
88+ wire = import sources.wire;
89+in
90+pkgs.mkShell {
91+ packages = [
92+ wire.packages.x86_64-linux.wire-small
93+ pkgs.npins
94+ pkgs.git
95+ ];
96+97+ shellHook = ''
98+ export NIX_PATH="nixpkgs=${sources.nixpkgs.outPath}"
99+ '';
100+}
101+```
102+103+You should now `exit` to quit the old shell, and
104+enter a new shell with `nix-shell`. Since we added wire as a package, our new
105+shell should have wire in the $PATH:
106+107+```sh
108+[nix-shell]$ exit
109+exit
110+$ cd wire-tutorial/
111+$ nix-shell
112+[nix-shell]$ wire --version
113+wire 0.5.0
114+Debug: Hive::SCHEMA_VERSION 0
115+116+```
···1+---
2+comment: true
3+title: Creating a Virtual Machine
4+description: Creating a NixOS virtual machine to use as a deployment target.
5+---
6+7+# Creating a Virtual Machine
8+9+{{ $frontmatter.description }}
10+11+## Creating a `vm.nix`
12+13+For this step, you'll need your ssh public key, which you can obtain from
14+`ssh-add -L`.
15+16+Open a text editor and edit `vm.nix`. Place in it this basic NixOS
17+virtual machine configuration, which enables openssh and forwards it's 22 port:
18+19+```nix:line-numbers [vm.nix]
20+let
21+ sources = import ./npins;
22+in
23+{
24+ imports = [ "${sources.nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix" ];
25+26+ networking.hostName = "wire-tutorial";
27+28+ users.users.root = {
29+ initialPassword = "root";
30+ openssh.authorizedKeys.keys = [
31+ # I made this a nix syntax error so you're forced to deal with it!
32+ <your ssh public-key as a string>
33+ ];
34+ };
35+36+ boot = {
37+ loader = {
38+ systemd-boot.enable = true;
39+ efi.canTouchEfiVariables = true;
40+ };
41+42+ kernelParams = [ "console=ttyS0" ];
43+44+ boot.growPartition = true;
45+ };
46+47+ # enable openssh
48+ services = {
49+ openssh = {
50+ enable = true;
51+ settings.PermitRootLogin = "yes";
52+ };
53+54+ getty.autologinUser = "root";
55+ };
56+57+ virtualisation = {
58+ graphics = false;
59+ useBootLoader = true;
60+61+ # use a 5gb disk
62+ diskSize = 5 * 1024;
63+64+ # grow the filesystem to fit the 5 gb we reserved
65+ fileSystems."/".autoResize = true;
66+67+ # forward `openssh` port 22 to localhost:2222.
68+ forwardPorts = [
69+ {
70+ from = "host";
71+ host.port = 2222;
72+ guest.port = 22;
73+ }
74+ ];
75+ };
76+77+ system.stateVersion = "23.11";
78+}
79+```
80+81+If you like, you may take a moment to understand each line of this
82+configuration.
83+84+## Building & Running the virtual machine
85+86+Open a separate Terminal tab/window/instance, ensuring you enter the development
87+shell with `nix-shell`.
88+Then, build the virtual machine with a bootloader,
89+taking our `vm.nix` as the nixos configuration.
90+91+```sh
92+$ nix-shell
93+[nix-shell]$ nix-build '<nixpkgs/nixos>' -A vmWithBootLoader -I nixos-config=./vm.nix
94+```
95+96+::: tip HELP
97+98+If you got an error such as
99+100+```
101+error: The option `...' in `...' is already declared in `...'.
102+```
103+104+make sure you ran the above command in the `nix-shell`!
105+106+:::
107+108+Building the virtual machine can take some time, but once it completes, start it
109+by running:
110+111+```sh
112+[nix-shell]$ ./result/bin/run-wire-tutorial-vm
113+```
114+115+You will see boot-up logs fly across the screen and eventually you will be placed
116+into shell inside the virtual machine.
117+118+```sh [Virtual Machine]
119+running activation script...
120+setting up /etc...
121+122+Welcome to NixOS 25.11 (Xantusia)!
123+124+[ OK ] Created slice Slice /system/getty.
125+[ OK ] Created slice Slice /system/modprobe.
126+...
127+<<< Welcome to NixOS 25.11pre861972.88cef159e47c (x86_64) - hvc0 >>>
128+129+Run 'nixos-help' for the NixOS manual.
130+131+wire-tutorial login: root (automatic login)
132+133+[root@wire-tutorial:~]#
134+135+```
136+137+::: details
138+Further details on how the above commands work can be found at
139+[nix.dev](https://nix.dev/tutorials/nixos/nixos-configuration-on-vm.html#creating-a-qemu-based-virtual-machine-from-a-nixos-configuration)
140+:::
141+142+## Summary
143+144+Congratulations, you created a virtual machine in your terminal.
145+We'll be deploying to this virtual machine, so keep the
146+terminal instance open.
147+148+::: info
149+From now on, commands ran inside the virtual machine will be lead with the
150+following prompt:
151+152+```sh [Virtual Machine]
153+[root@wire-tutorial:~]#
154+155+```
156+157+:::
158+159+::: tip
160+If you ever want to quit the virtual machine, run the command `poweroff`.
161+:::
···1+---
2+comment: true
3+title: Deployment Keys Basics
4+description: Deploy some basic secrets with wire tool.
5+---
6+7+# Deployment Keys Basics
8+9+{{ $frontmatter.description }}
10+11+## Creating a `secrets.nix`
12+13+Lets create a NixOS module that will contain our secret keys, and import it:
14+15+```nix:line-numbers [hive.nix]
16+let
17+ sources = import ./npins;
18+ wire = import sources.wire;
19+in
20+wire.makeHive {
21+ meta.nixpkgs = import sources.nixpkgs { };
22+23+ virtual-machine = {
24+ deployment.target = {
25+ port = 2222;
26+ hosts = [ "localhost" ];
27+ };
28+29+ imports = [
30+ ./vm.nix
31+ ./secrets.nix # [!code ++]
32+ ];
33+34+ environment.systemPackages = [ pkgs.vim ];
35+36+ nixpkgs.hostPlatform = "x86_64-linux";
37+ };
38+}
39+```
40+41+```nix:line-numbers [secrets.nix]
42+{
43+ deployment.keys = {
44+ # the key's unique name is `"basic.txt"`.
45+ "basic.txt" = {
46+ # In this key's case, the source is a literal string:
47+ source = ''
48+ Hello World
49+ '';
50+ };
51+ };
52+}
53+```
54+55+::: details
56+Further details on the `deployment.keys` options can be found
57+[in the reference](/reference/module.html#deployment-keys)
58+:::
59+60+Once we deploy this new configuration to the virtul machine,
61+`/run/keys/basic.txt` will be created with the contents of the key.
62+63+```sh
64+[nix-shell]$ wire apply keys
65+ WARN lib::nix_log: Store URL: ssh://root@localhost
66+(root@localhost) Password:
67+68+```
69+70+```sh [Virtual Machine]
71+[root@wire-tutorial:~]# cat /run/keys/basic.txt
72+Hello World
73+74+```
75+76+You successfully deployed your first, albeit not-so-secret, secret key! Let's
77+move on from literal-text keys and use something a bit more powerful.
78+79+## File-sourced keys <Badge type="info">Optional</Badge>
80+81+This section is optional to try, but you can also pass `deployment.keys.<name>.source`
82+a file path. It's contents is read and treated as literal text.
83+84+```sh
85+$ echo hello world > very-important-secret.txt
86+```
87+88+```nix:line-numbers [secrets.nix]
89+{
90+ deployment.keys = {
91+ # ...
92+93+ "very-important-secret.txt" = { # [!code ++]
94+ source = ./very-important-secret.txt; # [!code ++]
95+ }; # [!code ++]
96+ };
97+}
98+```
99+100+```sh [Virtual Machine]
101+[root@wire-tutorial:~]# cat /run/keys/very-important-secret.txt
102+hello world
103+104+```
105+106+## Command-sourced keys
107+108+Command-sourced keys are where the real power of wire keys lie. By passing a
109+list of strings, wire will execute them as a command and create a key out of it's `stdout`.
110+111+Because the command's output is never written to the nix store, these can be
112+considered real secrets.
113+114+To create a basic example, update your `secrets.nix` to include a secret that
115+echos "hello world":
116+117+```nix:line-numbers [secrets.nix]
118+{
119+ deployment.keys = {
120+ # ...
121+122+ "command.txt" = { # [!code ++]
123+ source = [ # [!code ++]
124+ "echo" # [!code ++]
125+ "hello world" # [!code ++]
126+ ]; # [!code ++]
127+ }; # [!code ++]
128+ };
129+}
130+```
131+132+After a quick `wire deploy secrets`, the `/run/keys/command.txt` file is
133+created:
134+135+```sh [Virtual Machine]
136+[root@wire-tutorial:~]# cat /run/keys/command.txt
137+hello world
138+139+```
140+141+Hopefully you can see the potential of command-sourced keys, as these are the
142+basic building block of how we achieve encrypted secrets with wire.
···1+---
2+comment: true
3+title: Deployment Keys Basics
4+description: Deploy a age-encrypted secret with wire tool.
5+---
6+7+# Deployment Keys Basics
8+9+{{ $frontmatter.description }}
10+11+::: tip
12+For this tutorial we will be using [`age`](https://github.com/FiloSottile/age),
13+but other encryption CLI tools work just as well such as GnuPG.
14+:::
15+16+## Installing age
17+18+Alter your shell.nix to include age:
19+20+```nix:line-numbers [shell.nix]
21+let
22+ sources = import ./npins;
23+ pkgs = import sources.nixpkgs { };
24+ wire = import sources.wire;
25+in
26+pkgs.mkShell {
27+ packages = [
28+ wire.packages.x86_64-linux.wire-small
29+ pkgs.npins
30+ pkgs.git
31+ pkgs.age # [!code ++]
32+ ];
33+34+ shellHook = ''
35+ export NIX_PATH="nixpkgs=${sources.nixpkgs.outPath}"
36+ '';
37+}
38+```
39+40+Quit and re-open your shell, and confirm age is now available:
41+42+```sh
43+[nix-shell]$ exit
44+exit
45+$ nix-shell
46+[nix-shell]$ age --version
47+1.2.1
48+49+```
50+51+## Encrypting a secret
52+53+First create an age private key:
54+55+```sh
56+[nix-shell]$ age-keygen -o key.txt
57+Public key: age1j08s3kmr8zw4w8k99vs4nut5mg03dm8nfuaajuekdyzlujxply5qwsv4g0
58+59+```
60+61+::: details
62+Further details on how age works can be found on in the
63+[age manual](https://man.archlinux.org/man/age.1.en.txt).
64+:::
65+66+Now, lets encrypt the words `"!! encrypted string !!"` with age and save it to the
67+file `top-secret.age`.
68+69+We will use a pipeline to echo the encrypted string into
70+age, and use `age-keygent -y` to give age the public key we generated, then we
71+use the redirection operator to save the encrypted data to `top-secret.age`.
72+73+```sh
74+[nix-shell]$ echo "encrypted string!" | age --encrypt --recipient $(age-keygen -y key.txt) > top-secret.age
75+```
76+77+## Adding an age-encrypted key
78+79+Now, lets combine our previous command-sourced key with `age`. Pass the
80+arguments `age --decrypt --identity key.txt ./top-secret.age` to wire:
81+82+```nix:line-numbers [secrets.nix]
83+{
84+ deployment.keys = {
85+ # ...
86+87+ "top-secret" = { # [!code ++]
88+ source = [ # [!code ++]
89+ "age" # [!code ++]
90+ "--decrypt" # [!code ++]
91+ "--identity" # [!code ++]
92+ "key.txt" # [!code ++]
93+ "${./top-secret.age}" # [!code ++]
94+ ]; # [!code ++]
95+ }; # [!code ++]
96+ };
97+}
98+```
99+100+One `wire apply keys` later, and you have successfully deployed an encrypted
101+key:
102+103+```sh [Virtual Machine]
104+[root@wire-tutorial:~]# cat /run/keys/top-secret
105+encrypted string!
106+107+```
···0001{ testName }:
2let
3 # Use the flake-compat code in project root to access the tests which are
···1+# SPDX-License-Identifier: AGPL-3.0-or-later
2+# Copyright 2024-2025 wire Contributors
3+4{ testName }:
5let
6 # Use the flake-compat code in project root to access the tests which are
+5-2
tests/nix/test-opts.nix
···0001{
2 lib,
3 snakeOil,
4- wire-small,
5 config,
6 pkgs,
7 ...
···33 "C+ /root/.ssh/id_ed25519 600 - - - ${snakeOil.snakeOilEd25519PrivateKey}"
34 ];
35 environment.systemPackages = [
36- wire-small
37 pkgs.ripgrep
38 ];
39 # It's important to note that you should never ever use this configuration
···1+# SPDX-License-Identifier: AGPL-3.0-or-later
2+# Copyright 2024-2025 wire Contributors
3+4{
5 lib,
6 snakeOil,
7+ wire-small-dev,
8 config,
9 pkgs,
10 ...
···36 "C+ /root/.ssh/id_ed25519 600 - - - ${snakeOil.snakeOilEd25519PrivateKey}"
37 ];
38 environment.systemPackages = [
39+ wire-small-dev
40 pkgs.ripgrep
41 ];
42 # It's important to note that you should never ever use this configuration