···7788## [Unreleased] - yyyy-mm-dd
991010+## [v1.1.1] - 2025-01-05
1111+1212+### Fixed
1313+1414+- Fix a bug where wire was attempting to SSH to the local machine when `buildOnTarget` &
1515+ `allowLocalDeployment` where true.
1616+1717+## [v1.1.0] - 2025-12-31
1818+1019### Added
11201212-- Added `--reboot`. Wire will wait for the node to reconnect after rebooting.
1313- Wire will refuse to reboot localhost. Keys post-activation will be applied
2121+- Add a `--substitute-on-destination` argument.
2222+- Add the `meta.nodeSpecialArgs` meta option.
2323+- Add `wire build`, a new command to build nodes offline.
2424+ It is distinct from `wire apply build`, as it will not ping
2525+ or push the result, making it useful for CI.
2626+2727+### Changed
2828+2929+- Build store paths will be output to stdout
3030+3131+### Fixed
3232+3333+- Fix invalidated caches not actually returning `None`.
3434+3535+## [v1.0.0] - 2025-12-17
3636+3737+### Added
3838+3939+- SIGINT signal handling.
4040+4141+### Changed
4242+4343+- Invalidate caches that reference garbage collected paths.
4444+4545+### Fixed
4646+4747+- Fix key filtering logic.
4848+4949+## [v1.0.0-beta.0] - 2025-12-02
5050+5151+### Added
5252+5353+- Implement `meta.nodeNixpkgs`.
5454+- Add caching of hive evaluation for flakes.
5555+5656+### Changed
5757+5858+- Run tests against 25.11.
5959+6060+## [v1.0.0-alpha.1] - 2025-11-24
6161+6262+### Added
6363+6464+- Add `--handle-unreachable`. You can use `--handle-unreachable ignore` to
6565+ ignore unreachable nodes in the status of the deployment.
6666+- Add a basic progress bar.
6767+6868+### Changed
6969+7070+- Revert "Wire will now attempt to use SSH ControlMaster by default.".
7171+- Change the `show` subcommand to look nicer now.
7272+- Change the `build` step to always build remotely when the node is
7373+ going to be applied locally.
7474+7575+## [v1.0.0-alpha.0] - 2025-10-22
7676+7777+### Added
7878+7979+- Add `--ssh-accept-host` argument.
8080+- Add `--on -` syntax to the `--on` argument.
8181+ Passing `-` will now read additional apply targets from stdin.
8282+- Add `{key.name}-key.{path,service}` systemd units.
8383+- Added `--flake` argument as an alias for `--path`.
8484+- A terminal bell will be output if a sudo / ssh prompt is ever printed.
8585+- Added a real tutorial, and separated many how-to guides.
8686+ The tutorial leads the user through creating and deploying a wire Hive.
8787+- Add `config.nixpkgs.flake.source` by default if `meta.nixpkgs` ends
8888+ with `-source` at priority 1000 (default).
8989+9090+### Fixed
9191+9292+- Fix bug where `--non-interactive` was inversed.
9393+- Fix a bug where `./result` links where being created.
9494+- Fix passing `sources.nixpkgs` directly from npins to `meta.nixpkgs`.
9595+- Fix nodes that will be applied locally running the `push` and `cleanup`
9696+ steps.
9797+9898+### Changed
9999+100100+- Improve logging from interactive commands (absence of `--non-interactive`).
101101+- Changed `--path` argument to support flakerefs (`github:foo/bar`,
102102+ `git+file:///...`, `https://.../main.tar.gz`, etc).
103103+- Changed SSH arguments to use ControlMaster by default.
104104+- Compile-out logs with level `tracing_level::TRACE` in release builds.
105105+- Improve aata integrity of keys.
106106+- Unknown SSH keys will be immediately rejected unless `--ssh-accept-host` is passed.
107107+- Changed evaluation to be ran in parallel with other steps until
108108+ the .drv is required.
109109+110110+## [0.5.0] - 2025-09-18
111111+112112+### Added
113113+114114+- Added `--reboot`. wire will wait for the node to reconnect after rebooting.
115115+ wire will refuse to reboot localhost. Keys post-activation will be applied
14116 after rebooting!
15117- Most errors now have error codes and documentation links.
16118- Added the global flag `--non-interactive`.
1717-- Wire now creates its own PTY to interface with openssh's PTY to allow for
119119+- wire now creates its own PTY to interface with openssh's PTY to allow for
18120 interactive sudo authentication on both remote and local targets.
1912120122 Using a wheel user as `deployment.target.user` is no longer necessary
···27129### Changed
2813029131- `wire inspect/show --json` will no longer use a pretty print.
3030-- Wire will now wait for the node to reconnect if activation failed (excluding
132132+- wire will now wait for the node to reconnect if activation failed (excluding
31133 dry-activate).
32134- Nix logs with the `Talkative` and `Chatty` level have been moved to
33135 `tracing_level::TRACE`.
···4314544146- Nodes may now fail without stopping the entire hive from continuing. A summary
45147 of errors will be presented at the end of the apply process.
4646-- Wire will now ping the node before it proceeds executing.
4747-- Wire will now properly respect `deployment.target.hosts`.
4848-- Wire will now attempt each target host in order until a valid one is found.
148148+- wire will now ping the node before it proceeds executing.
149149+- wire will now properly respect `deployment.target.hosts`.
150150+- wire will now attempt each target host in order until a valid one is found.
4915150152### Changed
511535252-- Wire now directly evaluates your hive instead of shipping extra nix code along with its binary.
154154+- wire now directly evaluates your hive instead of shipping extra nix code along with its binary.
53155 You must now use `outputs.makeHive { ... }` instead of a raw attribute.
54156 This can be obtained with npins or a flake input.
55157- The expected flake output name has changed from `outputs.colmena` to `outputs.wire`.
···63165### Changed
6416665167- Dependency Updates.
6666-- Wire now compiles and includes key agents for multiple architectures, currently only linux.
168168+- wire now compiles and includes key agents for multiple architectures, currently only linux.
67169- There is a new package output, `wire-small`, for testing purposes.
68170 It only compiles the key agent for the host that builds `wire-small`.
69171- `--no-progress` now defaults to true if stdin does not refer to a tty (unix pipelines, in CI).
7070-- Added an error for the internal hive evluation parse failure.
172172+- Added an error for the internal hive evaluation parse failure.
71173- The `inspect` command now has `show` as an alias.
72174- Remove `log` command as there are currently no plans to implement the feature
73175- The `completions` command is now hidden from the help page
7417675177### Fixed
761787777-- A non-existant key owner user/group would not default to gid/uid `0`.
179179+- A non-existent key owner user/group would not default to gid/uid `0`.
78180- Keys can now be deployed to localhost.
7918180182## [0.2.0] - 2025-04-21
+661
COPYING
···11+ GNU AFFERO GENERAL PUBLIC LICENSE
22+ Version 3, 19 November 2007
33+44+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
55+ Everyone is permitted to copy and distribute verbatim copies
66+ of this license document, but changing it is not allowed.
77+88+ Preamble
99+1010+ The GNU Affero General Public License is a free, copyleft license for
1111+software and other kinds of works, specifically designed to ensure
1212+cooperation with the community in the case of network server software.
1313+1414+ The licenses for most software and other practical works are designed
1515+to take away your freedom to share and change the works. By contrast,
1616+our General Public Licenses are intended to guarantee your freedom to
1717+share and change all versions of a program--to make sure it remains free
1818+software for all its users.
1919+2020+ When we speak of free software, we are referring to freedom, not
2121+price. Our General Public Licenses are designed to make sure that you
2222+have the freedom to distribute copies of free software (and charge for
2323+them if you wish), that you receive source code or can get it if you
2424+want it, that you can change the software or use pieces of it in new
2525+free programs, and that you know you can do these things.
2626+2727+ Developers that use our General Public Licenses protect your rights
2828+with two steps: (1) assert copyright on the software, and (2) offer
2929+you this License which gives you legal permission to copy, distribute
3030+and/or modify the software.
3131+3232+ A secondary benefit of defending all users' freedom is that
3333+improvements made in alternate versions of the program, if they
3434+receive widespread use, become available for other developers to
3535+incorporate. Many developers of free software are heartened and
3636+encouraged by the resulting cooperation. However, in the case of
3737+software used on network servers, this result may fail to come about.
3838+The GNU General Public License permits making a modified version and
3939+letting the public access it on a server without ever releasing its
4040+source code to the public.
4141+4242+ The GNU Affero General Public License is designed specifically to
4343+ensure that, in such cases, the modified source code becomes available
4444+to the community. It requires the operator of a network server to
4545+provide the source code of the modified version running there to the
4646+users of that server. Therefore, public use of a modified version, on
4747+a publicly accessible server, gives the public access to the source
4848+code of the modified version.
4949+5050+ An older license, called the Affero General Public License and
5151+published by Affero, was designed to accomplish similar goals. This is
5252+a different license, not a version of the Affero GPL, but Affero has
5353+released a new version of the Affero GPL which permits relicensing under
5454+this license.
5555+5656+ The precise terms and conditions for copying, distribution and
5757+modification follow.
5858+5959+ TERMS AND CONDITIONS
6060+6161+ 0. Definitions.
6262+6363+ "This License" refers to version 3 of the GNU Affero General Public License.
6464+6565+ "Copyright" also means copyright-like laws that apply to other kinds of
6666+works, such as semiconductor masks.
6767+6868+ "The Program" refers to any copyrightable work licensed under this
6969+License. Each licensee is addressed as "you". "Licensees" and
7070+"recipients" may be individuals or organizations.
7171+7272+ To "modify" a work means to copy from or adapt all or part of the work
7373+in a fashion requiring copyright permission, other than the making of an
7474+exact copy. The resulting work is called a "modified version" of the
7575+earlier work or a work "based on" the earlier work.
7676+7777+ A "covered work" means either the unmodified Program or a work based
7878+on the Program.
7979+8080+ To "propagate" a work means to do anything with it that, without
8181+permission, would make you directly or secondarily liable for
8282+infringement under applicable copyright law, except executing it on a
8383+computer or modifying a private copy. Propagation includes copying,
8484+distribution (with or without modification), making available to the
8585+public, and in some countries other activities as well.
8686+8787+ To "convey" a work means any kind of propagation that enables other
8888+parties to make or receive copies. Mere interaction with a user through
8989+a computer network, with no transfer of a copy, is not conveying.
9090+9191+ An interactive user interface displays "Appropriate Legal Notices"
9292+to the extent that it includes a convenient and prominently visible
9393+feature that (1) displays an appropriate copyright notice, and (2)
9494+tells the user that there is no warranty for the work (except to the
9595+extent that warranties are provided), that licensees may convey the
9696+work under this License, and how to view a copy of this License. If
9797+the interface presents a list of user commands or options, such as a
9898+menu, a prominent item in the list meets this criterion.
9999+100100+ 1. Source Code.
101101+102102+ The "source code" for a work means the preferred form of the work
103103+for making modifications to it. "Object code" means any non-source
104104+form of a work.
105105+106106+ A "Standard Interface" means an interface that either is an official
107107+standard defined by a recognized standards body, or, in the case of
108108+interfaces specified for a particular programming language, one that
109109+is widely used among developers working in that language.
110110+111111+ The "System Libraries" of an executable work include anything, other
112112+than the work as a whole, that (a) is included in the normal form of
113113+packaging a Major Component, but which is not part of that Major
114114+Component, and (b) serves only to enable use of the work with that
115115+Major Component, or to implement a Standard Interface for which an
116116+implementation is available to the public in source code form. A
117117+"Major Component", in this context, means a major essential component
118118+(kernel, window system, and so on) of the specific operating system
119119+(if any) on which the executable work runs, or a compiler used to
120120+produce the work, or an object code interpreter used to run it.
121121+122122+ The "Corresponding Source" for a work in object code form means all
123123+the source code needed to generate, install, and (for an executable
124124+work) run the object code and to modify the work, including scripts to
125125+control those activities. However, it does not include the work's
126126+System Libraries, or general-purpose tools or generally available free
127127+programs which are used unmodified in performing those activities but
128128+which are not part of the work. For example, Corresponding Source
129129+includes interface definition files associated with source files for
130130+the work, and the source code for shared libraries and dynamically
131131+linked subprograms that the work is specifically designed to require,
132132+such as by intimate data communication or control flow between those
133133+subprograms and other parts of the work.
134134+135135+ The Corresponding Source need not include anything that users
136136+can regenerate automatically from other parts of the Corresponding
137137+Source.
138138+139139+ The Corresponding Source for a work in source code form is that
140140+same work.
141141+142142+ 2. Basic Permissions.
143143+144144+ All rights granted under this License are granted for the term of
145145+copyright on the Program, and are irrevocable provided the stated
146146+conditions are met. This License explicitly affirms your unlimited
147147+permission to run the unmodified Program. The output from running a
148148+covered work is covered by this License only if the output, given its
149149+content, constitutes a covered work. This License acknowledges your
150150+rights of fair use or other equivalent, as provided by copyright law.
151151+152152+ You may make, run and propagate covered works that you do not
153153+convey, without conditions so long as your license otherwise remains
154154+in force. You may convey covered works to others for the sole purpose
155155+of having them make modifications exclusively for you, or provide you
156156+with facilities for running those works, provided that you comply with
157157+the terms of this License in conveying all material for which you do
158158+not control copyright. Those thus making or running the covered works
159159+for you must do so exclusively on your behalf, under your direction
160160+and control, on terms that prohibit them from making any copies of
161161+your copyrighted material outside their relationship with you.
162162+163163+ Conveying under any other circumstances is permitted solely under
164164+the conditions stated below. Sublicensing is not allowed; section 10
165165+makes it unnecessary.
166166+167167+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168168+169169+ No covered work shall be deemed part of an effective technological
170170+measure under any applicable law fulfilling obligations under article
171171+11 of the WIPO copyright treaty adopted on 20 December 1996, or
172172+similar laws prohibiting or restricting circumvention of such
173173+measures.
174174+175175+ When you convey a covered work, you waive any legal power to forbid
176176+circumvention of technological measures to the extent such circumvention
177177+is effected by exercising rights under this License with respect to
178178+the covered work, and you disclaim any intention to limit operation or
179179+modification of the work as a means of enforcing, against the work's
180180+users, your or third parties' legal rights to forbid circumvention of
181181+technological measures.
182182+183183+ 4. Conveying Verbatim Copies.
184184+185185+ You may convey verbatim copies of the Program's source code as you
186186+receive it, in any medium, provided that you conspicuously and
187187+appropriately publish on each copy an appropriate copyright notice;
188188+keep intact all notices stating that this License and any
189189+non-permissive terms added in accord with section 7 apply to the code;
190190+keep intact all notices of the absence of any warranty; and give all
191191+recipients a copy of this License along with the Program.
192192+193193+ You may charge any price or no price for each copy that you convey,
194194+and you may offer support or warranty protection for a fee.
195195+196196+ 5. Conveying Modified Source Versions.
197197+198198+ You may convey a work based on the Program, or the modifications to
199199+produce it from the Program, in the form of source code under the
200200+terms of section 4, provided that you also meet all of these conditions:
201201+202202+ a) The work must carry prominent notices stating that you modified
203203+ it, and giving a relevant date.
204204+205205+ b) The work must carry prominent notices stating that it is
206206+ released under this License and any conditions added under section
207207+ 7. This requirement modifies the requirement in section 4 to
208208+ "keep intact all notices".
209209+210210+ c) You must license the entire work, as a whole, under this
211211+ License to anyone who comes into possession of a copy. This
212212+ License will therefore apply, along with any applicable section 7
213213+ additional terms, to the whole of the work, and all its parts,
214214+ regardless of how they are packaged. This License gives no
215215+ permission to license the work in any other way, but it does not
216216+ invalidate such permission if you have separately received it.
217217+218218+ d) If the work has interactive user interfaces, each must display
219219+ Appropriate Legal Notices; however, if the Program has interactive
220220+ interfaces that do not display Appropriate Legal Notices, your
221221+ work need not make them do so.
222222+223223+ A compilation of a covered work with other separate and independent
224224+works, which are not by their nature extensions of the covered work,
225225+and which are not combined with it such as to form a larger program,
226226+in or on a volume of a storage or distribution medium, is called an
227227+"aggregate" if the compilation and its resulting copyright are not
228228+used to limit the access or legal rights of the compilation's users
229229+beyond what the individual works permit. Inclusion of a covered work
230230+in an aggregate does not cause this License to apply to the other
231231+parts of the aggregate.
232232+233233+ 6. Conveying Non-Source Forms.
234234+235235+ You may convey a covered work in object code form under the terms
236236+of sections 4 and 5, provided that you also convey the
237237+machine-readable Corresponding Source under the terms of this License,
238238+in one of these ways:
239239+240240+ a) Convey the object code in, or embodied in, a physical product
241241+ (including a physical distribution medium), accompanied by the
242242+ Corresponding Source fixed on a durable physical medium
243243+ customarily used for software interchange.
244244+245245+ b) Convey the object code in, or embodied in, a physical product
246246+ (including a physical distribution medium), accompanied by a
247247+ written offer, valid for at least three years and valid for as
248248+ long as you offer spare parts or customer support for that product
249249+ model, to give anyone who possesses the object code either (1) a
250250+ copy of the Corresponding Source for all the software in the
251251+ product that is covered by this License, on a durable physical
252252+ medium customarily used for software interchange, for a price no
253253+ more than your reasonable cost of physically performing this
254254+ conveying of source, or (2) access to copy the
255255+ Corresponding Source from a network server at no charge.
256256+257257+ c) Convey individual copies of the object code with a copy of the
258258+ written offer to provide the Corresponding Source. This
259259+ alternative is allowed only occasionally and noncommercially, and
260260+ only if you received the object code with such an offer, in accord
261261+ with subsection 6b.
262262+263263+ d) Convey the object code by offering access from a designated
264264+ place (gratis or for a charge), and offer equivalent access to the
265265+ Corresponding Source in the same way through the same place at no
266266+ further charge. You need not require recipients to copy the
267267+ Corresponding Source along with the object code. If the place to
268268+ copy the object code is a network server, the Corresponding Source
269269+ may be on a different server (operated by you or a third party)
270270+ that supports equivalent copying facilities, provided you maintain
271271+ clear directions next to the object code saying where to find the
272272+ Corresponding Source. Regardless of what server hosts the
273273+ Corresponding Source, you remain obligated to ensure that it is
274274+ available for as long as needed to satisfy these requirements.
275275+276276+ e) Convey the object code using peer-to-peer transmission, provided
277277+ you inform other peers where the object code and Corresponding
278278+ Source of the work are being offered to the general public at no
279279+ charge under subsection 6d.
280280+281281+ A separable portion of the object code, whose source code is excluded
282282+from the Corresponding Source as a System Library, need not be
283283+included in conveying the object code work.
284284+285285+ A "User Product" is either (1) a "consumer product", which means any
286286+tangible personal property which is normally used for personal, family,
287287+or household purposes, or (2) anything designed or sold for incorporation
288288+into a dwelling. In determining whether a product is a consumer product,
289289+doubtful cases shall be resolved in favor of coverage. For a particular
290290+product received by a particular user, "normally used" refers to a
291291+typical or common use of that class of product, regardless of the status
292292+of the particular user or of the way in which the particular user
293293+actually uses, or expects or is expected to use, the product. A product
294294+is a consumer product regardless of whether the product has substantial
295295+commercial, industrial or non-consumer uses, unless such uses represent
296296+the only significant mode of use of the product.
297297+298298+ "Installation Information" for a User Product means any methods,
299299+procedures, authorization keys, or other information required to install
300300+and execute modified versions of a covered work in that User Product from
301301+a modified version of its Corresponding Source. The information must
302302+suffice to ensure that the continued functioning of the modified object
303303+code is in no case prevented or interfered with solely because
304304+modification has been made.
305305+306306+ If you convey an object code work under this section in, or with, or
307307+specifically for use in, a User Product, and the conveying occurs as
308308+part of a transaction in which the right of possession and use of the
309309+User Product is transferred to the recipient in perpetuity or for a
310310+fixed term (regardless of how the transaction is characterized), the
311311+Corresponding Source conveyed under this section must be accompanied
312312+by the Installation Information. But this requirement does not apply
313313+if neither you nor any third party retains the ability to install
314314+modified object code on the User Product (for example, the work has
315315+been installed in ROM).
316316+317317+ The requirement to provide Installation Information does not include a
318318+requirement to continue to provide support service, warranty, or updates
319319+for a work that has been modified or installed by the recipient, or for
320320+the User Product in which it has been modified or installed. Access to a
321321+network may be denied when the modification itself materially and
322322+adversely affects the operation of the network or violates the rules and
323323+protocols for communication across the network.
324324+325325+ Corresponding Source conveyed, and Installation Information provided,
326326+in accord with this section must be in a format that is publicly
327327+documented (and with an implementation available to the public in
328328+source code form), and must require no special password or key for
329329+unpacking, reading or copying.
330330+331331+ 7. Additional Terms.
332332+333333+ "Additional permissions" are terms that supplement the terms of this
334334+License by making exceptions from one or more of its conditions.
335335+Additional permissions that are applicable to the entire Program shall
336336+be treated as though they were included in this License, to the extent
337337+that they are valid under applicable law. If additional permissions
338338+apply only to part of the Program, that part may be used separately
339339+under those permissions, but the entire Program remains governed by
340340+this License without regard to the additional permissions.
341341+342342+ When you convey a copy of a covered work, you may at your option
343343+remove any additional permissions from that copy, or from any part of
344344+it. (Additional permissions may be written to require their own
345345+removal in certain cases when you modify the work.) You may place
346346+additional permissions on material, added by you to a covered work,
347347+for which you have or can give appropriate copyright permission.
348348+349349+ Notwithstanding any other provision of this License, for material you
350350+add to a covered work, you may (if authorized by the copyright holders of
351351+that material) supplement the terms of this License with terms:
352352+353353+ a) Disclaiming warranty or limiting liability differently from the
354354+ terms of sections 15 and 16 of this License; or
355355+356356+ b) Requiring preservation of specified reasonable legal notices or
357357+ author attributions in that material or in the Appropriate Legal
358358+ Notices displayed by works containing it; or
359359+360360+ c) Prohibiting misrepresentation of the origin of that material, or
361361+ requiring that modified versions of such material be marked in
362362+ reasonable ways as different from the original version; or
363363+364364+ d) Limiting the use for publicity purposes of names of licensors or
365365+ authors of the material; or
366366+367367+ e) Declining to grant rights under trademark law for use of some
368368+ trade names, trademarks, or service marks; or
369369+370370+ f) Requiring indemnification of licensors and authors of that
371371+ material by anyone who conveys the material (or modified versions of
372372+ it) with contractual assumptions of liability to the recipient, for
373373+ any liability that these contractual assumptions directly impose on
374374+ those licensors and authors.
375375+376376+ All other non-permissive additional terms are considered "further
377377+restrictions" within the meaning of section 10. If the Program as you
378378+received it, or any part of it, contains a notice stating that it is
379379+governed by this License along with a term that is a further
380380+restriction, you may remove that term. If a license document contains
381381+a further restriction but permits relicensing or conveying under this
382382+License, you may add to a covered work material governed by the terms
383383+of that license document, provided that the further restriction does
384384+not survive such relicensing or conveying.
385385+386386+ If you add terms to a covered work in accord with this section, you
387387+must place, in the relevant source files, a statement of the
388388+additional terms that apply to those files, or a notice indicating
389389+where to find the applicable terms.
390390+391391+ Additional terms, permissive or non-permissive, may be stated in the
392392+form of a separately written license, or stated as exceptions;
393393+the above requirements apply either way.
394394+395395+ 8. Termination.
396396+397397+ You may not propagate or modify a covered work except as expressly
398398+provided under this License. Any attempt otherwise to propagate or
399399+modify it is void, and will automatically terminate your rights under
400400+this License (including any patent licenses granted under the third
401401+paragraph of section 11).
402402+403403+ However, if you cease all violation of this License, then your
404404+license from a particular copyright holder is reinstated (a)
405405+provisionally, unless and until the copyright holder explicitly and
406406+finally terminates your license, and (b) permanently, if the copyright
407407+holder fails to notify you of the violation by some reasonable means
408408+prior to 60 days after the cessation.
409409+410410+ Moreover, your license from a particular copyright holder is
411411+reinstated permanently if the copyright holder notifies you of the
412412+violation by some reasonable means, this is the first time you have
413413+received notice of violation of this License (for any work) from that
414414+copyright holder, and you cure the violation prior to 30 days after
415415+your receipt of the notice.
416416+417417+ Termination of your rights under this section does not terminate the
418418+licenses of parties who have received copies or rights from you under
419419+this License. If your rights have been terminated and not permanently
420420+reinstated, you do not qualify to receive new licenses for the same
421421+material under section 10.
422422+423423+ 9. Acceptance Not Required for Having Copies.
424424+425425+ You are not required to accept this License in order to receive or
426426+run a copy of the Program. Ancillary propagation of a covered work
427427+occurring solely as a consequence of using peer-to-peer transmission
428428+to receive a copy likewise does not require acceptance. However,
429429+nothing other than this License grants you permission to propagate or
430430+modify any covered work. These actions infringe copyright if you do
431431+not accept this License. Therefore, by modifying or propagating a
432432+covered work, you indicate your acceptance of this License to do so.
433433+434434+ 10. Automatic Licensing of Downstream Recipients.
435435+436436+ Each time you convey a covered work, the recipient automatically
437437+receives a license from the original licensors, to run, modify and
438438+propagate that work, subject to this License. You are not responsible
439439+for enforcing compliance by third parties with this License.
440440+441441+ An "entity transaction" is a transaction transferring control of an
442442+organization, or substantially all assets of one, or subdividing an
443443+organization, or merging organizations. If propagation of a covered
444444+work results from an entity transaction, each party to that
445445+transaction who receives a copy of the work also receives whatever
446446+licenses to the work the party's predecessor in interest had or could
447447+give under the previous paragraph, plus a right to possession of the
448448+Corresponding Source of the work from the predecessor in interest, if
449449+the predecessor has it or can get it with reasonable efforts.
450450+451451+ You may not impose any further restrictions on the exercise of the
452452+rights granted or affirmed under this License. For example, you may
453453+not impose a license fee, royalty, or other charge for exercise of
454454+rights granted under this License, and you may not initiate litigation
455455+(including a cross-claim or counterclaim in a lawsuit) alleging that
456456+any patent claim is infringed by making, using, selling, offering for
457457+sale, or importing the Program or any portion of it.
458458+459459+ 11. Patents.
460460+461461+ A "contributor" is a copyright holder who authorizes use under this
462462+License of the Program or a work on which the Program is based. The
463463+work thus licensed is called the contributor's "contributor version".
464464+465465+ A contributor's "essential patent claims" are all patent claims
466466+owned or controlled by the contributor, whether already acquired or
467467+hereafter acquired, that would be infringed by some manner, permitted
468468+by this License, of making, using, or selling its contributor version,
469469+but do not include claims that would be infringed only as a
470470+consequence of further modification of the contributor version. For
471471+purposes of this definition, "control" includes the right to grant
472472+patent sublicenses in a manner consistent with the requirements of
473473+this License.
474474+475475+ Each contributor grants you a non-exclusive, worldwide, royalty-free
476476+patent license under the contributor's essential patent claims, to
477477+make, use, sell, offer for sale, import and otherwise run, modify and
478478+propagate the contents of its contributor version.
479479+480480+ In the following three paragraphs, a "patent license" is any express
481481+agreement or commitment, however denominated, not to enforce a patent
482482+(such as an express permission to practice a patent or covenant not to
483483+sue for patent infringement). To "grant" such a patent license to a
484484+party means to make such an agreement or commitment not to enforce a
485485+patent against the party.
486486+487487+ If you convey a covered work, knowingly relying on a patent license,
488488+and the Corresponding Source of the work is not available for anyone
489489+to copy, free of charge and under the terms of this License, through a
490490+publicly available network server or other readily accessible means,
491491+then you must either (1) cause the Corresponding Source to be so
492492+available, or (2) arrange to deprive yourself of the benefit of the
493493+patent license for this particular work, or (3) arrange, in a manner
494494+consistent with the requirements of this License, to extend the patent
495495+license to downstream recipients. "Knowingly relying" means you have
496496+actual knowledge that, but for the patent license, your conveying the
497497+covered work in a country, or your recipient's use of the covered work
498498+in a country, would infringe one or more identifiable patents in that
499499+country that you have reason to believe are valid.
500500+501501+ If, pursuant to or in connection with a single transaction or
502502+arrangement, you convey, or propagate by procuring conveyance of, a
503503+covered work, and grant a patent license to some of the parties
504504+receiving the covered work authorizing them to use, propagate, modify
505505+or convey a specific copy of the covered work, then the patent license
506506+you grant is automatically extended to all recipients of the covered
507507+work and works based on it.
508508+509509+ A patent license is "discriminatory" if it does not include within
510510+the scope of its coverage, prohibits the exercise of, or is
511511+conditioned on the non-exercise of one or more of the rights that are
512512+specifically granted under this License. You may not convey a covered
513513+work if you are a party to an arrangement with a third party that is
514514+in the business of distributing software, under which you make payment
515515+to the third party based on the extent of your activity of conveying
516516+the work, and under which the third party grants, to any of the
517517+parties who would receive the covered work from you, a discriminatory
518518+patent license (a) in connection with copies of the covered work
519519+conveyed by you (or copies made from those copies), or (b) primarily
520520+for and in connection with specific products or compilations that
521521+contain the covered work, unless you entered into that arrangement,
522522+or that patent license was granted, prior to 28 March 2007.
523523+524524+ Nothing in this License shall be construed as excluding or limiting
525525+any implied license or other defenses to infringement that may
526526+otherwise be available to you under applicable patent law.
527527+528528+ 12. No Surrender of Others' Freedom.
529529+530530+ If conditions are imposed on you (whether by court order, agreement or
531531+otherwise) that contradict the conditions of this License, they do not
532532+excuse you from the conditions of this License. If you cannot convey a
533533+covered work so as to satisfy simultaneously your obligations under this
534534+License and any other pertinent obligations, then as a consequence you may
535535+not convey it at all. For example, if you agree to terms that obligate you
536536+to collect a royalty for further conveying from those to whom you convey
537537+the Program, the only way you could satisfy both those terms and this
538538+License would be to refrain entirely from conveying the Program.
539539+540540+ 13. Remote Network Interaction; Use with the GNU General Public License.
541541+542542+ Notwithstanding any other provision of this License, if you modify the
543543+Program, your modified version must prominently offer all users
544544+interacting with it remotely through a computer network (if your version
545545+supports such interaction) an opportunity to receive the Corresponding
546546+Source of your version by providing access to the Corresponding Source
547547+from a network server at no charge, through some standard or customary
548548+means of facilitating copying of software. This Corresponding Source
549549+shall include the Corresponding Source for any work covered by version 3
550550+of the GNU General Public License that is incorporated pursuant to the
551551+following paragraph.
552552+553553+ Notwithstanding any other provision of this License, you have
554554+permission to link or combine any covered work with a work licensed
555555+under version 3 of the GNU General Public License into a single
556556+combined work, and to convey the resulting work. The terms of this
557557+License will continue to apply to the part which is the covered work,
558558+but the work with which it is combined will remain governed by version
559559+3 of the GNU General Public License.
560560+561561+ 14. Revised Versions of this License.
562562+563563+ The Free Software Foundation may publish revised and/or new versions of
564564+the GNU Affero General Public License from time to time. Such new versions
565565+will be similar in spirit to the present version, but may differ in detail to
566566+address new problems or concerns.
567567+568568+ Each version is given a distinguishing version number. If the
569569+Program specifies that a certain numbered version of the GNU Affero General
570570+Public License "or any later version" applies to it, you have the
571571+option of following the terms and conditions either of that numbered
572572+version or of any later version published by the Free Software
573573+Foundation. If the Program does not specify a version number of the
574574+GNU Affero General Public License, you may choose any version ever published
575575+by the Free Software Foundation.
576576+577577+ If the Program specifies that a proxy can decide which future
578578+versions of the GNU Affero General Public License can be used, that proxy's
579579+public statement of acceptance of a version permanently authorizes you
580580+to choose that version for the Program.
581581+582582+ Later license versions may give you additional or different
583583+permissions. However, no additional obligations are imposed on any
584584+author or copyright holder as a result of your choosing to follow a
585585+later version.
586586+587587+ 15. Disclaimer of Warranty.
588588+589589+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590590+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591591+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592592+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593593+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594594+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595595+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596596+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597597+598598+ 16. Limitation of Liability.
599599+600600+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601601+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602602+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603603+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604604+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605605+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606606+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607607+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608608+SUCH DAMAGES.
609609+610610+ 17. Interpretation of Sections 15 and 16.
611611+612612+ If the disclaimer of warranty and limitation of liability provided
613613+above cannot be given local legal effect according to their terms,
614614+reviewing courts shall apply local law that most closely approximates
615615+an absolute waiver of all civil liability in connection with the
616616+Program, unless a warranty or assumption of liability accompanies a
617617+copy of the Program in return for a fee.
618618+619619+ END OF TERMS AND CONDITIONS
620620+621621+ How to Apply These Terms to Your New Programs
622622+623623+ If you develop a new program, and you want it to be of the greatest
624624+possible use to the public, the best way to achieve this is to make it
625625+free software which everyone can redistribute and change under these terms.
626626+627627+ To do so, attach the following notices to the program. It is safest
628628+to attach them to the start of each source file to most effectively
629629+state the exclusion of warranty; and each file should have at least
630630+the "copyright" line and a pointer to where the full notice is found.
631631+632632+ <one line to give the program's name and a brief idea of what it does.>
633633+ Copyright (C) <year> <name of author>
634634+635635+ This program is free software: you can redistribute it and/or modify
636636+ it under the terms of the GNU Affero General Public License as published
637637+ by the Free Software Foundation, either version 3 of the License, or
638638+ (at your option) any later version.
639639+640640+ This program is distributed in the hope that it will be useful,
641641+ but WITHOUT ANY WARRANTY; without even the implied warranty of
642642+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643643+ GNU Affero General Public License for more details.
644644+645645+ You should have received a copy of the GNU Affero General Public License
646646+ along with this program. If not, see <https://www.gnu.org/licenses/>.
647647+648648+Also add information on how to contact you by electronic and paper mail.
649649+650650+ If your software can interact with users remotely through a computer
651651+network, you should also make sure that it provides a way for users to
652652+get its source. For example, if your program is a web application, its
653653+interface could display a "Source" link that leads users to an archive
654654+of the code. There are many ways you could offer source, and different
655655+solutions will be better for different programs; see section 13 for the
656656+specific requirements.
657657+658658+ You should also get your employer (if you work as a programmer) or school,
659659+if any, to sign a "copyright disclaimer" for the program, if necessary.
660660+For more information on this, and how to apply and follow the GNU AGPL, see
661661+<https://www.gnu.org/licenses/>.
···11[workspace]
22-members = ["wire/key_agent", "wire/lib", "wire/cli"]
22+members = ["crates/key_agent", "crates/core", "crates/cli"]
33resolver = "2"
44-package.edition = "2021"
55-package.version = "0.5.0"
44+package.edition = "2024"
55+package.version = "1.1.1"
6677[workspace.metadata.crane]
88name = "wire"
991010+[workspace.lints.clippy]
1111+pedantic = { level = "deny", priority = -1 }
1212+missing_const_for_fn = "deny"
1313+1414+# annoying to deal with
1515+missing_errors_doc = "allow"
1616+missing_panics_doc = "allow"
1717+1018[workspace.dependencies]
1111-clap = { version = "4.5.47", features = ["derive", "string", "cargo"] }
1919+futures-util = { version = "0.3.31", features = ["sink", "std"] }
2020+clap = { version = "4.5.51", features = ["derive", "string", "cargo"] }
1221clap-verbosity-flag = "3.0.4"
1313-serde = { version = "1.0.225", features = ["derive", "rc"] }
1414-serde_json = { version = "1.0.145" }
1515-tokio = { version = "1.47.1", features = ["full"] }
1616-tracing = "0.1.41"
2222+serde = { version = "1.0.228", features = ["derive", "rc"] }
2323+tokio = { version = "1.48.0", features = ["full"] }
2424+tracing = { version = "0.1.41", features = ["release_max_level_debug"] }
1725tracing-log = "0.2.0"
1826tracing-subscriber = "0.3.20"
1927im = { version = "15.1.0", features = ["serde"] }
2020-anyhow = "1.0.98"
2828+anyhow = "1.0.100"
2129prost = "0.14.1"
2230nix = { version = "0.30.1", features = ["user", "poll", "term"] }
2331miette = { version = "7.6.0", features = ["fancy"] }
2424-thiserror = "2.0.16"
3232+thiserror = "2.0.17"
3333+sha2 = "0.10.9"
3434+tokio-util = { version = "0.7.17", features = ["codec"] }
3535+base64 = "0.22.1"
3636+nix-compat = { git = "https://git.snix.dev/snix/snix.git", features = [
3737+ "serde",
3838+ "flakeref",
3939+] }
4040+# simd-json = { version = "0.17.0", features = [
4141+# "serde_impl",
4242+# # swar-number-parsing is disabled because nix never outputs
4343+# # floats.
4444+# # "swar-number-parsing",
4545+# "runtime-detection",
4646+# "hints",
4747+# ] }
4848+serde_json = { version = "1.0.145" }
4949+owo-colors = { version = "4.2.3", features = ["supports-colors"] }
5050+5151+[profile.dev.package.sqlx-macros]
5252+opt-level = 3
-661
LICENSE
···11- GNU AFFERO GENERAL PUBLIC LICENSE
22- Version 3, 19 November 2007
33-44- Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
55- Everyone is permitted to copy and distribute verbatim copies
66- of this license document, but changing it is not allowed.
77-88- Preamble
99-1010- The GNU Affero General Public License is a free, copyleft license for
1111-software and other kinds of works, specifically designed to ensure
1212-cooperation with the community in the case of network server software.
1313-1414- The licenses for most software and other practical works are designed
1515-to take away your freedom to share and change the works. By contrast,
1616-our General Public Licenses are intended to guarantee your freedom to
1717-share and change all versions of a program--to make sure it remains free
1818-software for all its users.
1919-2020- When we speak of free software, we are referring to freedom, not
2121-price. Our General Public Licenses are designed to make sure that you
2222-have the freedom to distribute copies of free software (and charge for
2323-them if you wish), that you receive source code or can get it if you
2424-want it, that you can change the software or use pieces of it in new
2525-free programs, and that you know you can do these things.
2626-2727- Developers that use our General Public Licenses protect your rights
2828-with two steps: (1) assert copyright on the software, and (2) offer
2929-you this License which gives you legal permission to copy, distribute
3030-and/or modify the software.
3131-3232- A secondary benefit of defending all users' freedom is that
3333-improvements made in alternate versions of the program, if they
3434-receive widespread use, become available for other developers to
3535-incorporate. Many developers of free software are heartened and
3636-encouraged by the resulting cooperation. However, in the case of
3737-software used on network servers, this result may fail to come about.
3838-The GNU General Public License permits making a modified version and
3939-letting the public access it on a server without ever releasing its
4040-source code to the public.
4141-4242- The GNU Affero General Public License is designed specifically to
4343-ensure that, in such cases, the modified source code becomes available
4444-to the community. It requires the operator of a network server to
4545-provide the source code of the modified version running there to the
4646-users of that server. Therefore, public use of a modified version, on
4747-a publicly accessible server, gives the public access to the source
4848-code of the modified version.
4949-5050- An older license, called the Affero General Public License and
5151-published by Affero, was designed to accomplish similar goals. This is
5252-a different license, not a version of the Affero GPL, but Affero has
5353-released a new version of the Affero GPL which permits relicensing under
5454-this license.
5555-5656- The precise terms and conditions for copying, distribution and
5757-modification follow.
5858-5959- TERMS AND CONDITIONS
6060-6161- 0. Definitions.
6262-6363- "This License" refers to version 3 of the GNU Affero General Public License.
6464-6565- "Copyright" also means copyright-like laws that apply to other kinds of
6666-works, such as semiconductor masks.
6767-6868- "The Program" refers to any copyrightable work licensed under this
6969-License. Each licensee is addressed as "you". "Licensees" and
7070-"recipients" may be individuals or organizations.
7171-7272- To "modify" a work means to copy from or adapt all or part of the work
7373-in a fashion requiring copyright permission, other than the making of an
7474-exact copy. The resulting work is called a "modified version" of the
7575-earlier work or a work "based on" the earlier work.
7676-7777- A "covered work" means either the unmodified Program or a work based
7878-on the Program.
7979-8080- To "propagate" a work means to do anything with it that, without
8181-permission, would make you directly or secondarily liable for
8282-infringement under applicable copyright law, except executing it on a
8383-computer or modifying a private copy. Propagation includes copying,
8484-distribution (with or without modification), making available to the
8585-public, and in some countries other activities as well.
8686-8787- To "convey" a work means any kind of propagation that enables other
8888-parties to make or receive copies. Mere interaction with a user through
8989-a computer network, with no transfer of a copy, is not conveying.
9090-9191- An interactive user interface displays "Appropriate Legal Notices"
9292-to the extent that it includes a convenient and prominently visible
9393-feature that (1) displays an appropriate copyright notice, and (2)
9494-tells the user that there is no warranty for the work (except to the
9595-extent that warranties are provided), that licensees may convey the
9696-work under this License, and how to view a copy of this License. If
9797-the interface presents a list of user commands or options, such as a
9898-menu, a prominent item in the list meets this criterion.
9999-100100- 1. Source Code.
101101-102102- The "source code" for a work means the preferred form of the work
103103-for making modifications to it. "Object code" means any non-source
104104-form of a work.
105105-106106- A "Standard Interface" means an interface that either is an official
107107-standard defined by a recognized standards body, or, in the case of
108108-interfaces specified for a particular programming language, one that
109109-is widely used among developers working in that language.
110110-111111- The "System Libraries" of an executable work include anything, other
112112-than the work as a whole, that (a) is included in the normal form of
113113-packaging a Major Component, but which is not part of that Major
114114-Component, and (b) serves only to enable use of the work with that
115115-Major Component, or to implement a Standard Interface for which an
116116-implementation is available to the public in source code form. A
117117-"Major Component", in this context, means a major essential component
118118-(kernel, window system, and so on) of the specific operating system
119119-(if any) on which the executable work runs, or a compiler used to
120120-produce the work, or an object code interpreter used to run it.
121121-122122- The "Corresponding Source" for a work in object code form means all
123123-the source code needed to generate, install, and (for an executable
124124-work) run the object code and to modify the work, including scripts to
125125-control those activities. However, it does not include the work's
126126-System Libraries, or general-purpose tools or generally available free
127127-programs which are used unmodified in performing those activities but
128128-which are not part of the work. For example, Corresponding Source
129129-includes interface definition files associated with source files for
130130-the work, and the source code for shared libraries and dynamically
131131-linked subprograms that the work is specifically designed to require,
132132-such as by intimate data communication or control flow between those
133133-subprograms and other parts of the work.
134134-135135- The Corresponding Source need not include anything that users
136136-can regenerate automatically from other parts of the Corresponding
137137-Source.
138138-139139- The Corresponding Source for a work in source code form is that
140140-same work.
141141-142142- 2. Basic Permissions.
143143-144144- All rights granted under this License are granted for the term of
145145-copyright on the Program, and are irrevocable provided the stated
146146-conditions are met. This License explicitly affirms your unlimited
147147-permission to run the unmodified Program. The output from running a
148148-covered work is covered by this License only if the output, given its
149149-content, constitutes a covered work. This License acknowledges your
150150-rights of fair use or other equivalent, as provided by copyright law.
151151-152152- You may make, run and propagate covered works that you do not
153153-convey, without conditions so long as your license otherwise remains
154154-in force. You may convey covered works to others for the sole purpose
155155-of having them make modifications exclusively for you, or provide you
156156-with facilities for running those works, provided that you comply with
157157-the terms of this License in conveying all material for which you do
158158-not control copyright. Those thus making or running the covered works
159159-for you must do so exclusively on your behalf, under your direction
160160-and control, on terms that prohibit them from making any copies of
161161-your copyrighted material outside their relationship with you.
162162-163163- Conveying under any other circumstances is permitted solely under
164164-the conditions stated below. Sublicensing is not allowed; section 10
165165-makes it unnecessary.
166166-167167- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168168-169169- No covered work shall be deemed part of an effective technological
170170-measure under any applicable law fulfilling obligations under article
171171-11 of the WIPO copyright treaty adopted on 20 December 1996, or
172172-similar laws prohibiting or restricting circumvention of such
173173-measures.
174174-175175- When you convey a covered work, you waive any legal power to forbid
176176-circumvention of technological measures to the extent such circumvention
177177-is effected by exercising rights under this License with respect to
178178-the covered work, and you disclaim any intention to limit operation or
179179-modification of the work as a means of enforcing, against the work's
180180-users, your or third parties' legal rights to forbid circumvention of
181181-technological measures.
182182-183183- 4. Conveying Verbatim Copies.
184184-185185- You may convey verbatim copies of the Program's source code as you
186186-receive it, in any medium, provided that you conspicuously and
187187-appropriately publish on each copy an appropriate copyright notice;
188188-keep intact all notices stating that this License and any
189189-non-permissive terms added in accord with section 7 apply to the code;
190190-keep intact all notices of the absence of any warranty; and give all
191191-recipients a copy of this License along with the Program.
192192-193193- You may charge any price or no price for each copy that you convey,
194194-and you may offer support or warranty protection for a fee.
195195-196196- 5. Conveying Modified Source Versions.
197197-198198- You may convey a work based on the Program, or the modifications to
199199-produce it from the Program, in the form of source code under the
200200-terms of section 4, provided that you also meet all of these conditions:
201201-202202- a) The work must carry prominent notices stating that you modified
203203- it, and giving a relevant date.
204204-205205- b) The work must carry prominent notices stating that it is
206206- released under this License and any conditions added under section
207207- 7. This requirement modifies the requirement in section 4 to
208208- "keep intact all notices".
209209-210210- c) You must license the entire work, as a whole, under this
211211- License to anyone who comes into possession of a copy. This
212212- License will therefore apply, along with any applicable section 7
213213- additional terms, to the whole of the work, and all its parts,
214214- regardless of how they are packaged. This License gives no
215215- permission to license the work in any other way, but it does not
216216- invalidate such permission if you have separately received it.
217217-218218- d) If the work has interactive user interfaces, each must display
219219- Appropriate Legal Notices; however, if the Program has interactive
220220- interfaces that do not display Appropriate Legal Notices, your
221221- work need not make them do so.
222222-223223- A compilation of a covered work with other separate and independent
224224-works, which are not by their nature extensions of the covered work,
225225-and which are not combined with it such as to form a larger program,
226226-in or on a volume of a storage or distribution medium, is called an
227227-"aggregate" if the compilation and its resulting copyright are not
228228-used to limit the access or legal rights of the compilation's users
229229-beyond what the individual works permit. Inclusion of a covered work
230230-in an aggregate does not cause this License to apply to the other
231231-parts of the aggregate.
232232-233233- 6. Conveying Non-Source Forms.
234234-235235- You may convey a covered work in object code form under the terms
236236-of sections 4 and 5, provided that you also convey the
237237-machine-readable Corresponding Source under the terms of this License,
238238-in one of these ways:
239239-240240- a) Convey the object code in, or embodied in, a physical product
241241- (including a physical distribution medium), accompanied by the
242242- Corresponding Source fixed on a durable physical medium
243243- customarily used for software interchange.
244244-245245- b) Convey the object code in, or embodied in, a physical product
246246- (including a physical distribution medium), accompanied by a
247247- written offer, valid for at least three years and valid for as
248248- long as you offer spare parts or customer support for that product
249249- model, to give anyone who possesses the object code either (1) a
250250- copy of the Corresponding Source for all the software in the
251251- product that is covered by this License, on a durable physical
252252- medium customarily used for software interchange, for a price no
253253- more than your reasonable cost of physically performing this
254254- conveying of source, or (2) access to copy the
255255- Corresponding Source from a network server at no charge.
256256-257257- c) Convey individual copies of the object code with a copy of the
258258- written offer to provide the Corresponding Source. This
259259- alternative is allowed only occasionally and noncommercially, and
260260- only if you received the object code with such an offer, in accord
261261- with subsection 6b.
262262-263263- d) Convey the object code by offering access from a designated
264264- place (gratis or for a charge), and offer equivalent access to the
265265- Corresponding Source in the same way through the same place at no
266266- further charge. You need not require recipients to copy the
267267- Corresponding Source along with the object code. If the place to
268268- copy the object code is a network server, the Corresponding Source
269269- may be on a different server (operated by you or a third party)
270270- that supports equivalent copying facilities, provided you maintain
271271- clear directions next to the object code saying where to find the
272272- Corresponding Source. Regardless of what server hosts the
273273- Corresponding Source, you remain obligated to ensure that it is
274274- available for as long as needed to satisfy these requirements.
275275-276276- e) Convey the object code using peer-to-peer transmission, provided
277277- you inform other peers where the object code and Corresponding
278278- Source of the work are being offered to the general public at no
279279- charge under subsection 6d.
280280-281281- A separable portion of the object code, whose source code is excluded
282282-from the Corresponding Source as a System Library, need not be
283283-included in conveying the object code work.
284284-285285- A "User Product" is either (1) a "consumer product", which means any
286286-tangible personal property which is normally used for personal, family,
287287-or household purposes, or (2) anything designed or sold for incorporation
288288-into a dwelling. In determining whether a product is a consumer product,
289289-doubtful cases shall be resolved in favor of coverage. For a particular
290290-product received by a particular user, "normally used" refers to a
291291-typical or common use of that class of product, regardless of the status
292292-of the particular user or of the way in which the particular user
293293-actually uses, or expects or is expected to use, the product. A product
294294-is a consumer product regardless of whether the product has substantial
295295-commercial, industrial or non-consumer uses, unless such uses represent
296296-the only significant mode of use of the product.
297297-298298- "Installation Information" for a User Product means any methods,
299299-procedures, authorization keys, or other information required to install
300300-and execute modified versions of a covered work in that User Product from
301301-a modified version of its Corresponding Source. The information must
302302-suffice to ensure that the continued functioning of the modified object
303303-code is in no case prevented or interfered with solely because
304304-modification has been made.
305305-306306- If you convey an object code work under this section in, or with, or
307307-specifically for use in, a User Product, and the conveying occurs as
308308-part of a transaction in which the right of possession and use of the
309309-User Product is transferred to the recipient in perpetuity or for a
310310-fixed term (regardless of how the transaction is characterized), the
311311-Corresponding Source conveyed under this section must be accompanied
312312-by the Installation Information. But this requirement does not apply
313313-if neither you nor any third party retains the ability to install
314314-modified object code on the User Product (for example, the work has
315315-been installed in ROM).
316316-317317- The requirement to provide Installation Information does not include a
318318-requirement to continue to provide support service, warranty, or updates
319319-for a work that has been modified or installed by the recipient, or for
320320-the User Product in which it has been modified or installed. Access to a
321321-network may be denied when the modification itself materially and
322322-adversely affects the operation of the network or violates the rules and
323323-protocols for communication across the network.
324324-325325- Corresponding Source conveyed, and Installation Information provided,
326326-in accord with this section must be in a format that is publicly
327327-documented (and with an implementation available to the public in
328328-source code form), and must require no special password or key for
329329-unpacking, reading or copying.
330330-331331- 7. Additional Terms.
332332-333333- "Additional permissions" are terms that supplement the terms of this
334334-License by making exceptions from one or more of its conditions.
335335-Additional permissions that are applicable to the entire Program shall
336336-be treated as though they were included in this License, to the extent
337337-that they are valid under applicable law. If additional permissions
338338-apply only to part of the Program, that part may be used separately
339339-under those permissions, but the entire Program remains governed by
340340-this License without regard to the additional permissions.
341341-342342- When you convey a copy of a covered work, you may at your option
343343-remove any additional permissions from that copy, or from any part of
344344-it. (Additional permissions may be written to require their own
345345-removal in certain cases when you modify the work.) You may place
346346-additional permissions on material, added by you to a covered work,
347347-for which you have or can give appropriate copyright permission.
348348-349349- Notwithstanding any other provision of this License, for material you
350350-add to a covered work, you may (if authorized by the copyright holders of
351351-that material) supplement the terms of this License with terms:
352352-353353- a) Disclaiming warranty or limiting liability differently from the
354354- terms of sections 15 and 16 of this License; or
355355-356356- b) Requiring preservation of specified reasonable legal notices or
357357- author attributions in that material or in the Appropriate Legal
358358- Notices displayed by works containing it; or
359359-360360- c) Prohibiting misrepresentation of the origin of that material, or
361361- requiring that modified versions of such material be marked in
362362- reasonable ways as different from the original version; or
363363-364364- d) Limiting the use for publicity purposes of names of licensors or
365365- authors of the material; or
366366-367367- e) Declining to grant rights under trademark law for use of some
368368- trade names, trademarks, or service marks; or
369369-370370- f) Requiring indemnification of licensors and authors of that
371371- material by anyone who conveys the material (or modified versions of
372372- it) with contractual assumptions of liability to the recipient, for
373373- any liability that these contractual assumptions directly impose on
374374- those licensors and authors.
375375-376376- All other non-permissive additional terms are considered "further
377377-restrictions" within the meaning of section 10. If the Program as you
378378-received it, or any part of it, contains a notice stating that it is
379379-governed by this License along with a term that is a further
380380-restriction, you may remove that term. If a license document contains
381381-a further restriction but permits relicensing or conveying under this
382382-License, you may add to a covered work material governed by the terms
383383-of that license document, provided that the further restriction does
384384-not survive such relicensing or conveying.
385385-386386- If you add terms to a covered work in accord with this section, you
387387-must place, in the relevant source files, a statement of the
388388-additional terms that apply to those files, or a notice indicating
389389-where to find the applicable terms.
390390-391391- Additional terms, permissive or non-permissive, may be stated in the
392392-form of a separately written license, or stated as exceptions;
393393-the above requirements apply either way.
394394-395395- 8. Termination.
396396-397397- You may not propagate or modify a covered work except as expressly
398398-provided under this License. Any attempt otherwise to propagate or
399399-modify it is void, and will automatically terminate your rights under
400400-this License (including any patent licenses granted under the third
401401-paragraph of section 11).
402402-403403- However, if you cease all violation of this License, then your
404404-license from a particular copyright holder is reinstated (a)
405405-provisionally, unless and until the copyright holder explicitly and
406406-finally terminates your license, and (b) permanently, if the copyright
407407-holder fails to notify you of the violation by some reasonable means
408408-prior to 60 days after the cessation.
409409-410410- Moreover, your license from a particular copyright holder is
411411-reinstated permanently if the copyright holder notifies you of the
412412-violation by some reasonable means, this is the first time you have
413413-received notice of violation of this License (for any work) from that
414414-copyright holder, and you cure the violation prior to 30 days after
415415-your receipt of the notice.
416416-417417- Termination of your rights under this section does not terminate the
418418-licenses of parties who have received copies or rights from you under
419419-this License. If your rights have been terminated and not permanently
420420-reinstated, you do not qualify to receive new licenses for the same
421421-material under section 10.
422422-423423- 9. Acceptance Not Required for Having Copies.
424424-425425- You are not required to accept this License in order to receive or
426426-run a copy of the Program. Ancillary propagation of a covered work
427427-occurring solely as a consequence of using peer-to-peer transmission
428428-to receive a copy likewise does not require acceptance. However,
429429-nothing other than this License grants you permission to propagate or
430430-modify any covered work. These actions infringe copyright if you do
431431-not accept this License. Therefore, by modifying or propagating a
432432-covered work, you indicate your acceptance of this License to do so.
433433-434434- 10. Automatic Licensing of Downstream Recipients.
435435-436436- Each time you convey a covered work, the recipient automatically
437437-receives a license from the original licensors, to run, modify and
438438-propagate that work, subject to this License. You are not responsible
439439-for enforcing compliance by third parties with this License.
440440-441441- An "entity transaction" is a transaction transferring control of an
442442-organization, or substantially all assets of one, or subdividing an
443443-organization, or merging organizations. If propagation of a covered
444444-work results from an entity transaction, each party to that
445445-transaction who receives a copy of the work also receives whatever
446446-licenses to the work the party's predecessor in interest had or could
447447-give under the previous paragraph, plus a right to possession of the
448448-Corresponding Source of the work from the predecessor in interest, if
449449-the predecessor has it or can get it with reasonable efforts.
450450-451451- You may not impose any further restrictions on the exercise of the
452452-rights granted or affirmed under this License. For example, you may
453453-not impose a license fee, royalty, or other charge for exercise of
454454-rights granted under this License, and you may not initiate litigation
455455-(including a cross-claim or counterclaim in a lawsuit) alleging that
456456-any patent claim is infringed by making, using, selling, offering for
457457-sale, or importing the Program or any portion of it.
458458-459459- 11. Patents.
460460-461461- A "contributor" is a copyright holder who authorizes use under this
462462-License of the Program or a work on which the Program is based. The
463463-work thus licensed is called the contributor's "contributor version".
464464-465465- A contributor's "essential patent claims" are all patent claims
466466-owned or controlled by the contributor, whether already acquired or
467467-hereafter acquired, that would be infringed by some manner, permitted
468468-by this License, of making, using, or selling its contributor version,
469469-but do not include claims that would be infringed only as a
470470-consequence of further modification of the contributor version. For
471471-purposes of this definition, "control" includes the right to grant
472472-patent sublicenses in a manner consistent with the requirements of
473473-this License.
474474-475475- Each contributor grants you a non-exclusive, worldwide, royalty-free
476476-patent license under the contributor's essential patent claims, to
477477-make, use, sell, offer for sale, import and otherwise run, modify and
478478-propagate the contents of its contributor version.
479479-480480- In the following three paragraphs, a "patent license" is any express
481481-agreement or commitment, however denominated, not to enforce a patent
482482-(such as an express permission to practice a patent or covenant not to
483483-sue for patent infringement). To "grant" such a patent license to a
484484-party means to make such an agreement or commitment not to enforce a
485485-patent against the party.
486486-487487- If you convey a covered work, knowingly relying on a patent license,
488488-and the Corresponding Source of the work is not available for anyone
489489-to copy, free of charge and under the terms of this License, through a
490490-publicly available network server or other readily accessible means,
491491-then you must either (1) cause the Corresponding Source to be so
492492-available, or (2) arrange to deprive yourself of the benefit of the
493493-patent license for this particular work, or (3) arrange, in a manner
494494-consistent with the requirements of this License, to extend the patent
495495-license to downstream recipients. "Knowingly relying" means you have
496496-actual knowledge that, but for the patent license, your conveying the
497497-covered work in a country, or your recipient's use of the covered work
498498-in a country, would infringe one or more identifiable patents in that
499499-country that you have reason to believe are valid.
500500-501501- If, pursuant to or in connection with a single transaction or
502502-arrangement, you convey, or propagate by procuring conveyance of, a
503503-covered work, and grant a patent license to some of the parties
504504-receiving the covered work authorizing them to use, propagate, modify
505505-or convey a specific copy of the covered work, then the patent license
506506-you grant is automatically extended to all recipients of the covered
507507-work and works based on it.
508508-509509- A patent license is "discriminatory" if it does not include within
510510-the scope of its coverage, prohibits the exercise of, or is
511511-conditioned on the non-exercise of one or more of the rights that are
512512-specifically granted under this License. You may not convey a covered
513513-work if you are a party to an arrangement with a third party that is
514514-in the business of distributing software, under which you make payment
515515-to the third party based on the extent of your activity of conveying
516516-the work, and under which the third party grants, to any of the
517517-parties who would receive the covered work from you, a discriminatory
518518-patent license (a) in connection with copies of the covered work
519519-conveyed by you (or copies made from those copies), or (b) primarily
520520-for and in connection with specific products or compilations that
521521-contain the covered work, unless you entered into that arrangement,
522522-or that patent license was granted, prior to 28 March 2007.
523523-524524- Nothing in this License shall be construed as excluding or limiting
525525-any implied license or other defenses to infringement that may
526526-otherwise be available to you under applicable patent law.
527527-528528- 12. No Surrender of Others' Freedom.
529529-530530- If conditions are imposed on you (whether by court order, agreement or
531531-otherwise) that contradict the conditions of this License, they do not
532532-excuse you from the conditions of this License. If you cannot convey a
533533-covered work so as to satisfy simultaneously your obligations under this
534534-License and any other pertinent obligations, then as a consequence you may
535535-not convey it at all. For example, if you agree to terms that obligate you
536536-to collect a royalty for further conveying from those to whom you convey
537537-the Program, the only way you could satisfy both those terms and this
538538-License would be to refrain entirely from conveying the Program.
539539-540540- 13. Remote Network Interaction; Use with the GNU General Public License.
541541-542542- Notwithstanding any other provision of this License, if you modify the
543543-Program, your modified version must prominently offer all users
544544-interacting with it remotely through a computer network (if your version
545545-supports such interaction) an opportunity to receive the Corresponding
546546-Source of your version by providing access to the Corresponding Source
547547-from a network server at no charge, through some standard or customary
548548-means of facilitating copying of software. This Corresponding Source
549549-shall include the Corresponding Source for any work covered by version 3
550550-of the GNU General Public License that is incorporated pursuant to the
551551-following paragraph.
552552-553553- Notwithstanding any other provision of this License, you have
554554-permission to link or combine any covered work with a work licensed
555555-under version 3 of the GNU General Public License into a single
556556-combined work, and to convey the resulting work. The terms of this
557557-License will continue to apply to the part which is the covered work,
558558-but the work with which it is combined will remain governed by version
559559-3 of the GNU General Public License.
560560-561561- 14. Revised Versions of this License.
562562-563563- The Free Software Foundation may publish revised and/or new versions of
564564-the GNU Affero General Public License from time to time. Such new versions
565565-will be similar in spirit to the present version, but may differ in detail to
566566-address new problems or concerns.
567567-568568- Each version is given a distinguishing version number. If the
569569-Program specifies that a certain numbered version of the GNU Affero General
570570-Public License "or any later version" applies to it, you have the
571571-option of following the terms and conditions either of that numbered
572572-version or of any later version published by the Free Software
573573-Foundation. If the Program does not specify a version number of the
574574-GNU Affero General Public License, you may choose any version ever published
575575-by the Free Software Foundation.
576576-577577- If the Program specifies that a proxy can decide which future
578578-versions of the GNU Affero General Public License can be used, that proxy's
579579-public statement of acceptance of a version permanently authorizes you
580580-to choose that version for the Program.
581581-582582- Later license versions may give you additional or different
583583-permissions. However, no additional obligations are imposed on any
584584-author or copyright holder as a result of your choosing to follow a
585585-later version.
586586-587587- 15. Disclaimer of Warranty.
588588-589589- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590590-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591591-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592592-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593593-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594594-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595595-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596596-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597597-598598- 16. Limitation of Liability.
599599-600600- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601601-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602602-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603603-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604604-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605605-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606606-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607607-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608608-SUCH DAMAGES.
609609-610610- 17. Interpretation of Sections 15 and 16.
611611-612612- If the disclaimer of warranty and limitation of liability provided
613613-above cannot be given local legal effect according to their terms,
614614-reviewing courts shall apply local law that most closely approximates
615615-an absolute waiver of all civil liability in connection with the
616616-Program, unless a warranty or assumption of liability accompanies a
617617-copy of the Program in return for a fee.
618618-619619- END OF TERMS AND CONDITIONS
620620-621621- How to Apply These Terms to Your New Programs
622622-623623- If you develop a new program, and you want it to be of the greatest
624624-possible use to the public, the best way to achieve this is to make it
625625-free software which everyone can redistribute and change under these terms.
626626-627627- To do so, attach the following notices to the program. It is safest
628628-to attach them to the start of each source file to most effectively
629629-state the exclusion of warranty; and each file should have at least
630630-the "copyright" line and a pointer to where the full notice is found.
631631-632632- <one line to give the program's name and a brief idea of what it does.>
633633- Copyright (C) <year> <name of author>
634634-635635- This program is free software: you can redistribute it and/or modify
636636- it under the terms of the GNU Affero General Public License as published
637637- by the Free Software Foundation, either version 3 of the License, or
638638- (at your option) any later version.
639639-640640- This program is distributed in the hope that it will be useful,
641641- but WITHOUT ANY WARRANTY; without even the implied warranty of
642642- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643643- GNU Affero General Public License for more details.
644644-645645- You should have received a copy of the GNU Affero General Public License
646646- along with this program. If not, see <https://www.gnu.org/licenses/>.
647647-648648-Also add information on how to contact you by electronic and paper mail.
649649-650650- If your software can interact with users remotely through a computer
651651-network, you should also make sure that it provides a way for users to
652652-get its source. For example, if your program is a web application, its
653653-interface could display a "Source" link that leads users to an archive
654654-of the code. There are many ways you could offer source, and different
655655-solutions will be better for different programs; see section 13 for the
656656-specific requirements.
657657-658658- You should also get your employer (if you work as a programmer) or school,
659659-if any, to sign a "copyright disclaimer" for the program, if necessary.
660660-For more information on this, and how to apply and follow the GNU AGPL, see
661661-<https://www.gnu.org/licenses/>.
+4-40
README.md
···11-# wire
22-33-
44-
55-
11+
22+
33+
6475wire is a tool to deploy nixos systems. its usage is inspired by colmena however it is not a fork.
8699-Read the [The Guide](https://wire.althaea.zone/guide/wire.html), or continue reading this readme for development information.
1010-1111-## Tree Layout
1212-1313-```
1414-wire
1515-โโโ wire
1616-โ โโโ lib
1717-โ โ โโโ Rust library containing business logic, consumed by `wire`
1818-โ โโโ cli
1919-โ โ โโโ Rust binary, using `lib`
2020-โ โโโ key_agent
2121-โ โโโ Rust binary ran on a target node. recieves key file bytes and metadata w/ protobuf over SSH stdin
2222-โโโ doc
2323-โ โโโ a [vitepress](https://vitepress.dev/) site
2424-โโโ runtime
2525-โ โโโ Nix files used during runtime to evaluate nodes
2626-โโโtests
2727- โโโ Directories used during cargo & NixOS VM testing
2828-```
77+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.
298309## Development
31103211Please use `nix develop` for access to the development environment and to ensure
3312your changes are ran against the defined git hooks. For simplicity, you may wish
3413to use [direnv](https://github.com/direnv/direnv).
3535-3636-### Testing
3737-3838-#### dhat profiling
3939-4040-```sh
4141-$ just build-dhat
4242-```
4343-4444-#### Testing
4545-4646-```sh
4747-$ cargo test
4848-$ nix flake check
4949-```
···11+// SPDX-License-Identifier: AGPL-3.0-or-later
22+// Copyright 2024-2025 wire Contributors
33+44+pub mod activate;
55+pub mod build;
66+pub mod cleanup;
77+pub mod evaluate;
88+pub mod keys;
99+pub mod ping;
1010+pub mod push;
+58
crates/core/src/hive/steps/ping.rs
···11+// SPDX-License-Identifier: AGPL-3.0-or-later
22+// Copyright 2024-2025 wire Contributors
33+44+use std::fmt::Display;
55+66+use tracing::{Level, event, instrument};
77+88+use crate::{
99+ HiveLibError,
1010+ hive::node::{Context, ExecuteStep, Objective},
1111+};
1212+1313+#[derive(Debug, PartialEq)]
1414+pub struct Ping;
1515+1616+impl Display for Ping {
1717+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1818+ write!(f, "Ping node")
1919+ }
2020+}
2121+2222+impl ExecuteStep for Ping {
2323+ fn should_execute(&self, ctx: &Context) -> bool {
2424+ let Objective::Apply(apply_objective) = ctx.objective else {
2525+ return false;
2626+ };
2727+2828+ !apply_objective.should_apply_locally
2929+ }
3030+3131+ #[instrument(skip_all, name = "ping")]
3232+ async fn execute(&self, ctx: &mut Context<'_>) -> Result<(), HiveLibError> {
3333+ loop {
3434+ event!(
3535+ Level::INFO,
3636+ status = "attempting",
3737+ host = ctx.node.target.get_preferred_host()?.to_string()
3838+ );
3939+4040+ if ctx.node.ping(ctx.modifiers).await.is_ok() {
4141+ event!(
4242+ Level::INFO,
4343+ status = "success",
4444+ host = ctx.node.target.get_preferred_host()?.to_string()
4545+ );
4646+ return Ok(());
4747+ }
4848+4949+ // ? will take us out if we ran out of hosts
5050+ event!(
5151+ Level::WARN,
5252+ status = "failed to ping",
5353+ host = ctx.node.target.get_preferred_host()?.to_string()
5454+ );
5555+ ctx.node.target.host_failed();
5656+ }
5757+ }
5858+}
+84
crates/core/src/hive/steps/push.rs
···11+// SPDX-License-Identifier: AGPL-3.0-or-later
22+// Copyright 2024-2025 wire Contributors
33+44+use std::fmt::Display;
55+66+use tracing::instrument;
77+88+use crate::{
99+ HiveLibError,
1010+ commands::common::push,
1111+ hive::node::{Context, ExecuteStep, Goal, Objective},
1212+};
1313+1414+#[derive(Debug, PartialEq)]
1515+pub struct PushEvaluatedOutput;
1616+#[derive(Debug, PartialEq)]
1717+pub struct PushBuildOutput;
1818+1919+impl Display for PushEvaluatedOutput {
2020+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2121+ write!(f, "Push the evaluated output")
2222+ }
2323+}
2424+2525+impl Display for PushBuildOutput {
2626+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2727+ write!(f, "Push the build output")
2828+ }
2929+}
3030+3131+impl ExecuteStep for PushEvaluatedOutput {
3232+ fn should_execute(&self, ctx: &Context) -> bool {
3333+ let Objective::Apply(apply_objective) = ctx.objective else {
3434+ return false;
3535+ };
3636+3737+ !matches!(apply_objective.goal, Goal::Keys)
3838+ && !apply_objective.should_apply_locally
3939+ && (ctx.node.build_remotely | matches!(apply_objective.goal, Goal::Push))
4040+ }
4141+4242+ #[instrument(skip_all, name = "push_eval")]
4343+ async fn execute(&self, ctx: &mut Context<'_>) -> Result<(), HiveLibError> {
4444+ let top_level = ctx.state.evaluation.as_ref().unwrap();
4545+4646+ push(ctx, crate::hive::node::Push::Derivation(top_level)).await?;
4747+4848+ Ok(())
4949+ }
5050+}
5151+5252+impl ExecuteStep for PushBuildOutput {
5353+ fn should_execute(&self, ctx: &Context) -> bool {
5454+ let Objective::Apply(apply_objective) = ctx.objective else {
5555+ return false;
5656+ };
5757+5858+ if matches!(apply_objective.goal, Goal::Keys | Goal::Push) {
5959+ // skip if we are not building
6060+ return false;
6161+ }
6262+6363+ if ctx.node.build_remotely {
6464+ // skip if we are building remotely
6565+ return false;
6666+ }
6767+6868+ if apply_objective.should_apply_locally {
6969+ // skip step if we are applying locally
7070+ return false;
7171+ }
7272+7373+ true
7474+ }
7575+7676+ #[instrument(skip_all, name = "push_build")]
7777+ async fn execute(&self, ctx: &mut Context<'_>) -> Result<(), HiveLibError> {
7878+ let built_path = ctx.state.build.as_ref().unwrap();
7979+8080+ push(ctx, crate::hive::node::Push::Path(built_path)).await?;
8181+8282+ Ok(())
8383+ }
8484+}
···11----
22-comment: true
33-title: Applying Your Config
44-description: How to apply a node with wire.
55----
66-77-# {{ $frontmatter.title }}
88-99-{{ $frontmatter.description }}
1010-1111-## What does it mean to 'apply'?
1212-1313-Once you have [created a hive](./getting-started), you can now "apply" your
1414-configuration to nodes in your hive. Simply, "applying" is the term used by wire to describe **deploying the
1515-config**.
1616-1717-::: info
1818-Applying a node typically involves pushing keys,
1919-evaluating the node's NixOS system, building the node's NixOS system, and running
2020-`switch-to-configuration`, depending on which specific goal is used.
2121-:::
2222-2323-The simplest way to apply is simply running:
2424-2525-```sh
2626-wire apply switch
2727-```
2828-2929-Which will `switch` to each node's NixOS system in your hive and push
3030-secrets (the equivalent to `nixos-rebuild`'s `nixos-rebuild switch`).
3131-3232-::: details Apply Goal Flowchart
3333-The following is an illustrative flowchart of how each step in the apply execution is ran.
3434-3535-Depending on the specific goal certain steps will not run, for example the
3636-Switch to Configuration step will never run if the goal is `build`.
3737-3838-```mermaid
3939-flowchart TD
4040- A(Test Connection) --> |IP / Hostname| B(Push Keys)
4141-4242- C(Evaluate NixOS System)
4343-4444- B --> C
4545- C -->|.drv Path| local
4646- C -->|.drv Path| remote
4747-4848- subgraph remote[Remote Node]
4949- D(Push To Node)
5050- D --> E(Build NixOS System)
5151- E -->|Built System| H(Push To Node)
5252- end
5353-5454- subgraph local[Local Node]
5555- direction RL
5656- G(Build NixOS System Locally)
5757- end
5858-5959- G --> F(Switch To Configuration)
6060- H --> F
6161-```
6262-6363-:::
6464-6565-## Apply goals
6666-6767-`wire apply` accepts a goal, which include verbs which will be familiar to
6868-`nixos-rebuild` users such as `switch`, `boot`, and `test`, alongside additional verbs
6969-like `keys` and `push`.
7070-7171-### `wire apply keys`
7272-7373-Wire will push all deployment keys to nodes, and do nothing else. While running
7474-this goal, option
7575-[`deployment.keys.<name>.uploadAt`](/reference/module#deployment-keys-name-uploadat)
7676-has no effect and all keys will be pushed. Read [the secret management guide](./keys)
7777-to learn more about wire deployment keys.
7878-7979-### `wire apply push`
8080-8181-Wire will "push" (equivalent to [`nix
8282-copy`](https://nix.dev/manual/nix/2.18/command-ref/new-cli/nix3-copy)) the
8383-`.drv` file that can produce the node's NixOS system when built.
8484-8585-### `wire apply build`
8686-8787-Sister to `wire apply push`, wire will build the
8888-node's NixOS system and ensure the output path exists on the node. Depending on
8989-[`deployment.buildOnTarget`](/reference/module#deployment-buildontarget), the
9090-`.drv` file may be built on the machine invoking wire or the node itself.
9191-9292-### `wire apply [switch|boot|test|dry-activate]`
9393-9494-Type `wire apply --help` or
9595-[read the reference](../reference/cli#wire-apply) to read more.
9696-9797-## Applying locally
9898-9999-If `deployment.allowLocalDeployment` is `true`, and the machine invoking wire's
100100-host name is equivalent to a node's name, wire will apply that node to the local
101101-machine. Goals like `push` and `build`, wont actually "push" anything as
102102-the paths already exists on the local machine.
103103-104104-When applying to your local machine, wire can interactively run `sudo`!
105105-Wire will prompt for your password, meaning wire can be ran as any user in
106106-the `wheel` group.
107107-108108-## Applying specific nodes
109109-110110-Use the `--on` argument to specify which nodes in your hive to apply:
111111-112112-```sh
113113-wire apply --on node-a
114114-```
115115-116116-Further examples, including how you can utilise tags, can be found on the [Targeting Nodes](./targeting) page.
-75
doc/guide/flakes.md
···11----
22-comment: true
33-title: Flakes
44-description: Learn how to output a hive from a flake.
55----
66-77-# {{ $frontmatter.title }}
88-99-{{ $frontmatter.description }}
1010-1111-## Output a hive
1212-1313-::: tip
1414-If you have skipped ahead, please read the previous page to understand the
1515-concept of a hive.
1616-:::
1717-1818-You can use wire with a flake by outputting a hive with the `wire` flake output.
1919-Just like when using a `hive.nix`, you must provide `meta.nixpkgs` which will
2020-come from an input.
2121-2222-::: code-group
2323-<<< @/snippets/getting-started/flake.nix [flake.nix]
2424-:::
2525-2626-```
2727-โฏ nix flake show
2828-git+file:///some/path
2929-โโโโcolmena: unknown
3030-```
3131-3232-## How to keep using `nixos-rebuild`
3333-3434-You can provide `makeHive` with your `nixosConfigurations` with the `inherit`
3535-nix keyword. `makeHive` will merge any nodes and nixosConfigurations that share
3636-the same name together.
3737-3838-::: tip
3939-It should be noted that there are a few downsides. For example, you cannot access `config.deployment` from `nixosConfigurations`. For this reason it would be best practice to limit configuration in `colmena` to simply defining keys and deployment options.
4040-:::
4141-4242-::: code-group
4343-<<< @/snippets/getting-started/flake-merged.nix [flake.nix]
4444-:::
4545-4646-Now, if we run `wire show`, you will see that wire only finds
4747-the `nixosConfigurations`-es that also match a node in the hive.
4848-4949-```
5050-โฏ nix run ~/Projects/wire#wire-small -- show
5151-Hive {
5252- nodes: {
5353- Name(
5454- "node-a",
5555- ): Node {
5656- target: Target {
5757- hosts: [
5858- "node-a",
5959- ],
6060- user: "root",
6161- port: 22,
6262- current_host: 0,
6363- },
6464- build_remotely: false,
6565- allow_local_deployment: true,
6666- tags: {},
6767- keys: [],
6868- host_platform: "x86_64-linux",
6969- },
7070- },
7171- schema: 0,
7272-}
7373-```
7474-7575-This way, you can continue using `nixos-rebuild` and wire at the same time.
-112
doc/guide/getting-started.md
···11----
22-comment: true
33-title: Getting Started
44-description: Getting started with Wire Tool!
55----
66-77-# {{ $frontmatter.title }}
88-99-## Installation
1010-1111-Wire can be heavy to compile. You should enable the substituter `wires.cachix.org`.
1212-1313-::: code-group
1414-1515-<<< @/snippets/getting-started/cache.nix [module.nix]
1616-<<< @/snippets/getting-started/nix.conf
1717-1818-:::
1919-2020-### Supported Nix & NixOS versions
2121-2222-Wire is currently _tested_ against `unstable`, `24.11` and `25.05`.
2323-For each channel, it is tested against the given channel's `pkgs.lix`.
2424-2525-There is currently a bug when our VM tests are ran with nixcpp. Nixcpp will try
2626-to download a file in a network sandbox, whereas Lix will not. We don't know
2727-how to solve it. Please see [#126](https://github.com/wires-org/wire/issues/126)
2828-2929-### NixOS / Home Manager
3030-3131-::: code-group
3232-3333-<<< @/snippets/getting-started/nixos.flake.nix [flake.nix (NixOS)]
3434-<<< @/snippets/getting-started/hm.flake.nix [flake.nix (Home Manager)]
3535-<<< @/snippets/getting-started/configuration.nix
3636-<<< @/snippets/getting-started/home.nix
3737-3838-:::
3939-4040-## Your First Hive
4141-4242-Wire groups your machines into _nodes_, which are NixOS configurations with
4343-additional information for deployment. Start by creating a `hive.nix` in the same directory as your
4444-`configuration.nix`.
4545-4646-::: info
4747-4848-To include wire in these examples, we are using
4949-[npins](https://github.com/andir/npins). To create this setup you
5050-would run `npins add github wires-org wire`.
5151-5252-:::
5353-5454-A `hive.nix` is an attribute set with NixOS configurations, each with a unique
5555-name. Add a node for your local machine:
5656-5757-```nix:line-numbers [hive.nix]
5858-let
5959- sources = import ./npins;
6060- wire = import sources.wire;
6161-in wire.makeHive {
6262- meta.nixpkgs = import sources.nixpkgs { };
6363-6464- my-local-machine = {
6565- imports = [./configuration.nix];
6666-6767- # If you don't know, find this value by running
6868- # `nix eval --expr 'builtins.currentSystem' --impure`
6969- nixpkgs.hostPlatform = "x86_64-linux";
7070- };
7171-}
7272-```
7373-7474-### A Remote Machine
7575-7676-Lets add another node to your hive! This one is an example of a remote machine.
7777-7878-```nix:line-numbers [hive.nix]
7979-let
8080- sources = import ./npins;
8181- wire = import sources.wire;
8282-in wire.makeHive {
8383- meta.nixpkgs = import sources.nixpkgs { };
8484-8585- my-local-machine = {
8686- imports = [./local-machine/configuration.nix];
8787- nixpkgs.hostPlatform = "x86_64-linux";
8888- };
8989-9090- my-remote-machine = {
9191- deployment = {
9292- # buildOnTarget defaults to `false`, enable this
9393- # if the machine is strong enough to build itself.
9494- buildOnTarget = true;
9595- target = {
9696- # Some IP or host that this node is reachable by ssh under,
9797- # defaults to "my-remote-machine" (node name).
9898- host = "10.1.1.2";
9999- # A user you can non-interactively login through ssh by,
100100- # defaults to "root".
101101- user = "root";
102102- };
103103- };
104104- imports = [./remote-machine/configuration.nix];
105105- nixpkgs.hostPlatform = "x86_64-linux";
106106- };
107107-}
108108-```
109109-110110-> [!TIP]
111111-> Read more options in [the reference](/reference/module#deployment-target) to adjust options such as
112112-> ssh port.
-56
doc/guide/hive-default.md
···11----
22-comment: true
33-title: hive.default
44-description: Deduplicate options with default node configuration.
55----
66-77-# `{{ $frontmatter.title }}`
88-99-{{ $frontmatter.description }}
1010-1111-## Introduction
1212-1313-At the top level of a hive wire reserves the `defaults` attribute. It's applied
1414-to every node.
1515-1616-::: warning
1717-1818-`defaults` must not rely on modules that a node imports, but a
1919-node may rely on modules that default imports.
2020-2121-:::
2222-2323-```nix:line-numbers [hive.nix]
2424-let
2525- sources = import ./npins;
2626- wire = import sources.wire;
2727-in wire.makeHive {
2828- meta.nixpkgs = import sources.nixpkgs { };
2929-3030- defaults = {
3131- # name of the node that defaults is being applied to
3232- name,
3333- # attribute set of all nodes
3434- nodes,
3535- ...
3636- }: {
3737- import = [
3838- ./default-module.nix
3939-4040- # module that is imported for all nodes
4141- some-flake.nixosModules.default
4242- ];
4343-4444- # default configuration
4545- # may or may not utilise `name` or `nodes`
4646- };
4747-4848- node-a = {
4949- # some config
5050- };
5151-5252- node-b = {
5353- # some more config
5454- };
5555-}
5656-```
-225
doc/guide/keys.md
···11----
22-comment: true
33-title: Secret Management
44-description: Keys, files, and other out-of-store paths with Wire Tool.
55----
66-77-# {{ $frontmatter.title }}
88-99-{{ $frontmatter.description }}
1010-1111-## Introduction
1212-1313-Wire Tool is very unopinionated as to how you encrypt your secrets, Wire only
1414-handles pushing and setting up permissions of your key files.
1515-1616-The `source` of your key can be a literal string (unencrypted), a path
1717-(unencrypted), or a command that wire runs to evaluate the key. Programs that
1818-work well with wire keys include:
1919-2020-- GPG
2121-- [Age](https://github.com/FiloSottile/age)
2222-- Anything that non-interactively decrypts to `stdout`.
2323-2424-### A Trivial "Key"
2525-2626-```nix:line-numbers [hive.nix]
2727-let
2828- sources = import ./npins;
2929- wire = import sources.wire;
3030-in wire.makeHive {
3131- meta.nixpkgs = import sources.nixpkgs { };
3232-3333- node-1 = {
3434- deployment.key."file.txt" = {
3535- source = ''
3636- Hello World!
3737- '';
3838- };
3939- };
4040-}
4141-```
4242-4343-```sh
4444-[user@node-1]$ cat /run/keys/file.txt
4545-Hello World!
4646-```
4747-4848-### Encrypting with GPG
4949-5050-```nix:line-numbers [hive.nix]
5151-let
5252- sources = import ./npins;
5353- wire = import sources.wire;
5454-in wire.makeHive {
5555- meta.nixpkgs = import sources.nixpkgs { };
5656-5757- node-1 = {
5858- deployment.key."file.txt" = {
5959- source = [
6060- "gpg"
6161- "--decrypt"
6262- "${./secrets/file.txt.gpg}"
6363- ];
6464- };
6565- };
6666-}
6767-```
6868-6969-```sh
7070-[user@node-1]$ cat /run/keys/file.txt
7171-Hello World!
7272-```
7373-7474-### Encrypting with KeepassXC
7575-7676-A simple example of extracting a KeepassXC attachment into a wire key.
7777-You must pass the password through stdin as the command must be non-interactive.
7878-Note that the `--stdout` is important as wire expects the command to output the key to stdout.
7979-8080-```nix:line-numbers [hive.nix]
8181-let
8282- sources = import ./npins;
8383- wire = import sources.wire;
8484-in wire.makeHive {
8585- meta.nixpkgs = import sources.nixpkgs { };
8686-8787- node-1 = {
8888- deployment.key."file.txt" = {
8989- source = [
9090- "bash"
9191- "-c"
9292- ''cat ~/pass | keepassxc-cli attachment-export --stdout ~/.local/share/keepass/database.kdbx test 'file.txt'''
9393- ];
9494- };
9595- };
9696-}
9797-```
9898-9999-```sh
100100-[user@node-1]$ cat /run/keys/file.txt
101101-Hello World!
102102-```
103103-104104-### A Plain Text File
105105-106106-```nix:line-numbers [hive.nix]
107107-let
108108- sources = import ./npins;
109109- wire = import sources.wire;
110110-in wire.makeHive {
111111- meta.nixpkgs = import sources.nixpkgs { };
112112-113113- node-1 = {
114114- deployment.key."file.txt" = {
115115- # using this syntax will enter the file into the store, readable by
116116- # anyone!
117117- source = ./file.txt;
118118- };
119119- };
120120-}
121121-```
122122-123123-## Persistence
124124-125125-Wire defaults `destDir` to `/run/keys`. `/run/` is held in memory and will not
126126-persist past reboot. Change
127127-[`deployment.key.<name>.destDir`](/reference/module#deployment-keys-name-destdir)
128128-to something like `/etc/keys` if you need secrets every time the machine boots.
129129-130130-## Upload Order
131131-132132-By default Wire will upload keys before the system is activated. You can
133133-force Wire to upload the key after the system is activated by setting
134134-[`deployment.keys.<name>.uploadAt`](/reference/module#deployment-keys-name-uploadat)
135135-to `post-activation`.
136136-137137-## Permissions and Ownership
138138-139139-Wire secrets are owned by user & group `root` (`0600`). You can change these
140140-with the `user` and `group` option.
141141-142142-```nix:line-numbers [hive.nix]
143143-let
144144- sources = import ./npins;
145145- wire = import sources.wire;
146146-in wire.makeHive {
147147- meta.nixpkgs = import sources.nixpkgs { };
148148-149149- node-1 = {
150150- deployment.key."file.txt" = {
151151- source = [
152152- "gpg"
153153- "--decrypt"
154154- "${./secrets/file.txt.gpg}"
155155- ];
156156-157157- user = "my-user";
158158- group = "my-group";
159159- };
160160- };
161161-}
162162-```
163163-164164-## Further Examples
165165-166166-### Using Keys With Services
167167-168168-You can access the full absolute path of any key with
169169-`config.deployment.keys.<name>.path` (auto-generated and read-only).
170170-Here's an example with the Tailscale service:
171171-172172-```nix:line-numbers [hive.nix]
173173-let
174174- sources = import ./npins;
175175- wire = import sources.wire;
176176-in wire.makeHive {
177177- meta.nixpkgs = import sources.nixpkgs { };
178178-179179- node-1 = {config, ...}: {
180180- services.tailscale = {
181181- enable = true;
182182- # use deployment key path directly
183183- authKeyFile = config.deployment.keys."tailscale.key".path;
184184- };
185185-186186- deployment.keys."tailscale.key" = {
187187- keyCommand = ["gpg" "--decrypt" "${./secrets/tailscale.key.gpg}"];
188188- };
189189- };
190190-}
191191-```
192192-193193-### Scoping a Key to a service account
194194-195195-Additionally you can scope the key to the user that the service runs under, to
196196-further reduce duplication using the `config` argument. Here's an example of
197197-providing a certificate that is only readable by the caddy service.
198198-199199-```nix:line-numbers [hive.nix]
200200-let
201201- sources = import ./npins;
202202- wire = import sources.wire;
203203-in wire.makeHive {
204204- meta.nixpkgs = import sources.nixpkgs { };
205205-206206- some-web-server = {config, ...}: {
207207- deployment.keys."some.host.pem" = {
208208- keyCommand = ["gpg" "--decrypt" "${./some.host.pem.gpg}"];
209209- destDir = "/etc/keys";
210210-211211- # inherit the user and group that caddy runs under
212212- # the key will only readable by the caddy service
213213- inherit (config.services.caddy) user group;
214214- };
215215-216216- # ^^ repeat for `some.host.key`
217217-218218- services.caddy = {
219219- virtualHosts."https://some.host".extraConfig = ''
220220- tls ${config.deployment.keys."some.host.pem".path} ${config.deployment.keys."some.host.key".path}
221221- '';
222222- };
223223- };
224224-}
225225-```
-3
doc/guide/magic-rollback.md
···11-# Magic Rollback
22-33-Magic Rollback is unimplemented.
-32
doc/guide/parallelism.md
···11----
22-comment: true
33-title: Parallelism
44-description: A deeper dive into parallelism with Wire Tool.
55----
66-77-# {{ $frontmatter.title }}
88-99-{{ $frontmatter.description }}
1010-1111-## Controlling CPU Usage
1212-1313-Wire evaluates, builds, pushes, and deploys each node completely independently
1414-from each other. Internally Wire calls this process a "node execution".
1515-1616-The default number of parallel _node executions_ is `10`, which can be
1717-controlled with the `-p` / `--parallel` argument.
1818-1919-```sh
2020-wire apply -p <NUMBER>
2121-```
2222-2323-## Interaction with Nix's `max-jobs`
2424-2525-Nix has an overall derivation build limit and core limit.
2626-If executing a node fills Nix's `max-jobs` all other nodes will bottleneck. You
2727-should read [the relevant
2828-documentation](https://nix.dev/manual/nix/2.28/advanced-topics/cores-vs-jobs) to fine tune these settings.
2929-3030-When a Node is built remotely due to
3131-[`deployment.buildOnTarget`](/reference/module.html#deployment-buildontarget)
3232-that node will not push up the _local machine's_ max-jobs limit.
···11----
22-comment: true
33-title: Targeting Nodes
44-description: Tags, nodes, and how to target them with Wire Tool.
55----
66-77-# {{ $frontmatter.title }}
88-99-{{ $frontmatter.description }}
1010-1111-## Targeting Specific Nodes
1212-1313-`wire apply --on` without an `@` prefix interprets as a literal node name. For
1414-example:
1515-1616-```sh
1717-wire apply switch --on node-a,node-b
1818-```
1919-2020-Will switch-to-configuration on node a, and node b.
2121-2222-## Tag Basics
2323-2424-Nodes can have _tags_, which allows you to easily target multiple, related
2525-nodes for deployment.
2626-2727-```nix:line-numbers{9,13,17,21} [hive.nix]
2828-let
2929- sources = import ./npins;
3030- wire = import sources.wire;
3131-in wire.makeHive {
3232- meta.nixpkgs = import sources.nixpkgs { };
3333-3434- node-1 = {
3535- # ...
3636- deployment.tags = ["cloud"];
3737- };
3838- node-2 = {
3939- # ...
4040- deployment.tags = ["cloud", "virtual"];
4141- };
4242- node-3 = {
4343- # ...
4444- deployment.tags = ["on-prem"];
4545- };
4646- node-4 = {
4747- # ...
4848- deployment.tags = ["virtual"];
4949- };
5050- node-5 = {
5151- # Untagged
5252- };
5353-}
5454-```
5555-5656-To target all nodes with a specific tag, prefix tags with an `@`.
5757-For example, to deploy only nodes with the `cloud` tag, use
5858-5959-```sh
6060-wire apply --on @cloud
6161-```
6262-6363-## Further Examples
6464-6565-::: info
6666-6767-Other operations such as an `--ignore` argument are unimplemented as of wire `v0.2.0`.
6868-6969-:::
7070-7171-### Mixing Tags with Node Names
7272-7373-You can mix tags and node names with `--on`:
7474-7575-```sh
7676-wire apply --on @cloud node-5
7777-```
7878-7979-This will deploy all nodes in `@cloud`, alongside the node `node-5`.
8080-8181-### Targeting Many Tags (Union)
8282-8383-You can specify many tags together:
8484-8585-```sh
8686-wire apply --on @cloud @on-prem
8787-```
8888-8989-This is a union between `@cloud` and `@on-prem`.
-49
doc/guide/wire.md
···11----
22-comment: true
33----
44-55-# What is Wire?
66-77-<p style="display: flex; gap: 8px">
88- <a href="https://github.com/wires-org/wire/actions/workflows/test.yml?query=branch%3Amain">
99- <img alt="Rust Tests Status" src="https://img.shields.io/github/actions/workflow/status/wires-org/wire/test.yml?branch=main&style=flat-square&label=Rust%20Tests">
1010- </a>
1111-1212- <a href="https://hydra.althaea.zone/jobset/wire/main">
1313- <img alt="BuildBot Build & VM Test Status" src="https://img.shields.io/github/checks-status/wires-org/wire/main?style=flat-square&label=BuildBot%20Build%20%26%20VM%20Tests">
1414- </a>
1515-1616- <a href="https://github.com/wires-org/wire/actions/workflows/pages.yml?query=branch%3Amain">
1717- <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">
1818- </a>
1919-</p>
2020-2121-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.
2222-2323-[^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.
2424-2525-::: warning
2626-Wire is alpha software, please use at your own risk. Many features listed in this documentation may not be complete / implemented.
2727-:::
2828-2929-<div class="tip custom-block" style="padding-top: 8px">
3030-3131-Ready? Skip to the [Quickstart](./getting-started).
3232-3333-</div>
3434-3535-## Why Wire?
3636-3737-::: info
3838-The following is the goal for a stable release and not fully implemented.
3939-:::
4040-4141-| Features | Wire | Colmena |
4242-| --------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------- |
4343-| Secret Management | :white_check_mark: | :white_check_mark: |
4444-| Parallel Evaluation | :white_check_mark: | [Experimental](https://colmena.cli.rs/unstable/features/parallelism.html#parallel-evaluation-experimental) |
4545-| Node Tagging | :white_check_mark: | :white_check_mark: |
4646-| `jq` pipeline support | :white_check_mark: | :x:[^2] |
4747-| Magic Rollback | :white_check_mark: (Planned) | :x: |
4848-4949-[^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.
+83
doc/guides/apply.md
···11+---
22+comment: true
33+title: Apply your Config
44+description: How to apply a node with wire.
55+---
66+77+# Apply your Config
88+99+{{ $frontmatter.description }}
1010+1111+## What does it mean to 'apply'?
1212+1313+Once you have created a hive, you can now "apply" your
1414+configuration to nodes in your hive. Simply, "applying" is the term used by wire to describe **deploying the
1515+config**.
1616+1717+::: info
1818+Applying a node typically involves pushing keys,
1919+evaluating the node's NixOS system, building the node's NixOS system, and running
2020+`switch-to-configuration`, depending on which specific goal is used.
2121+:::
2222+2323+The simplest way to apply is simply running:
2424+2525+```sh
2626+$ wire apply switch
2727+```
2828+2929+Which will `switch` to each node's NixOS system in your hive and push
3030+secrets (the equivalent to `nixos-rebuild`'s `nixos-rebuild switch`).
3131+3232+## Apply goals
3333+3434+`wire apply` accepts a goal, which include verbs which will be familiar to
3535+`nixos-rebuild` users such as `switch`, `boot`, and `test`, alongside additional verbs
3636+like `keys` and `push`.
3737+3838+### `wire apply keys`
3939+4040+wire will push all deployment keys to nodes, and do nothing else. While running
4141+this goal, option
4242+[`deployment.keys.<name>.uploadAt`](/reference/module#deployment-keys-name-uploadat)
4343+has no effect and all keys will be pushed. Read [the secret management guide](./keys)
4444+to learn more about wire deployment keys.
4545+4646+### `wire apply push`
4747+4848+wire will "push" (equivalent to [`nix
4949+copy`](https://nix.dev/manual/nix/2.18/command-ref/new-cli/nix3-copy)) the
5050+`.drv` file that can produce the node's NixOS system when built.
5151+5252+### `wire apply build`
5353+5454+Sister to `wire apply push`, wire will build the
5555+node's NixOS system and ensure the output path exists on the node. Depending on
5656+[`deployment.buildOnTarget`](/reference/module#deployment-buildontarget), the
5757+`.drv` file may be built on the machine invoking wire or the node itself.
5858+5959+### `wire apply [switch|boot|test|dry-activate]`
6060+6161+Type `wire apply --help` or
6262+[read the reference](../reference/cli#wire-apply) to read more.
6363+6464+## Applying locally
6565+6666+If `deployment.allowLocalDeployment` is `true`, and the machine invoking wire's
6767+host name is equivalent to a node's name, wire will apply that node to the local
6868+machine. Goals like `push` and `build`, wont actually "push" anything as
6969+the paths already exists on the local machine.
7070+7171+When applying to your local machine, wire can interactively run `sudo`!
7272+wire will prompt for your password, meaning wire can be ran as any user in
7373+the `wheel` group.
7474+7575+## Applying specific nodes
7676+7777+Use the `--on` argument to specify which nodes in your hive to apply:
7878+7979+```sh
8080+$ wire apply --on node-a
8181+```
8282+8383+Further examples, including how you can utilise tags, can be found on the [Targeting Nodes](./targeting) page.
+36
doc/guides/build-in-ci.md
···11+---
22+comment: true
33+title: Build in CI
44+---
55+66+# Build in CI
77+88+## The `wire build` command <Badge type="tip" text="^1.1.0" />
99+1010+`wire build` builds nodes locally. It is distinct from
1111+`wire apply build`, as it will not ping or push the result,
1212+making it useful for CI.
1313+1414+It accepts the same `--on` argument as `wire apply` does.
1515+1616+## Partitioning builds
1717+1818+`wire build` accepts a `--partition` option inspired by
1919+[cargo-nextest](https://nexte.st/docs/ci-features/partitioning/), which splits
2020+selected nodes into buckets to be built separately.
2121+2222+It accepts values in the format `--partition current/total`, where 1 โค current โค total.
2323+2424+For example, these two commands will build the entire hive in two invocations:
2525+2626+```sh
2727+wire build --partition 1/2
2828+2929+# later or synchronously:
3030+3131+wire build --partition 2/2
3232+```
3333+3434+## Example: Build in Github Actions
3535+3636+<<< @/snippets/guides/example-action.yml [.github/workflows/build.yml]
+42
doc/guides/flakes/nixos-rebuild.md
···11+---
22+comment: true
33+title: Keep Using nixos-rebuild
44+description: How to combine outputs.nixosConfigurations with outputs.wire
55+---
66+77+# Keep Using nixos-rebuild
88+99+{{ $frontmatter.description }}
1010+1111+## An Example
1212+1313+You can provide `makeHive` with your `nixosConfigurations` with the `inherit`
1414+nix keyword. `makeHive` will merge any nodes and nixosConfigurations that share
1515+the same name together.
1616+1717+::: tip
1818+You should include the wire module, which will provide the `deployment` options, even if nixos-rebuild can't directly use them.
1919+:::
2020+2121+::: code-group
2222+<<< @/snippets/getting-started/flake-merged.nix [flake.nix]
2323+:::
2424+2525+Now, if we run `wire show`, you will see that wire only finds
2626+the `nixosConfigurations`-es that also match a node in the hive.
2727+`some-other-host` is not included in the hive unless specified in `makeHive`.
2828+2929+```
3030+$ wire show
3131+Node node-a (x86_64-linux):
3232+3333+ > Connection: {root@node-a:22}
3434+ > Build remotely `deployment.buildOnTarget`: false
3535+ > Local apply allowed `deployment.allowLocalDeployment`: true
3636+3737+Summary: 1 total node(s), totalling 0 keys (0 distinct).
3838+Note: Listed connections are tried from Left to Right
3939+4040+```
4141+4242+This way, you can continue using `nixos-rebuild` and wire at the same time.
+40
doc/guides/flakes/overview.md
···11+---
22+comment: true
33+title: Use Flakes
44+description: How to output a hive from a flake.
55+---
66+77+# Use Flakes
88+99+{{ $frontmatter.description }}
1010+1111+## Output a hive
1212+1313+::: tip
1414+If you have skipped ahead, please read the previous page to understand the
1515+concept of a hive.
1616+:::
1717+1818+You can use wire with a flake by outputting a hive with the `wire` flake output.
1919+Just like when using a `hive.nix`, you must provide `meta.nixpkgs` which will
2020+come from an input.
2121+2222+::: code-group
2323+<<< @/snippets/getting-started/flake.nix [flake.nix]
2424+:::
2525+2626+```
2727+$ nix flake show
2828+git+file:///some/path
2929+โโโโwire: unknown
3030+3131+$ wire show
3232+Node node-a (x86_64-linux):
3333+3434+ > Connection: {root@node-a:22}
3535+ > Build remotely `deployment.buildOnTarget`: false
3636+ > Local apply allowed `deployment.allowLocalDeployment`: true
3737+3838+Summary: 1 total node(s), totalling 0 keys (0 distinct).
3939+Note: Listed connections are tried from Left to Right
4040+```
+56
doc/guides/hive-default.md
···11+---
22+comment: true
33+title: Use hive.default
44+description: Deduplicate options with default node configuration.
55+---
66+77+# `Use hive.default`
88+99+{{ $frontmatter.description }}
1010+1111+## Introduction
1212+1313+At the top level of a hive wire reserves the `defaults` attribute. It's applied
1414+to every node.
1515+1616+::: warning
1717+1818+`defaults` must not rely on modules that a node imports, but a
1919+node may rely on modules that default imports.
2020+2121+:::
2222+2323+```nix:line-numbers [hive.nix]
2424+let
2525+ sources = import ./npins;
2626+ wire = import sources.wire;
2727+in wire.makeHive {
2828+ meta.nixpkgs = import sources.nixpkgs { };
2929+3030+ defaults = {
3131+ # name of the node that defaults is being applied to
3232+ name,
3333+ # attribute set of all nodes
3434+ nodes,
3535+ ...
3636+ }: {
3737+ import = [
3838+ ./default-module.nix
3939+4040+ # module that is imported for all nodes
4141+ some-flake.nixosModules.default
4242+ ];
4343+4444+ # default configuration
4545+ # may or may not utilise `name` or `nodes`
4646+ };
4747+4848+ node-a = {
4949+ # some config
5050+ };
5151+5252+ node-b = {
5353+ # some more config
5454+ };
5555+}
5656+```
+60
doc/guides/installation.md
···11+---
22+comment: true
33+title: Install wire
44+description: How to install wire tool.
55+---
66+77+# Install wire
88+99+{{ $frontmatter.description }}
1010+1111+::: info
1212+1313+The `wire` binary and the `wire.makeHive` function are tightly coupled, so it is
1414+recommended that you use the same version for both.
1515+1616+:::
1717+1818+It is recommended you stick to either using a tagged version of wire, or the `stable` branch which tracks the latest stable tag.
1919+2020+## Binary Cache
2121+2222+You should enable the [garnix binary cache](https://garnix.io/docs/caching) _before_
2323+continuing otherwise you will be compiling from source:
2424+2525+::: code-group
2626+<<< @/snippets/tutorial/cache.conf [nix.conf]
2727+<<< @/snippets/tutorial/cache.nix [configuration.nix]
2828+:::
2929+3030+## Installation through flakes
3131+3232+When using flakes, you should install wire through the same input you create
3333+your hive from, sourced from the `stable` branch.
3434+3535+::: code-group
3636+<<< @/snippets/guides/installation/flake.nix [flake.nix]
3737+:::
3838+3939+## Installation through npins
4040+4141+With npins you may allow it to use release tags instead of the `stable`
4242+branch.
4343+4444+Using npins specifically is not required, you can pin your sources in any way
4545+you'd like, really.
4646+4747+```sh
4848+$ npins add github forallsys wire --branch stable
4949+```
5050+5151+Alternatively, you can use a tag instead:
5252+5353+```sh
5454+$ npins add github forallsys wire --at v1.1.1
5555+```
5656+5757+Then, use this pinned version of wire for both your `hive.nix` and `shell.nix`:
5858+5959+<<< @/snippets/guides/installation/shell.nix{8} [shell.nix]
6060+<<< @/snippets/guides/installation/hive.nix [hive.nix]
+259
doc/guides/keys.md
···11+---
22+comment: true
33+title: Manage Secrets
44+description: Manage keys, secrets, files, and other out-of-store paths with wire Tool.
55+---
66+77+# Manage Secrets
88+99+{{ $frontmatter.description }}
1010+1111+## Introduction
1212+1313+wire Tool is very unopinionated as to how you encrypt your secrets, wire only
1414+handles pushing and setting up permissions of your key files.
1515+1616+The `source` of your key can be a literal string (unencrypted), a path
1717+(unencrypted), or a command that wire runs to evaluate the key. Programs that
1818+work well with wire keys include:
1919+2020+- GPG
2121+- [Age](https://github.com/FiloSottile/age)
2222+- Anything that non-interactively decrypts to `stdout`.
2323+2424+### Prerequisites
2525+2626+wire uses a Rust binary to receive encrypted key data, so your deploying
2727+user must be trusted or you must add garnix as a trusted public key:
2828+2929+```nix
3030+{ config, ... }:
3131+{
3232+ nix.settings.trusted-users = [
3333+ config.deployment.target.user # [!code ++]
3434+ ];
3535+}
3636+```
3737+3838+Otherwise, you may see errors such as:
3939+4040+```
4141+error: cannot add path '/nix/store/...-wire-tool-key_agent-x86_64-linux-...' because it lacks a signature by a trusted key
4242+```
4343+4444+This is a requirement because `nix copy` is used to copy the binary.
4545+As a benefit to this approach, key deployments are significantly faster!
4646+4747+### A Trivial "Key"
4848+4949+```nix:line-numbers [hive.nix]
5050+let
5151+ sources = import ./npins;
5252+ wire = import sources.wire;
5353+in wire.makeHive {
5454+ meta.nixpkgs = import sources.nixpkgs { };
5555+5656+ node-1 = {
5757+ deployment.key."file.txt" = {
5858+ source = ''
5959+ Hello World!
6060+ '';
6161+ };
6262+ };
6363+}
6464+```
6565+6666+```sh
6767+[user@node-1]$ cat /run/keys/file.txt
6868+Hello World!
6969+```
7070+7171+### Encrypting with GPG
7272+7373+```nix:line-numbers [hive.nix]
7474+let
7575+ sources = import ./npins;
7676+ wire = import sources.wire;
7777+in wire.makeHive {
7878+ meta.nixpkgs = import sources.nixpkgs { };
7979+8080+ node-1 = {
8181+ deployment.key."file.txt" = {
8282+ source = [
8383+ "gpg"
8484+ "--decrypt"
8585+ "${./secrets/file.txt.gpg}"
8686+ ];
8787+ };
8888+ };
8989+}
9090+```
9191+9292+```sh
9393+[user@node-1]$ cat /run/keys/file.txt
9494+Hello World!
9595+```
9696+9797+### Encrypting with KeepassXC
9898+9999+A simple example of extracting a KeepassXC attachment into a wire key.
100100+You must pass the password through stdin as the command must be non-interactive.
101101+Note that the `--stdout` is important as wire expects the command to output the key to stdout.
102102+103103+```nix:line-numbers [hive.nix]
104104+let
105105+ sources = import ./npins;
106106+ wire = import sources.wire;
107107+in wire.makeHive {
108108+ meta.nixpkgs = import sources.nixpkgs { };
109109+110110+ node-1 = {
111111+ deployment.key."file.txt" = {
112112+ source = [
113113+ "bash"
114114+ "-c"
115115+ ''cat ~/pass | keepassxc-cli attachment-export --stdout ~/.local/share/keepass/database.kdbx test 'file.txt'''
116116+ ];
117117+ };
118118+ };
119119+}
120120+```
121121+122122+```sh
123123+[user@node-1]$ cat /run/keys/file.txt
124124+Hello World!
125125+```
126126+127127+### A Plain Text File
128128+129129+```nix:line-numbers [hive.nix]
130130+let
131131+ sources = import ./npins;
132132+ wire = import sources.wire;
133133+in wire.makeHive {
134134+ meta.nixpkgs = import sources.nixpkgs { };
135135+136136+ node-1 = {
137137+ deployment.key."file.txt" = {
138138+ # using this syntax will enter the file into the store, readable by
139139+ # anyone!
140140+ source = ./file.txt;
141141+ };
142142+ };
143143+}
144144+```
145145+146146+## Persistence
147147+148148+wire defaults `destDir` to `/run/keys`. `/run/` is held in memory and will not
149149+persist past reboot. Change
150150+[`deployment.key.<name>.destDir`](/reference/module#deployment-keys-name-destdir)
151151+to something like `/etc/keys` if you need secrets every time the machine boots.
152152+153153+## Upload Order
154154+155155+By default wire will upload keys before the system is activated. You can
156156+force wire to upload the key after the system is activated by setting
157157+[`deployment.keys.<name>.uploadAt`](/reference/module#deployment-keys-name-uploadat)
158158+to `post-activation`.
159159+160160+## Permissions and Ownership
161161+162162+wire secrets are owned by user & group `root` (`0600`). You can change these
163163+with the `user` and `group` option.
164164+165165+```nix:line-numbers [hive.nix]
166166+let
167167+ sources = import ./npins;
168168+ wire = import sources.wire;
169169+in wire.makeHive {
170170+ meta.nixpkgs = import sources.nixpkgs { };
171171+172172+ node-1 = {
173173+ deployment.key."file.txt" = {
174174+ source = [
175175+ "gpg"
176176+ "--decrypt"
177177+ "${./secrets/file.txt.gpg}"
178178+ ];
179179+180180+ user = "my-user";
181181+ group = "my-group";
182182+ };
183183+ };
184184+}
185185+```
186186+187187+## Further Examples
188188+189189+### Using Keys With Services
190190+191191+You can access the full absolute path of any key with
192192+`config.deployment.keys.<name>.path` (auto-generated and read-only).
193193+194194+Keys also have a `config.deployment.keys.<name>.service` property
195195+(auto-generated and read-only), which represent systemd services that you can
196196+`require`, telling systemd there is a hard-dependency on that key for the
197197+service to run.
198198+199199+Here's an example with the Tailscale service:
200200+201201+```nix:line-numbers [hive.nix]
202202+let
203203+ sources = import ./npins;
204204+ wire = import sources.wire;
205205+in wire.makeHive {
206206+ meta.nixpkgs = import sources.nixpkgs { };
207207+208208+ node-1 = {config, ...}: {
209209+ services.tailscale = {
210210+ enable = true;
211211+ # use deployment key path directly
212212+ authKeyFile = config.deployment.keys."tailscale.key".path;
213213+ };
214214+215215+ deployment.keys."tailscale.key" = {
216216+ keyCommand = ["gpg" "--decrypt" "${./secrets/tailscale.key.gpg}"];
217217+ };
218218+219219+ # The service will not start unless the key exists.
220220+ systemd.services.tailscaled-autoconnect.requires = [
221221+ config.deployment.keys."tailscale.key".service
222222+ ];
223223+ };
224224+}
225225+```
226226+227227+### Scoping a Key to a service account
228228+229229+Additionally you can scope the key to the user that the service runs under, to
230230+further reduce duplication using the `config` argument. Here's an example of
231231+providing a certificate that is only readable by the caddy service.
232232+233233+```nix:line-numbers [hive.nix]
234234+let
235235+ sources = import ./npins;
236236+ wire = import sources.wire;
237237+in wire.makeHive {
238238+ meta.nixpkgs = import sources.nixpkgs { };
239239+240240+ some-web-server = {config, ...}: {
241241+ deployment.keys."some.host.pem" = {
242242+ keyCommand = ["gpg" "--decrypt" "${./some.host.pem.gpg}"];
243243+ destDir = "/etc/keys";
244244+245245+ # inherit the user and group that caddy runs under
246246+ # the key will only readable by the caddy service
247247+ inherit (config.services.caddy) user group;
248248+ };
249249+250250+ # ^^ repeat for `some.host.key`
251251+252252+ services.caddy = {
253253+ virtualHosts."https://some.host".extraConfig = ''
254254+ tls ${config.deployment.keys."some.host.pem".path} ${config.deployment.keys."some.host.key".path}
255255+ '';
256256+ };
257257+ };
258258+}
259259+```
+88
doc/guides/migrate.md
···11+---
22+comment: true
33+title: Migrate to wire
44+description: How-to migrate from other tools to wire tool.
55+---
66+77+# Migrate to wire
88+99+{{ $frontmatter.description }}
1010+1111+Migrate from...
1212+1313+- [Colmena](#from-colmena)
1414+- [`nixos-rebuild`](#from-nixos-rebuild)
1515+1616+## From Colmena
1717+1818+If you're familiar with colmena, wire will hopefully come quickly to you! (or,
1919+atleast that was the intention when writing it!). There are a few changes you
2020+should know:
2121+2222+- [You don't have to use a root user](/guides/non-root-user.html)
2323+- `apply-local` does not exist, `apply` will apply locally when appropriate
2424+- [Many options have been aliased to nicer names](/reference/module.html)
2525+ (ie, `deployment.targetUser` <=> `deployment.target.user`)
2626+- You may pass a list of hosts to `deployment.targetHost` (no more fiddling with
2727+ your hive whenever DNS is down, for example)
2828+- `--path` optionally takes a flakeref! You can pass `--path github:foo/bar`,
2929+ `--path git+file:///...`, `--path https://.../main.tar.gz`, etc.
3030+ (plain paths like `--path ~/my-hive` still work as always)
3131+3232+::: tip
3333+You should also follow [installation](/guides/installation) to install the
3434+binary.
3535+:::
3636+3737+### Convert a Hive as a Flake
3838+3939+```nix [flake.nix]
4040+{
4141+ inputs = {
4242+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
4343+ colmena.url = "github:zhaofengli/colmena"; # [!code --]
4444+ wire.url = "github:forallsys/wire/stable"; # [!code ++]
4545+ };
4646+ outputs =
4747+ { nixpkgs, colmena, ... }:
4848+ {
4949+ colmenaHive = colmena.lib.makeHive { # [!code --]
5050+ wire = wire.lib.makeHive { # [!code ++]
5151+ # ..
5252+ };
5353+ };
5454+}
5555+```
5656+5757+### Convert a Hive with npins
5858+5959+::: tip
6060+You should also follow [installation](/guides/installation) to setup
6161+npins and install the binary.
6262+:::
6363+6464+Unlike colmena, you must call `makeHive` directly even in non-flake hives.
6565+6666+```nix [hive.nix]
6767+let
6868+ sources = import ./npins;
6969+ wire = import sources.wire;
7070+in
7171+{ # [!code --]
7272+wire.makeHive { # [!code ++]
7373+7474+ meta.nixpkgs = <nixpkgs>; # [!code --]
7575+ meta.nixpkgs = import sources.nixpkgs { }; # [!code ++]
7676+7777+ # ...
7878+}
7979+```
8080+8181+Replacing `<nixpkgs>` with a pinned source is optional, but you should
8282+probably use one if you ask me \:)
8383+8484+## From `nixos-rebuild`
8585+8686+You can keep using `nixos-rebuild` alongside wire!
8787+8888+Follow the instructions in [the relevant page](/guides/flakes/nixos-rebuild.html).
+78
doc/guides/non-root-user.md
···11+---
22+comment: true
33+title: Use a non-root user
44+description: Deploy without root permissions with wire.
55+---
66+77+# Use a non-root user
88+99+{{ $frontmatter.description }}
1010+1111+## Deploying User Requirements
1212+1313+For deployment commands to succeed, the user defined in `deployment.target.user` must meet the following criteria:
1414+1515+1. Essential Config
1616+1717+- **Sudo Access**: The user must be `wheel` (A sudo user)
1818+- **SSH Key Authentication**: The user must be authenticated through SSH keys,
1919+ and password-based SSH auth is not supported.
2020+2121+ **Why?** Wire can prompt you for your `sudo` password, but not your `ssh` password.
2222+2323+2. Deploying with Secrets
2424+2525+- **Trusted User**: The user must be listed in the `trusted-users` nix config.
2626+2727+ If the user is not trusted, wire will fail in the key deployment stage.
2828+2929+For setting up a trusted user, see [Manage Secrets - Prerequisites](/guides/keys.html#prerequisites).
3030+3131+## Changing the user
3232+3333+By default, the target is set to root:
3434+3535+```nix
3636+{
3737+ deployment.target.user = "root";
3838+}
3939+```
4040+4141+But it can be any user you want so long as it fits the requirements above.
4242+4343+```nix
4444+{
4545+ deployment.target.user = "root"; # [!code --]
4646+ deployment.target.user = "deploy-user"; # [!code ++]
4747+}
4848+```
4949+5050+After this change, wire will prompt you for sudo authentication, and tell you
5151+the exact command wire wants privileged:
5252+5353+```sh{6}
5454+$ wire apply keys --on media
5555+ INFO eval_hive: evaluating hive Flake("/path/to/hive")
5656+...
5757+ INFO media | step="Upload key @ NoFilter" progress="3/4"
5858+deploy-user@node:22 | Authenticate for "sudo /nix/store/.../bin/key_agent":
5959+[sudo] password for deploy-user:
6060+```
6161+6262+## Using alternative privilege escalation
6363+6464+You may change the privilege escalation command with the
6565+[deployment.privilegeEscalationCommand](/reference/module.html#deployment-privilegeescalationcommand)
6666+option.
6767+6868+For example, doas:
6969+7070+```nix
7171+{
7272+ deployment.privilegeEscalationCommand = [
7373+ "sudo" # [!code --]
7474+ "--" # [!code --]
7575+ "doas" # [!code ++]
7676+ ];
7777+}
7878+```
+32
doc/guides/parallelism.md
···11+---
22+comment: true
33+title: Use Parallelism
44+description: How to use parallelism with wire Tool.
55+---
66+77+# Use Parallelism
88+99+{{ $frontmatter.description }}
1010+1111+## Controlling CPU Usage
1212+1313+wire evaluates, builds, pushes, and deploys each node completely independently
1414+from each other. Internally wire calls this process a "node execution".
1515+1616+The default number of parallel _node executions_ is `10`, which can be
1717+controlled with the `-p` / `--parallel` argument.
1818+1919+```sh
2020+$ wire apply -p <NUMBER>
2121+```
2222+2323+## Interaction with Nix's `max-jobs`
2424+2525+Nix has an overall derivation build limit and core limit.
2626+If executing a node fills Nix's `max-jobs` all other nodes will bottleneck. You
2727+should read [the relevant
2828+documentation](https://nix.dev/manual/nix/2.28/advanced-topics/cores-vs-jobs) to fine tune these settings.
2929+3030+When a Node is built remotely due to
3131+[`deployment.buildOnTarget`](/reference/module.html#deployment-buildontarget)
3232+that node will not push up the _local machine's_ max-jobs limit.
+102
doc/guides/targeting.md
···11+---
22+comment: true
33+title: Target Nodes
44+description: Tags, nodes, and how to target them with wire Tool.
55+---
66+77+# Target Nodes
88+99+{{ $frontmatter.description }}
1010+1111+## Targeting Specific Nodes
1212+1313+`wire apply --on` without an `@` prefix interprets as a literal node name. For
1414+example:
1515+1616+```sh
1717+$ wire apply switch --on node-a,node-b
1818+```
1919+2020+Will switch-to-configuration on node a, and node b.
2121+2222+## Reading from Stdin
2323+2424+Passing `--on -` will read whitespace-separated nodes and tags from stdin. This
2525+can be combined with normal `--on` usage.
2626+2727+For example:
2828+2929+```sh
3030+$ echo "node-a node-b" | wire apply --on @other --on -
3131+```
3232+3333+Will apply on `node-a`, `node-b`, and all nodes with the tag `@other`.
3434+3535+## Tag Basics
3636+3737+Nodes can have _tags_, which allows you to easily target multiple, related
3838+nodes for deployment.
3939+4040+```nix:line-numbers{9,13,17,21} [hive.nix]
4141+let
4242+ sources = import ./npins;
4343+ wire = import sources.wire;
4444+in wire.makeHive {
4545+ meta.nixpkgs = import sources.nixpkgs { };
4646+4747+ node-1 = {
4848+ # ...
4949+ deployment.tags = ["cloud"];
5050+ };
5151+ node-2 = {
5252+ # ...
5353+ deployment.tags = ["cloud", "virtual"];
5454+ };
5555+ node-3 = {
5656+ # ...
5757+ deployment.tags = ["on-prem"];
5858+ };
5959+ node-4 = {
6060+ # ...
6161+ deployment.tags = ["virtual"];
6262+ };
6363+ node-5 = {
6464+ # Untagged
6565+ };
6666+}
6767+```
6868+6969+To target all nodes with a specific tag, prefix tags with an `@`.
7070+For example, to deploy only nodes with the `cloud` tag, use
7171+7272+```sh
7373+$ wire apply --on @cloud
7474+```
7575+7676+## Further Examples
7777+7878+::: info
7979+8080+Other operations such as an `--ignore` argument are unimplemented as of wire `v0.2.0`.
8181+8282+:::
8383+8484+### Mixing Tags with Node Names
8585+8686+You can mix tags and node names with `--on`:
8787+8888+```sh
8989+$ wire apply --on @cloud --on node-5
9090+```
9191+9292+This will deploy all nodes in `@cloud`, alongside the node `node-5`.
9393+9494+### Targeting Many Tags (Union)
9595+9696+You can specify many tags together:
9797+9898+```sh
9999+$ wire apply --on @cloud @on-prem
100100+```
101101+102102+This is a union between `@cloud` and `@on-prem`.
+116
doc/guides/writing-a-hive.md
···11+---
22+comment: true
33+title: Write a Hive
44+---
55+66+# Write a Hive
77+88+## Anatomy of a Hive
99+1010+A "Hive" is the attribute set that you pass to `wire.makeHive`. It has the
1111+following layout:
1212+1313+```nix
1414+wire.makeHive {
1515+ # `meta`
1616+ # type: attrset
1717+ meta = {
1818+ # `meta.nixpkgs` tells wire how to get nixpkgs.
1919+ # type: "A path or an instance of nixpkgs."
2020+ nixpkgs = <nixpkgs>;
2121+2222+ # `meta.specialArgs` are specialArgs to pass to each node & default
2323+ # type: attrset
2424+ specialArgs = { };
2525+2626+ # `meta.nodeSpecialArgs` lets you override `meta.specialArgs` per-node.
2727+ # type: attrset of attrset
2828+ nodeSpecialArgs: = { };
2929+3030+ # `meta.nodeNixpkgs` lets you override nixpkgs per-node.
3131+ # type: attrset of "A path or an instance of nixpkgs."
3232+ nodeNixpkgs: = { };
3333+ };
3434+3535+ # `defaults` is a module applied to every node
3636+ # type: NixOS Module
3737+ defaults = { ... }: { };
3838+3939+ # Any other attributes are nodes.
4040+ <node-name> = { ... }: { };
4141+}
4242+```
4343+4444+### `<node-name>`
4545+4646+Other attributes are NixOs modules that describe a system. They automatically
4747+have `defaults` and the wire NixOS module imported.
4848+4949+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.
5050+5151+### `meta`
5252+5353+There is more detailed information about `meta` in [the
5454+reference](/reference/meta.html).
5555+5656+### `defaults`
5757+5858+De-duplicate options with default node configuration.
5959+6060+At the top level of a hive wire reserves the `defaults` attribute. It's applied
6161+to every node.
6262+6363+## Example
6464+6565+There is more detailed information the special options for nodes [the
6666+reference](/reference/module.html).
6767+6868+```nix:line-numbers [hive.nix]
6969+{
7070+ meta.nixpkgs = import some-sources-or-inputs.nixpkgs { };
7171+7272+ defaults = {
7373+ # name of the node that defaults is being applied to
7474+ name,
7575+ # attribute set of all nodes
7676+ nodes,
7777+ pkgs,
7878+ ...
7979+ }: {
8080+ import = [
8181+ ./default-module.nix
8282+8383+ # module that is imported for all nodes
8484+ some-flake.nixosModules.default
8585+ ];
8686+8787+ # all nodes should include vim!
8888+ environment.systemPackages [ pkgs.vim ];
8989+ };
9090+9191+ node-a = {
9292+ # name of the node that defaults is being applied to
9393+ name,
9494+ # attribute set of all nodes
9595+ nodes,
9696+ pkgs,
9797+ ...
9898+ }: {
9999+ imports = [
100100+ # import the hardware-config and all your extra stuff
101101+ ./node-a
102102+ ];
103103+104104+ deployment = {
105105+ target.host = "192.0.2.1";
106106+ tags = [ "x86" ];
107107+ };
108108+ };
109109+110110+ # as many nodes as you'd like...
111111+112112+ node-g = {
113113+ # some more config
114114+ };
115115+}
116116+```
+19-11
doc/index.md
···55hero:
66 name: wire
77 text: a tool to deploy nixos systems
88- # tagline: My great project tagline
98 actions:
109 - theme: brand
1111- text: Read Guide
1212- link: /guide/wire
1010+ text: Read Tutorial
1111+ link: /tutorial/overview
1212+ - theme: alt
1313+ text: How-to Guides
1414+ link: /guides/installation
1315 - theme: alt
1414- text: Reference
1515- link: /reference/cli
1616+ text: Sources
1717+ link: https://github.com/forallsys/wire.git
16181719features:
1818- - title: Parallelism
1919- details: Build and deploy many nodes at once
2020- - title: Secret management
2121- details: Fast & Unopinionated secret management
2222- - title: Node Tagging & CI Friendly
2323- details: Pipe data through jq
2020+ - title: Deploy in Parallel
2121+ details: Build and deploy many nodes at once.
2222+ link: /guides/parallelism
2323+ icon: ๐ฝ
2424+ - title: Manage Secrets
2525+ details: Fast & Unopinionated secret management. Bring your own GPG, Age, or any other encryption tool.
2626+ link: /guides/keys
2727+ icon: ๐
2828+ - title: Deploy as Any User
2929+ details: Non-root deployments and interactive authentication is fully supported.
3030+ link: /guides/non-root-user
3131+ icon: ๐งโ๐ป
2432---
···11+---
22+comment: false
33+title: wire Tutorial Overview
44+description: In this tutorial we will create and deploy a wire Hive.
55+---
66+77+# wire Tutorial Overview
88+99+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.
1010+1111+[^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.
1212+1313+---
1414+1515+In this tutorial we will create and deploy a wire Hive. Along the way we will
1616+encounter [npins](https://github.com/andir/npins), simple NixOS
1717+configurations, virtual machines, and deployment keys.
1818+1919+You'll need at least 10~ GB of free disk space to complete this tutorial.
2020+2121+<div class="tip custom-block" style="padding-top: 8px">
2222+2323+Ready? Skip to [Nix Setup](./part-one/nix-setup).
2424+2525+</div>
2626+2727+## What features does wire have?
2828+2929+| Features | wire | Colmena |
3030+| ------------------------------------------------------------- | ------------------ | ------------------ |
3131+| [Node Tagging](/guides/targeting.html#tag-basics) | :white_check_mark: | :white_check_mark: |
3232+| [Secret Management](/guides/keys.html) | :white_check_mark: | :white_check_mark: |
3333+| [Parallel Deployment](/guides/parallelism.html) | :white_check_mark: | :white_check_mark: |
3434+| Remote Builds | :white_check_mark: | :white_check_mark: |
3535+| [Key Services](/guides/keys.html#using-keys-with-services) | :white_check_mark: | :white_check_mark: |
3636+| [Pipeline Support](/guides/targeting.html#reading-from-stdin) | :white_check_mark: | :x:[^2] |
3737+| [Non-Root Deployments](/guides/non-root-user) | :white_check_mark: | :x:[^3] |
3838+| `--path` accepts flakerefs | :white_check_mark: | :x: |
3939+| REPL & Eval expressions | :x: | :white_check_mark: |
4040+| Adhoc remote command execution[^4] | :x: | :white_check_mark: |
4141+4242+[^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.
4343+4444+[^3]: See https://github.com/zhaofengli/colmena/issues/120
4545+4646+[^4]: wire lacks an equivalent to `colmena exec`.
+188
doc/tutorial/part-one/basic-hive.md
···11+---
22+comment: true
33+title: Basic Hive & Deployment
44+description: Creating a basic hive and deploying changes to the virtual machine.
55+---
66+77+# Basic Hive & Deployment
88+99+{{ $frontmatter.description }}
1010+1111+## Editing `hive.nix`
1212+1313+Open a text editor and edit `hive.nix`. You should copy this example, which imports
1414+the npins sources we added. It also calls `makeHive`, and gives wire `nixpkgs`
1515+from npins as well.
1616+1717+```nix:line-numbers [hive.nix]
1818+let
1919+ # import npins sources
2020+ sources = import ./npins;
2121+ # import `wire` from npins sources
2222+ wire = import sources.wire;
2323+in
2424+wire.makeHive {
2525+ # give wire nixpkgs from npins
2626+ meta.nixpkgs = import sources.nixpkgs { };
2727+2828+ # we'll edit this part
2929+}
3030+```
3131+3232+Lets check out what wire sees with `wire show`.
3333+3434+```sh
3535+[nix-shell]$ wire show
3636+ INFO eval_hive: evaluating hive HiveNix("/home/marsh/scratch/wire-tutorial/hive.nix")
3737+ WARN use --json to output something scripting suitable
3838+Summary: 0 total node(s), totalling 0 keys (0 distinct).
3939+Note: Listed connections are tried from Left to Right
4040+4141+```
4242+4343+The line `nodes: {}` means there is no "nodes" in our hive.
4444+4545+## Adding The First Node
4646+4747+Lets add the virtual machine as a node to the hive with the name
4848+`virtual-machine`. Additionally, we will add `deployment.target`, recalling we
4949+forwarded sshd `virtual-machine:22` to the port `localhost:2222`:
5050+5151+```nix:line-numbers [hive.nix]
5252+let
5353+ sources = import ./npins;
5454+ wire = import sources.wire;
5555+in
5656+wire.makeHive {
5757+ meta.nixpkgs = import sources.nixpkgs { };
5858+5959+ virtual-machine = { pkgs, ... }: { # [!code ++]
6060+ deployment.target = { # [!code ++]
6161+ port = 2222; # [!code ++]
6262+ hosts = [ "localhost" ]; # [!code ++]
6363+ }; # [!code ++]
6464+6565+ nixpkgs.hostPlatform = "x86_64-linux"; # [!code ++]
6666+ }; # [!code ++]
6767+}
6868+```
6969+7070+## A naive `wire apply`
7171+7272+If we tried to run `wire apply` on our hive at this stage, it likely won't work.
7373+If you've used NixOS before, you'll notice that many important options are
7474+missing. But let's try anyway:
7575+7676+```sh
7777+[nix-shell]$ wire apply
7878+ERROR apply{goal=Switch on=}:goal{node=virtual-machine}: lib::hive::node: Failed to execute `Evaluate the node`
7979+Error: ร 1 node(s) failed to apply.
8080+8181+Error:
8282+ ร node virtual-machine failed to apply
8383+ โโโถ wire::Evaluate
8484+ โ
8585+ โ ร failed to evaluate `--file /home/marsh/scratch/wire-tutorial/hive.nix topLevels.virtual-machine` from the context
8686+ โ โ of a hive.
8787+ โ
8888+ โฐโโถ nix --extra-experimental-features nix-command --extra-experimental-features flakes eval --json --file /home/marsh/scratch/
8989+ wire-tutorial/hive.nix topLevels.virtual-machine --log-format internal-json failed (reason: known-status) with code 1 (last 20
9090+ lines):
9191+ error:
9292+ โฆ while evaluating '(evaluateNode node).config.system.build.toplevel' to select 'drvPath' on it
9393+ at /nix/store/5pfz0v479gnciac17rcqi2gwyz8pl4s0-source/runtime/evaluate.nix:65:23:
9494+ 64|
9595+ 65| getTopLevel = node: (evaluateNode node).config.system.build.toplevel.drvPath;
9696+ | ^
9797+ 66| in
9898+9999+ โฆ while calling the 'head' builtin
100100+ at /nix/store/n3d1ricw0cb5jd8vvfym6ig0mw7x7sv9-source/lib/attrsets.nix:1701:13:
101101+ 1700| if length values == 1 || pred here (elemAt values 1) (head values) then
102102+ 1701| head values
103103+ | ^
104104+ 1702| else
105105+106106+ (stack trace truncated; use '--show-trace' to show the full trace)
107107+108108+ error:
109109+ Failed assertions:
110110+ - The โfileSystemsโ option does not specify your root file system.
111111+ - You must set the option โboot.loader.grub.devicesโ or 'boot.loader.grub.mirroredBoots' to make the system bootable.
112112+ trace: evaluation warning: system.stateVersion is not set, defaulting to 25.11. Read why this matters on https://nixos.org/
113113+ manual/nixos/stable/options.html#opt-system.stateVersion.
114114+115115+```
116116+117117+The command complained about not defining any fileSystems or a boot loader.
118118+The `${sources.nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix` imported in
119119+`vm.nix` does
120120+extra work to make our virtual machine work, which we are currently missing.
121121+122122+## Importing `vm.nix`
123123+124124+Lets import our `vm.nix` to this hive to fix our evaluation errors.
125125+Additionally, add a new package such as `vim` to our configuration:
126126+127127+```nix:line-numbers [hive.nix]
128128+let
129129+ sources = import ./npins;
130130+ wire = import sources.wire;
131131+in
132132+wire.makeHive {
133133+ meta.nixpkgs = import sources.nixpkgs { };
134134+135135+ virtual-machine = { pkgs, ... }: {
136136+ deployment.target = {
137137+ port = 2222;
138138+ hosts = [ "localhost" ];
139139+ };
140140+141141+ imports = [ # [!code ++]
142142+ ./vm.nix # [!code ++]
143143+ ]; # [!code ++]
144144+145145+ environment.systemPackages = [ pkgs.vim ]; # [!code ++]
146146+147147+ nixpkgs.hostPlatform = "x86_64-linux";
148148+ };
149149+}
150150+```
151151+152152+## Our first deploy
153153+154154+Trying our basic `wire apply` again with these changes:
155155+156156+```sh
157157+[nix-shell]$ wire apply
158158+...
159159+ INFO lib::nix_log: stopping the following units: boot.mount
160160+ INFO lib::nix_log: NOT restarting the following changed units: systemd-fsck@dev-disk-by\x2dlabel-ESP.service
161161+ INFO lib::nix_log: activating the configuration...
162162+ INFO lib::nix_log: setting up /etc...
163163+ INFO lib::nix_log: restarting systemd...
164164+ INFO lib::nix_log: reloading user units for root...
165165+ INFO lib::nix_log: restarting sysinit-reactivation.target
166166+ INFO lib::nix_log: reloading the following units: dbus.service
167167+ INFO lib::nix_log: the following new units were started: boot.automount, sysinit-reactivation.target, systemd-tmpfiles-resetup.service
168168+ INFO apply{goal=Switch on=}:goal{node=virtual-machines}: lib::hive::node: Executing step `Upload key @ PostActivation`
169169+ INFO apply{goal=Switch on=}: wire::apply: Successfully applied goal to 1 node(s): [Name("virtual-machines")]
170170+```
171171+172172+Now, lets confirm these changes were applied to the virtual machine by executing
173173+`vim` in the virtual machine window:
174174+175175+```sh [Virtual Machine]
176176+[root@wire-tutorial:~]# vim --version
177177+VIM - Vi IMproved 9.1 (2024 Jan 02, compiled Jan 01 1980 00:00:00)
178178+```
179179+180180+Nice! You successfully deployed a new NixOS configuration to a **remote host**!
181181+182182+::: info
183183+This followed common steps of adding the node's `deployment.target` details and
184184+importing it's pre-existing NixOS configuration (in this case, `vm.nix`), a
185185+pattern you'll be using a lot if you chose to adopt wire.
186186+:::
187187+188188+In the next section, we'll cover how to deploy secrets / keys to our remote node.
+40
doc/tutorial/part-one/nix-setup.md
···11+---
22+comment: true
33+title: Nix Setup
44+description: Installing npins, nix, and enabling the binary cache.
55+---
66+77+# Nix Setup
88+99+{{ $frontmatter.description }}
1010+1111+::: warning
1212+This page is for the purposes for the **Tutorial**.
1313+You should read [How-to Guides - Install wire](/guides/installation.html) for installing wire for
1414+regular use.
1515+:::
1616+1717+## Nix Installation
1818+1919+You should install nix if you do not have it on your system already.
2020+There are detailed steps to installing Nix on [nix.dev](https://nix.dev/install-nix).
2121+2222+By the end of the installation, you should see something like this:
2323+2424+```sh
2525+$ nix --version
2626+nix (Nix) 2.11.0
2727+```
2828+2929+## Binary Cache
3030+3131+Because wire can be heavy to compile, it is distributed with a [binary
3232+cache](https://wiki.nixos.org/wiki/Binary_Cache).
3333+3434+You must enable the [garnix binary cache](https://garnix.io/docs/caching) or you
3535+will be compiling everything from source:
3636+3737+::: code-group
3838+<<< @/snippets/tutorial/cache.conf [nix.conf]
3939+<<< @/snippets/tutorial/cache.nix [configuration.nix]
4040+:::
+116
doc/tutorial/part-one/repo-setup.md
···11+---
22+comment: true
33+title: Preparing Repo & Shell
44+description: Adding npins sources and a nix development shell.
55+---
66+77+# Preparing Repo & Shell
88+99+{{ $frontmatter.description }}
1010+1111+## Initialising with Git & `npins`
1212+1313+First, lets create an adhoc shell to bring these two tools into our $PATH.
1414+1515+```sh
1616+$ nix-shell -p git npins
1717+[nix-shell]$ git --version
1818+git version 2.51.0
1919+[nix-shell]$ npins --version
2020+npins 0.3.1
2121+```
2222+2323+Great! Now lets use Git & `npins` to create a new Git repo and initialise it.
2424+`npins init` may take a while to download `nixpkgs`.
2525+2626+```sh
2727+[nix-shell]$ git init wire-tutorial
2828+Initialized empty Git repository in /home/.../wire-tutorial/.git/
2929+[nix-shell]$ cd wire-tutorial/
3030+[nix-shell]$ npins init
3131+[INFO ] Welcome to npins!
3232+[INFO ] Creating `npins` directory
3333+[INFO ] Writing default.nix
3434+[INFO ] Writing initial lock file (empty)
3535+[INFO ] Successfully written initial files to 'npins/sources.json'.
3636+```
3737+3838+This has created a pinned version of `nixpkgs` for us to use in our wire hive.
3939+4040+## Adding wire as a dependency
4141+4242+We can now need to tell `npins` to use `forallsys/wire` as a dependency.
4343+4444+```sh
4545+[nix-shell]$ npins add github forallsys wire --branch stable
4646+[INFO ] Adding 'wire' โฆ
4747+ repository: https://github.com/forallsys/wire.git
4848+ pre_releases: false
4949+ submodules: false
5050+ version: v0.4.0
5151+ revision: f33d80c15b17c85d557d533441609a59a2210941
5252+ hash: 0wgah341hvjpvppkgwjrj50rvzf56ccmjz720xsl3mw38h9nn6sr
5353+ frozen: false
5454+```
5555+5656+Great, now lets confirm the two dependencies we have added to this `npins`
5757+project:
5858+5959+```sh
6060+[nix-shell]$ npins show
6161+nixpkgs: (git repository)
6262+ repository: https://github.com/pkpbynum/nixpkgs.git
6363+ branch: pb/disk-size-bootloader
6464+ submodules: false
6565+ revision: da2060bdc1c9bc35acc4eafa265ba6b6c64f9926
6666+ url: https://github.com/pkpbynum/nixpkgs/archive/da2060bdc1c9bc35acc4eafa265ba6b6c64f9926.tar.gz
6767+ hash: 0j07gvnm7c5mzw1313asa8limzbmsbnsd02dcw22ing8fg3vbb7g
6868+ frozen: false
6969+7070+wire: (git release tag)
7171+ repository: https://github.com/forallsys/wire.git
7272+ pre_releases: false
7373+ submodules: false
7474+ version: v0.4.0
7575+ revision: f33d80c15b17c85d557d533441609a59a2210941
7676+ hash: 0wgah341hvjpvppkgwjrj50rvzf56ccmjz720xsl3mw38h9nn6sr
7777+ frozen: false
7878+```
7979+8080+## Creating a `shell.nix`
8181+8282+Open a text editor to edit `shell.nix` in the `wire-tutorial` directory.
8383+8484+```nix:line-numbers [shell.nix]
8585+let
8686+ sources = import ./npins;
8787+ pkgs = import sources.nixpkgs { };
8888+ wire = import sources.wire;
8989+in
9090+pkgs.mkShell {
9191+ packages = [
9292+ wire.packages.x86_64-linux.wire-small
9393+ pkgs.npins
9494+ pkgs.git
9595+ ];
9696+9797+ shellHook = ''
9898+ export NIX_PATH="nixpkgs=${sources.nixpkgs.outPath}"
9999+ '';
100100+}
101101+```
102102+103103+You should now `exit` to quit the old shell, and
104104+enter a new shell with `nix-shell`. Since we added wire as a package, our new
105105+shell should have wire in the $PATH:
106106+107107+```sh
108108+[nix-shell]$ exit
109109+exit
110110+$ cd wire-tutorial/
111111+$ nix-shell
112112+[nix-shell]$ wire --version
113113+wire 0.5.0
114114+Debug: Hive::SCHEMA_VERSION 0
115115+116116+```
+161
doc/tutorial/part-one/vm-setup.md
···11+---
22+comment: true
33+title: Creating a Virtual Machine
44+description: Creating a NixOS virtual machine to use as a deployment target.
55+---
66+77+# Creating a Virtual Machine
88+99+{{ $frontmatter.description }}
1010+1111+## Creating a `vm.nix`
1212+1313+For this step, you'll need your ssh public key, which you can obtain from
1414+`ssh-add -L`.
1515+1616+Open a text editor and edit `vm.nix`. Place in it this basic NixOS
1717+virtual machine configuration, which enables openssh and forwards it's 22 port:
1818+1919+```nix:line-numbers [vm.nix]
2020+let
2121+ sources = import ./npins;
2222+in
2323+{
2424+ imports = [ "${sources.nixpkgs}/nixos/modules/virtualisation/qemu-vm.nix" ];
2525+2626+ networking.hostName = "wire-tutorial";
2727+2828+ users.users.root = {
2929+ initialPassword = "root";
3030+ openssh.authorizedKeys.keys = [
3131+ # I made this a nix syntax error so you're forced to deal with it!
3232+ <your ssh public-key as a string>
3333+ ];
3434+ };
3535+3636+ boot = {
3737+ loader = {
3838+ systemd-boot.enable = true;
3939+ efi.canTouchEfiVariables = true;
4040+ };
4141+4242+ kernelParams = [ "console=ttyS0" ];
4343+4444+ boot.growPartition = true;
4545+ };
4646+4747+ # enable openssh
4848+ services = {
4949+ openssh = {
5050+ enable = true;
5151+ settings.PermitRootLogin = "yes";
5252+ };
5353+5454+ getty.autologinUser = "root";
5555+ };
5656+5757+ virtualisation = {
5858+ graphics = false;
5959+ useBootLoader = true;
6060+6161+ # use a 5gb disk
6262+ diskSize = 5 * 1024;
6363+6464+ # grow the filesystem to fit the 5 gb we reserved
6565+ fileSystems."/".autoResize = true;
6666+6767+ # forward `openssh` port 22 to localhost:2222.
6868+ forwardPorts = [
6969+ {
7070+ from = "host";
7171+ host.port = 2222;
7272+ guest.port = 22;
7373+ }
7474+ ];
7575+ };
7676+7777+ system.stateVersion = "23.11";
7878+}
7979+```
8080+8181+If you like, you may take a moment to understand each line of this
8282+configuration.
8383+8484+## Building & Running the virtual machine
8585+8686+Open a separate Terminal tab/window/instance, ensuring you enter the development
8787+shell with `nix-shell`.
8888+Then, build the virtual machine with a bootloader,
8989+taking our `vm.nix` as the nixos configuration.
9090+9191+```sh
9292+$ nix-shell
9393+[nix-shell]$ nix-build '<nixpkgs/nixos>' -A vmWithBootLoader -I nixos-config=./vm.nix
9494+```
9595+9696+::: tip HELP
9797+9898+If you got an error such as
9999+100100+```
101101+error: The option `...' in `...' is already declared in `...'.
102102+```
103103+104104+make sure you ran the above command in the `nix-shell`!
105105+106106+:::
107107+108108+Building the virtual machine can take some time, but once it completes, start it
109109+by running:
110110+111111+```sh
112112+[nix-shell]$ ./result/bin/run-wire-tutorial-vm
113113+```
114114+115115+You will see boot-up logs fly across the screen and eventually you will be placed
116116+into shell inside the virtual machine.
117117+118118+```sh [Virtual Machine]
119119+running activation script...
120120+setting up /etc...
121121+122122+Welcome to NixOS 25.11 (Xantusia)!
123123+124124+[ OK ] Created slice Slice /system/getty.
125125+[ OK ] Created slice Slice /system/modprobe.
126126+...
127127+<<< Welcome to NixOS 25.11pre861972.88cef159e47c (x86_64) - hvc0 >>>
128128+129129+Run 'nixos-help' for the NixOS manual.
130130+131131+wire-tutorial login: root (automatic login)
132132+133133+[root@wire-tutorial:~]#
134134+135135+```
136136+137137+::: details
138138+Further details on how the above commands work can be found at
139139+[nix.dev](https://nix.dev/tutorials/nixos/nixos-configuration-on-vm.html#creating-a-qemu-based-virtual-machine-from-a-nixos-configuration)
140140+:::
141141+142142+## Summary
143143+144144+Congratulations, you created a virtual machine in your terminal.
145145+We'll be deploying to this virtual machine, so keep the
146146+terminal instance open.
147147+148148+::: info
149149+From now on, commands ran inside the virtual machine will be lead with the
150150+following prompt:
151151+152152+```sh [Virtual Machine]
153153+[root@wire-tutorial:~]#
154154+155155+```
156156+157157+:::
158158+159159+::: tip
160160+If you ever want to quit the virtual machine, run the command `poweroff`.
161161+:::
+142
doc/tutorial/part-two/basic-keys.md
···11+---
22+comment: true
33+title: Deployment Keys Basics
44+description: Deploy some basic secrets with wire tool.
55+---
66+77+# Deployment Keys Basics
88+99+{{ $frontmatter.description }}
1010+1111+## Creating a `secrets.nix`
1212+1313+Lets create a NixOS module that will contain our secret keys, and import it:
1414+1515+```nix:line-numbers [hive.nix]
1616+let
1717+ sources = import ./npins;
1818+ wire = import sources.wire;
1919+in
2020+wire.makeHive {
2121+ meta.nixpkgs = import sources.nixpkgs { };
2222+2323+ virtual-machine = {
2424+ deployment.target = {
2525+ port = 2222;
2626+ hosts = [ "localhost" ];
2727+ };
2828+2929+ imports = [
3030+ ./vm.nix
3131+ ./secrets.nix # [!code ++]
3232+ ];
3333+3434+ environment.systemPackages = [ pkgs.vim ];
3535+3636+ nixpkgs.hostPlatform = "x86_64-linux";
3737+ };
3838+}
3939+```
4040+4141+```nix:line-numbers [secrets.nix]
4242+{
4343+ deployment.keys = {
4444+ # the key's unique name is `"basic.txt"`.
4545+ "basic.txt" = {
4646+ # In this key's case, the source is a literal string:
4747+ source = ''
4848+ Hello World
4949+ '';
5050+ };
5151+ };
5252+}
5353+```
5454+5555+::: details
5656+Further details on the `deployment.keys` options can be found
5757+[in the reference](/reference/module.html#deployment-keys)
5858+:::
5959+6060+Once we deploy this new configuration to the virtul machine,
6161+`/run/keys/basic.txt` will be created with the contents of the key.
6262+6363+```sh
6464+[nix-shell]$ wire apply keys
6565+ WARN lib::nix_log: Store URL: ssh://root@localhost
6666+(root@localhost) Password:
6767+6868+```
6969+7070+```sh [Virtual Machine]
7171+[root@wire-tutorial:~]# cat /run/keys/basic.txt
7272+Hello World
7373+7474+```
7575+7676+You successfully deployed your first, albeit not-so-secret, secret key! Let's
7777+move on from literal-text keys and use something a bit more powerful.
7878+7979+## File-sourced keys <Badge type="info">Optional</Badge>
8080+8181+This section is optional to try, but you can also pass `deployment.keys.<name>.source`
8282+a file path. It's contents is read and treated as literal text.
8383+8484+```sh
8585+$ echo hello world > very-important-secret.txt
8686+```
8787+8888+```nix:line-numbers [secrets.nix]
8989+{
9090+ deployment.keys = {
9191+ # ...
9292+9393+ "very-important-secret.txt" = { # [!code ++]
9494+ source = ./very-important-secret.txt; # [!code ++]
9595+ }; # [!code ++]
9696+ };
9797+}
9898+```
9999+100100+```sh [Virtual Machine]
101101+[root@wire-tutorial:~]# cat /run/keys/very-important-secret.txt
102102+hello world
103103+104104+```
105105+106106+## Command-sourced keys
107107+108108+Command-sourced keys are where the real power of wire keys lie. By passing a
109109+list of strings, wire will execute them as a command and create a key out of it's `stdout`.
110110+111111+Because the command's output is never written to the nix store, these can be
112112+considered real secrets.
113113+114114+To create a basic example, update your `secrets.nix` to include a secret that
115115+echos "hello world":
116116+117117+```nix:line-numbers [secrets.nix]
118118+{
119119+ deployment.keys = {
120120+ # ...
121121+122122+ "command.txt" = { # [!code ++]
123123+ source = [ # [!code ++]
124124+ "echo" # [!code ++]
125125+ "hello world" # [!code ++]
126126+ ]; # [!code ++]
127127+ }; # [!code ++]
128128+ };
129129+}
130130+```
131131+132132+After a quick `wire deploy secrets`, the `/run/keys/command.txt` file is
133133+created:
134134+135135+```sh [Virtual Machine]
136136+[root@wire-tutorial:~]# cat /run/keys/command.txt
137137+hello world
138138+139139+```
140140+141141+Hopefully you can see the potential of command-sourced keys, as these are the
142142+basic building block of how we achieve encrypted secrets with wire.
+107
doc/tutorial/part-two/encryption.md
···11+---
22+comment: true
33+title: Deployment Keys Basics
44+description: Deploy a age-encrypted secret with wire tool.
55+---
66+77+# Deployment Keys Basics
88+99+{{ $frontmatter.description }}
1010+1111+::: tip
1212+For this tutorial we will be using [`age`](https://github.com/FiloSottile/age),
1313+but other encryption CLI tools work just as well such as GnuPG.
1414+:::
1515+1616+## Installing age
1717+1818+Alter your shell.nix to include age:
1919+2020+```nix:line-numbers [shell.nix]
2121+let
2222+ sources = import ./npins;
2323+ pkgs = import sources.nixpkgs { };
2424+ wire = import sources.wire;
2525+in
2626+pkgs.mkShell {
2727+ packages = [
2828+ wire.packages.x86_64-linux.wire-small
2929+ pkgs.npins
3030+ pkgs.git
3131+ pkgs.age # [!code ++]
3232+ ];
3333+3434+ shellHook = ''
3535+ export NIX_PATH="nixpkgs=${sources.nixpkgs.outPath}"
3636+ '';
3737+}
3838+```
3939+4040+Quit and re-open your shell, and confirm age is now available:
4141+4242+```sh
4343+[nix-shell]$ exit
4444+exit
4545+$ nix-shell
4646+[nix-shell]$ age --version
4747+1.2.1
4848+4949+```
5050+5151+## Encrypting a secret
5252+5353+First create an age private key:
5454+5555+```sh
5656+[nix-shell]$ age-keygen -o key.txt
5757+Public key: age1j08s3kmr8zw4w8k99vs4nut5mg03dm8nfuaajuekdyzlujxply5qwsv4g0
5858+5959+```
6060+6161+::: details
6262+Further details on how age works can be found on in the
6363+[age manual](https://man.archlinux.org/man/age.1.en.txt).
6464+:::
6565+6666+Now, lets encrypt the words `"!! encrypted string !!"` with age and save it to the
6767+file `top-secret.age`.
6868+6969+We will use a pipeline to echo the encrypted string into
7070+age, and use `age-keygent -y` to give age the public key we generated, then we
7171+use the redirection operator to save the encrypted data to `top-secret.age`.
7272+7373+```sh
7474+[nix-shell]$ echo "encrypted string!" | age --encrypt --recipient $(age-keygen -y key.txt) > top-secret.age
7575+```
7676+7777+## Adding an age-encrypted key
7878+7979+Now, lets combine our previous command-sourced key with `age`. Pass the
8080+arguments `age --decrypt --identity key.txt ./top-secret.age` to wire:
8181+8282+```nix:line-numbers [secrets.nix]
8383+{
8484+ deployment.keys = {
8585+ # ...
8686+8787+ "top-secret" = { # [!code ++]
8888+ source = [ # [!code ++]
8989+ "age" # [!code ++]
9090+ "--decrypt" # [!code ++]
9191+ "--identity" # [!code ++]
9292+ "key.txt" # [!code ++]
9393+ "${./top-secret.age}" # [!code ++]
9494+ ]; # [!code ++]
9595+ }; # [!code ++]
9696+ };
9797+}
9898+```
9999+100100+One `wire apply keys` later, and you have successfully deployed an encrypted
101101+key:
102102+103103+```sh [Virtual Machine]
104104+[root@wire-tutorial:~]# cat /run/keys/top-secret
105105+encrypted string!
106106+107107+```
···11+# SPDX-License-Identifier: AGPL-3.0-or-later
22+# Copyright 2024-2025 wire Contributors
33+14{ testName }:
25let
36 # Use the flake-compat code in project root to access the tests which are
+5-2
tests/nix/test-opts.nix
···11+# SPDX-License-Identifier: AGPL-3.0-or-later
22+# Copyright 2024-2025 wire Contributors
33+14{
25 lib,
36 snakeOil,
44- wire-small,
77+ wire-small-dev,
58 config,
69 pkgs,
710 ...
···3336 "C+ /root/.ssh/id_ed25519 600 - - - ${snakeOil.snakeOilEd25519PrivateKey}"
3437 ];
3538 environment.systemPackages = [
3636- wire-small
3939+ wire-small-dev
3740 pkgs.ripgrep
3841 ];
3942 # It's important to note that you should never ever use this configuration