@homeflare/alchemy 0.31.2 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/README.md +39 -3
  2. package/dist/grafana/dashboard-model.d.ts +77 -0
  3. package/dist/grafana/dashboard-model.d.ts.map +1 -0
  4. package/dist/grafana/dashboard.d.ts +98 -0
  5. package/dist/grafana/dashboard.d.ts.map +1 -0
  6. package/dist/grafana/folder.d.ts +100 -0
  7. package/dist/grafana/folder.d.ts.map +1 -0
  8. package/dist/grafana/index.d.ts +9 -8
  9. package/dist/grafana/index.d.ts.map +1 -1
  10. package/dist/grafana/index.js +158 -6
  11. package/dist/grafana/index.js.map +8 -4
  12. package/dist/grafana/providers.d.ts +1 -1
  13. package/dist/grafana/providers.d.ts.map +1 -1
  14. package/dist/grafana/provisioned.d.ts +11 -0
  15. package/dist/grafana/provisioned.d.ts.map +1 -0
  16. package/dist/linux/container-form.d.ts +129 -0
  17. package/dist/linux/container-form.d.ts.map +1 -0
  18. package/dist/linux/container-generator.d.ts +74 -0
  19. package/dist/linux/container-generator.d.ts.map +1 -0
  20. package/dist/linux/container-handlers.d.ts +15 -0
  21. package/dist/linux/container-handlers.d.ts.map +1 -0
  22. package/dist/linux/container-lifecycle.d.ts +37 -0
  23. package/dist/linux/container-lifecycle.d.ts.map +1 -0
  24. package/dist/linux/container-preflight.d.ts +34 -0
  25. package/dist/linux/container-preflight.d.ts.map +1 -0
  26. package/dist/linux/container-secrets.d.ts +37 -0
  27. package/dist/linux/container-secrets.d.ts.map +1 -0
  28. package/dist/linux/container-settle.d.ts +34 -0
  29. package/dist/linux/container-settle.d.ts.map +1 -0
  30. package/dist/linux/container.d.ts +30 -0
  31. package/dist/linux/container.d.ts.map +1 -0
  32. package/dist/linux/fake-quadlet.d.ts +25 -0
  33. package/dist/linux/fake-quadlet.d.ts.map +1 -0
  34. package/dist/linux/index.d.ts +6 -3
  35. package/dist/linux/index.d.ts.map +1 -1
  36. package/dist/linux/index.js +641 -268
  37. package/dist/linux/index.js.map +15 -7
  38. package/dist/linux/providers.d.ts +1 -1
  39. package/dist/linux/providers.d.ts.map +1 -1
  40. package/dist/linux/systemctl.d.ts +7 -1
  41. package/dist/linux/systemctl.d.ts.map +1 -1
  42. package/dist/opnsense/alias-form.d.ts +29 -0
  43. package/dist/opnsense/alias-form.d.ts.map +1 -0
  44. package/dist/opnsense/alias.d.ts +81 -0
  45. package/dist/opnsense/alias.d.ts.map +1 -0
  46. package/dist/opnsense/category-form.d.ts +10 -0
  47. package/dist/opnsense/category-form.d.ts.map +1 -0
  48. package/dist/opnsense/category.d.ts +58 -0
  49. package/dist/opnsense/category.d.ts.map +1 -0
  50. package/dist/opnsense/credentials.d.ts +36 -0
  51. package/dist/opnsense/credentials.d.ts.map +1 -0
  52. package/dist/opnsense/fake-opnsense.d.ts +51 -0
  53. package/dist/opnsense/fake-opnsense.d.ts.map +1 -0
  54. package/dist/opnsense/group-form.d.ts +11 -0
  55. package/dist/opnsense/group-form.d.ts.map +1 -0
  56. package/dist/opnsense/group.d.ts +62 -0
  57. package/dist/opnsense/group.d.ts.map +1 -0
  58. package/dist/opnsense/index.d.ts +16 -0
  59. package/dist/opnsense/index.d.ts.map +1 -0
  60. package/dist/opnsense/index.js +211 -0
  61. package/dist/opnsense/index.js.map +20 -0
  62. package/dist/opnsense/policy.d.ts +20 -0
  63. package/dist/opnsense/policy.d.ts.map +1 -0
  64. package/dist/opnsense/providers.d.ts +13 -0
  65. package/dist/opnsense/providers.d.ts.map +1 -0
  66. package/dist/opnsense/resource.d.ts +74 -0
  67. package/dist/opnsense/resource.d.ts.map +1 -0
  68. package/dist/opnsense/wire.d.ts +39 -0
  69. package/dist/opnsense/wire.d.ts.map +1 -0
  70. package/dist/proxmox/index.js +170 -80
  71. package/dist/proxmox/index.js.map +9 -7
  72. package/dist/proxmox/storage-form.d.ts +54 -0
  73. package/dist/proxmox/storage-form.d.ts.map +1 -0
  74. package/dist/proxmox/storage-wire.d.ts +56 -0
  75. package/dist/proxmox/storage-wire.d.ts.map +1 -0
  76. package/dist/proxmox/storage.d.ts +55 -60
  77. package/dist/proxmox/storage.d.ts.map +1 -1
  78. package/dist/proxmox/zfs-pool-form.d.ts +124 -0
  79. package/dist/proxmox/zfs-pool-form.d.ts.map +1 -0
  80. package/dist/proxmox/zfs-pool-wire.d.ts +78 -0
  81. package/dist/proxmox/zfs-pool-wire.d.ts.map +1 -0
  82. package/dist/proxmox/zfs-pool.d.ts +27 -52
  83. package/dist/proxmox/zfs-pool.d.ts.map +1 -1
  84. package/dist/unifi/fake-unifi.d.ts +48 -0
  85. package/dist/unifi/fake-unifi.d.ts.map +1 -0
  86. package/dist/unifi/firewall-zone-form.d.ts +40 -0
  87. package/dist/unifi/firewall-zone-form.d.ts.map +1 -0
  88. package/dist/unifi/firewall-zone.d.ts +50 -0
  89. package/dist/unifi/firewall-zone.d.ts.map +1 -0
  90. package/dist/unifi/index.d.ts +13 -0
  91. package/dist/unifi/index.d.ts.map +1 -0
  92. package/dist/unifi/index.js +190 -0
  93. package/dist/unifi/index.js.map +16 -0
  94. package/dist/unifi/network-form.d.ts +67 -0
  95. package/dist/unifi/network-form.d.ts.map +1 -0
  96. package/dist/unifi/network.d.ts +67 -0
  97. package/dist/unifi/network.d.ts.map +1 -0
  98. package/dist/unifi/policy.d.ts +20 -0
  99. package/dist/unifi/policy.d.ts.map +1 -0
  100. package/dist/unifi/providers.d.ts +13 -0
  101. package/dist/unifi/providers.d.ts.map +1 -0
  102. package/dist/unifi/resource.d.ts +64 -0
  103. package/dist/unifi/resource.d.ts.map +1 -0
  104. package/docs/grafana-folder-dashboard.md +145 -0
  105. package/docs/grafana.md +11 -10
  106. package/docs/opnsense.md +146 -0
  107. package/docs/provider-standard.md +1 -1
  108. package/docs/quadlet-container.md +132 -0
  109. package/docs/unifi.md +93 -0
  110. package/docs/upstream-conformance.md +9 -4
  111. package/package.json +12 -2
  112. package/src/grafana/dashboard-model.test.ts +111 -0
  113. package/src/grafana/dashboard-model.ts +111 -0
  114. package/src/grafana/dashboard.test.ts +232 -0
  115. package/src/grafana/dashboard.ts +161 -0
  116. package/src/grafana/folder.test.ts +212 -0
  117. package/src/grafana/folder.ts +161 -0
  118. package/src/grafana/index.ts +21 -8
  119. package/src/grafana/providers.ts +7 -1
  120. package/src/grafana/provisioned.ts +49 -0
  121. package/src/linux/container-fixture.test.ts +92 -0
  122. package/src/linux/container-form.ts +243 -0
  123. package/src/linux/container-generator.test.ts +195 -0
  124. package/src/linux/container-generator.ts +113 -0
  125. package/src/linux/container-handlers.ts +73 -0
  126. package/src/linux/container-lifecycle.test.ts +209 -0
  127. package/src/linux/container-lifecycle.ts +217 -0
  128. package/src/linux/container-preflight.ts +97 -0
  129. package/src/linux/container-secrets.test.ts +171 -0
  130. package/src/linux/container-secrets.ts +112 -0
  131. package/src/linux/container-settle.ts +97 -0
  132. package/src/linux/container.ts +60 -0
  133. package/src/linux/fake-quadlet.ts +127 -0
  134. package/src/linux/index.ts +11 -3
  135. package/src/linux/providers.ts +2 -0
  136. package/src/linux/systemctl.ts +9 -0
  137. package/src/opnsense/alias-form.test.ts +89 -0
  138. package/src/opnsense/alias-form.ts +53 -0
  139. package/src/opnsense/alias.test.ts +203 -0
  140. package/src/opnsense/alias.ts +117 -0
  141. package/src/opnsense/category-form.test.ts +54 -0
  142. package/src/opnsense/category-form.ts +20 -0
  143. package/src/opnsense/category.test.ts +138 -0
  144. package/src/opnsense/category.ts +82 -0
  145. package/src/opnsense/credentials.ts +41 -0
  146. package/src/opnsense/fake-opnsense.ts +79 -0
  147. package/src/opnsense/group-form.test.ts +75 -0
  148. package/src/opnsense/group-form.ts +25 -0
  149. package/src/opnsense/group.test.ts +141 -0
  150. package/src/opnsense/group.ts +78 -0
  151. package/src/opnsense/index.ts +45 -0
  152. package/src/opnsense/policy.ts +49 -0
  153. package/src/opnsense/providers.ts +21 -0
  154. package/src/opnsense/resource.ts +146 -0
  155. package/src/opnsense/wire.ts +56 -0
  156. package/src/opnsense/write-refusal.test.ts +148 -0
  157. package/src/proxmox/constraints-host-forms.test.ts +1 -1
  158. package/src/proxmox/storage-form.ts +144 -0
  159. package/src/proxmox/storage-read-failure.test.ts +214 -0
  160. package/src/proxmox/storage-wire.ts +124 -0
  161. package/src/proxmox/storage.ts +165 -175
  162. package/src/proxmox/zfs-pool-adopt.test.ts +26 -0
  163. package/src/proxmox/zfs-pool-form.ts +236 -0
  164. package/src/proxmox/zfs-pool-read-failure.test.ts +118 -0
  165. package/src/proxmox/zfs-pool-wire.ts +132 -0
  166. package/src/proxmox/zfs-pool.ts +106 -76
  167. package/src/unifi/fake-unifi.ts +60 -0
  168. package/src/unifi/firewall-zone-form.ts +65 -0
  169. package/src/unifi/firewall-zone.test.ts +88 -0
  170. package/src/unifi/firewall-zone.ts +66 -0
  171. package/src/unifi/index.ts +26 -0
  172. package/src/unifi/network-form.ts +207 -0
  173. package/src/unifi/network.test.ts +209 -0
  174. package/src/unifi/network.ts +83 -0
  175. package/src/unifi/policy.ts +37 -0
  176. package/src/unifi/providers.ts +15 -0
  177. package/src/unifi/resource.test.ts +133 -0
  178. package/src/unifi/resource.ts +131 -0
  179. package/dist/proxmox/zfs-pool-spec.d.ts +0 -27
  180. package/dist/proxmox/zfs-pool-spec.d.ts.map +0 -1
  181. package/dist/proxmox/zfs-pool-write.d.ts +0 -128
  182. package/dist/proxmox/zfs-pool-write.d.ts.map +0 -1
  183. package/src/proxmox/zfs-pool-spec.ts +0 -76
  184. package/src/proxmox/zfs-pool-write.ts +0 -196
@@ -5130,64 +5130,150 @@ var handlers24 = pveHandlers({
5130
5130
  var ProxmoxSdnZoneProvider = () => Provider33.effect(ProxmoxSdnZone, Effect63.succeed(ProxmoxSdnZone.Provider.of(handlers24)));
5131
5131
  // src/proxmox/storage.ts
5132
5132
  import { Resource as Resource34 } from "alchemy";
5133
+ import { isResolved as isResolved15 } from "alchemy/Diff";
5133
5134
  import * as Provider34 from "alchemy/Provider";
5134
- import * as Effect64 from "effect/Effect";
5135
- var ProxmoxStorage = Resource34("Proxmox.Storage", {
5136
- defaultRemovalPolicy: "retain"
5137
- });
5138
- var str2 = (value, fallback = "") => typeof value === "string" ? value : fallback;
5135
+ import * as storage2 from "@distilled.cloud/proxmox/storage";
5136
+ import * as Effect65 from "effect/Effect";
5137
+
5138
+ // src/proxmox/storage-form.ts
5139
+ var STORAGE_CREATE = "pve:POST /storage";
5140
+ var STORAGE_UPDATE = "pve:PUT /storage/{storage}";
5139
5141
  var field6 = (name, value) => value === undefined ? {} : { [name]: value };
5140
5142
  var locatorForm = (locator) => ({ ...locator });
5141
- var tokens = (value) => value.split(",").map((part) => part.trim()).filter((part) => part !== "").sort().join(",");
5142
- var sameList2 = (declared2, live) => declared2 === undefined || tokens(declared2) === tokens(live);
5143
- var same7 = (declared2, live) => declared2 === undefined || declared2 === live;
5143
+ var underscored = (form) => Object.fromEntries(Object.entries(form).map(([key, value]) => [key.replaceAll("-", "_"), value]));
5144
5144
  var mutable2 = (props) => ({
5145
5145
  ...field6("comment", props.comment),
5146
5146
  ...field6("content", props.content),
5147
5147
  ...field6("disable", flag(props.disable)),
5148
- ...field6("maxfiles", props.maxfiles === undefined ? undefined : String(props.maxfiles)),
5149
5148
  ...field6("nodes", props.nodes),
5150
5149
  ...field6("preallocation", props.preallocation),
5151
5150
  ...field6("prune-backups", props["prune-backups"]),
5152
5151
  ...field6("shared", flag(props.shared))
5153
5152
  });
5154
- var handlers25 = pveHandlers({
5155
- readRole: "provision",
5156
- attributes: (live, props) => ({
5157
- comment: str2(live["comment"]),
5158
- content: str2(live["content"]),
5159
- disable: bool(live["disable"]),
5160
- maxfiles: typeof live["maxfiles"] === "number" ? live["maxfiles"] : -1,
5161
- nodes: str2(live["nodes"]),
5162
- preallocation: str2(live["preallocation"]),
5163
- "prune-backups": str2(live["prune-backups"]),
5164
- shared: bool(live["shared"]),
5153
+ var createForm10 = (props) => ({
5154
+ ...locatorForm(props.locator),
5155
+ ...mutable2(props),
5156
+ storage: props.storage,
5157
+ type: props.type
5158
+ });
5159
+ var updateForm7 = (props) => ({
5160
+ ...mutable2(props),
5161
+ storage: props.storage
5162
+ });
5163
+ var toDistilledCreate = (props) => underscored(createForm10(props));
5164
+ var toDistilledUpdate = (props) => underscored(updateForm7(props));
5165
+
5166
+ // src/proxmox/storage-wire.ts
5167
+ import * as storage from "@distilled.cloud/proxmox/storage";
5168
+ import * as Effect64 from "effect/Effect";
5169
+ var str2 = (value, fallback = "") => typeof value === "string" ? value : fallback;
5170
+ var tokens = (value) => value.split(",").map((part) => part.trim()).filter((part) => part !== "").sort().join(",");
5171
+ var sameList2 = (declared2, live) => declared2 === undefined || tokens(declared2) === tokens(live);
5172
+ var same7 = (declared2, live) => declared2 === undefined || declared2 === live;
5173
+ var attributesOf7 = (live, props) => {
5174
+ const data = live;
5175
+ return {
5176
+ comment: str2(data["comment"]),
5177
+ content: str2(data["content"]),
5178
+ disable: bool(data["disable"]),
5179
+ nodes: str2(data["nodes"]),
5180
+ preallocation: str2(data["preallocation"]),
5181
+ "prune-backups": str2(data["prune-backups"]),
5182
+ shared: bool(data["shared"]),
5165
5183
  storage: props.storage,
5166
- type: str2(live["type"], props.type)
5184
+ type: str2(data["type"], props.type)
5185
+ };
5186
+ };
5187
+ var readStorageOrFail = (props) => readOrUnreadable(runPve(props.target, "provision", false, storage.getStorage({ storage: props.storage }))).pipe(Effect64.map((live) => live === UNREADABLE ? UNREADABLE : attributesOf7(live, props)));
5188
+ var readStorage = (props) => readStorageOrFail(props).pipe(Effect64.orElseSucceed(() => {
5189
+ return;
5190
+ }));
5191
+ var dropUnreadable6 = (live) => live === UNREADABLE ? undefined : live;
5192
+ var matches7 = (attributes2, props) => sameList2(props.content, attributes2.content) && sameList2(props.nodes, attributes2.nodes) && sameList2(props["prune-backups"], attributes2["prune-backups"]) && same7(props.disable, attributes2.disable) && same7(props.shared, attributes2.shared) && same7(props.preallocation, attributes2.preallocation) && same7(props.comment, attributes2.comment);
5193
+
5194
+ // src/proxmox/storage.ts
5195
+ var ProxmoxStorage = Resource34("Proxmox.Storage", {
5196
+ defaultRemovalPolicy: "retain"
5197
+ });
5198
+ var ProxmoxStorageProvider = () => Provider34.effect(ProxmoxStorage, Effect65.succeed(ProxmoxStorage.Provider.of({
5199
+ list: () => Effect65.succeed([]),
5200
+ read: Effect65.fn(function* ({ olds, output }) {
5201
+ return dropUnreadable6(yield* output === undefined ? readStorage(olds) : readStorageOrFail(olds));
5167
5202
  }),
5168
- collection: () => "storage",
5169
- createForm: (props) => ({
5170
- ...locatorForm(props.locator),
5171
- ...mutable2(props),
5172
- storage: props.storage,
5173
- type: props.type
5203
+ diff: Effect65.fn(function* ({ news, output }) {
5204
+ if (!isResolved15(news))
5205
+ return;
5206
+ yield* guardWrite2(STORAGE_CREATE, createForm10(news), output === undefined);
5207
+ yield* guardWrite2(STORAGE_UPDATE, updateForm7(news), false);
5208
+ if (output === undefined)
5209
+ return;
5210
+ const live = yield* readStorageOrFail(news);
5211
+ if (live === UNREADABLE) {
5212
+ yield* unreadableWarning("Proxmox.Storage", news.storage);
5213
+ return { action: "noop" };
5214
+ }
5215
+ if (live === undefined) {
5216
+ yield* guardWrite2(STORAGE_CREATE, createForm10(news), true);
5217
+ return { action: "update" };
5218
+ }
5219
+ return matches7(live, news) ? { action: "noop" } : { action: "update" };
5174
5220
  }),
5175
- endpoint: { create: "pve:POST /storage", update: "pve:PUT /storage/{storage}" },
5176
- matches: (attributes2, props) => sameList2(props.content, attributes2.content) && sameList2(props.nodes, attributes2.nodes) && sameList2(props["prune-backups"], attributes2["prune-backups"]) && same7(props.disable, attributes2.disable) && same7(props.shared, attributes2.shared) && same7(props.preallocation, attributes2.preallocation) && same7(props.comment, attributes2.comment) && same7(props.maxfiles, attributes2.maxfiles),
5177
- path: (props) => `storage/${props.storage}`,
5178
- updateForm: mutable2
5179
- });
5180
- var ProxmoxStorageProvider = () => Provider34.effect(ProxmoxStorage, Effect64.succeed(ProxmoxStorage.Provider.of(handlers25)));
5221
+ reconcile: Effect65.fn(function* ({ news }) {
5222
+ const before = dropUnreadable6(yield* readStorage(news));
5223
+ yield* guardWrite2(STORAGE_CREATE, createForm10(news), before === undefined);
5224
+ yield* guardWrite2(STORAGE_UPDATE, updateForm7(news), false);
5225
+ if (before === undefined) {
5226
+ yield* runPve(news.target, "provision", true, storage2.createStorage(toDistilledCreate(news)));
5227
+ } else if (!matches7(before, news)) {
5228
+ yield* runPve(news.target, "provision", true, storage2.putStorage(toDistilledUpdate(news)));
5229
+ }
5230
+ const after = dropUnreadable6(yield* readStorage(news));
5231
+ if (after === undefined) {
5232
+ return yield* Effect65.die(new Error(`storage/${news.storage}: the write returned no error but the storage is still ` + 'absent. PVE wraps every answer in {"data":...} and can report success on a ' + "call that did nothing -- read back rather than trusting the status code."));
5233
+ }
5234
+ return after;
5235
+ }),
5236
+ delete: Effect65.fn(function* ({ olds }) {
5237
+ yield* runPve(olds.target, "provision", true, storage2.deleteStorage({ storage: olds.storage }));
5238
+ })
5239
+ })));
5181
5240
  // src/proxmox/zfs-pool.ts
5182
5241
  import { Resource as Resource35 } from "alchemy";
5242
+ import { isResolved as isResolved16 } from "alchemy/Diff";
5183
5243
  import * as Provider35 from "alchemy/Provider";
5184
- import * as Effect66 from "effect/Effect";
5244
+ import * as Effect68 from "effect/Effect";
5185
5245
 
5186
- // src/proxmox/zfs-pool-write.ts
5187
- import * as Effect65 from "effect/Effect";
5188
- var ZFS_POOL_ENDPOINT = { create: "pve:POST /nodes/{node}/disks/zfs" };
5189
- var zfsPoolEndpoint = (props) => props.devices === undefined || props.raidlevel === undefined ? {} : ZFS_POOL_ENDPOINT;
5190
- var createForm10 = (props) => ({
5246
+ // src/proxmox/zfs-pool-wire.ts
5247
+ import * as nodes from "@distilled.cloud/proxmox/nodes";
5248
+ import * as Effect66 from "effect/Effect";
5249
+ var leafDevices = (children) => Array.isArray(children) ? children.flatMap((entry) => {
5250
+ const vdev = entry;
5251
+ const nested = leafDevices(vdev.children);
5252
+ return nested.length > 0 ? nested : [text(vdev.name)].filter((name) => name !== "");
5253
+ }) : [];
5254
+ var attributesOf8 = (live, props) => ({
5255
+ devices: leafDevices(live.children).join(","),
5256
+ errors: text(live.errors, "unknown"),
5257
+ name: props.name,
5258
+ node: props.node,
5259
+ state: text(live.state, "unknown")
5260
+ });
5261
+ var readPoolOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, nodes.getNodeDiskZfs({ name: props.name, node: props.node }))).pipe(Effect66.map((live) => {
5262
+ if (live === UNREADABLE)
5263
+ return UNREADABLE;
5264
+ return text(live.name) === "" ? undefined : attributesOf8(live, props);
5265
+ }));
5266
+ var readPool = (props) => readPoolOrFail(props).pipe(Effect66.orElseSucceed(() => {
5267
+ return;
5268
+ }));
5269
+ var dropUnreadable7 = (live) => live === UNREADABLE ? undefined : live;
5270
+
5271
+ // src/proxmox/zfs-pool-form.ts
5272
+ import * as Effect67 from "effect/Effect";
5273
+ import * as nodes2 from "@distilled.cloud/proxmox/nodes";
5274
+ var ZFS_POOL_CREATE = "pve:POST /nodes/{node}/disks/zfs";
5275
+ var zfsPoolCreateEndpoint = (props) => props.devices === undefined || props.raidlevel === undefined ? undefined : ZFS_POOL_CREATE;
5276
+ var createForm11 = (props) => ({
5191
5277
  ...props.devices === undefined ? {} : { devices: props.devices.join(",") },
5192
5278
  name: props.name,
5193
5279
  ...props.raidlevel === undefined ? {} : { raidlevel: props.raidlevel },
@@ -5195,68 +5281,72 @@ var createForm10 = (props) => ({
5195
5281
  ...props.compression === undefined ? {} : { compression: props.compression },
5196
5282
  ...props["draid-config"] === undefined ? {} : { "draid-config": props["draid-config"] }
5197
5283
  });
5284
+ var toDistilledCreate2 = (props) => {
5285
+ const form = createForm11(props);
5286
+ return {
5287
+ ...form,
5288
+ draid_config: form["draid-config"],
5289
+ node: props.node
5290
+ };
5291
+ };
5198
5292
  var SETTLE_ATTEMPTS = 30;
5199
- var createPool = (props, collection2, path2, read4) => Effect65.gen(function* () {
5293
+ var createPool = (props, read4) => Effect67.gen(function* () {
5200
5294
  const existing = yield* read4(props);
5201
5295
  if (existing !== undefined)
5202
5296
  return existing;
5203
5297
  if (props.devices === undefined || props.raidlevel === undefined) {
5204
- return yield* Effect65.die(new Error(`${props.node}/${props.name}: this is an adopt-only declaration (no \`devices\` or ` + "`raidlevel`) and the pool is not there to adopt. An adopt-only Proxmox.ZfsPool never " + "creates -- declare both fields for a pool this resource should build, or point this " + "declaration at a pool that already exists on this node."));
5298
+ return yield* Effect67.die(new Error(`${props.node}/${props.name}: this is an adopt-only declaration (no \`devices\` or ` + "`raidlevel`) and the pool is not there to adopt. An adopt-only Proxmox.ZfsPool never " + "creates -- declare both fields for a pool this resource should build, or point this " + "declaration at a pool that already exists on this node."));
5205
5299
  }
5206
- const upid = yield* pve(props.target, "provision", "POST", collection2, createForm10(props));
5207
- const settle4 = (attempts) => Effect65.gen(function* () {
5300
+ yield* guardForm(zfsPoolCreateEndpoint(props), asForm2(createForm11(props)), true);
5301
+ const upid = yield* runPve(props.target, "provision", true, nodes2.createNodeDiskZfs(toDistilledCreate2(props)));
5302
+ const settle4 = (attempts) => Effect67.gen(function* () {
5208
5303
  const live = yield* read4(props);
5209
5304
  if (live !== undefined || attempts <= 0)
5210
5305
  return live;
5211
- yield* Effect65.sleep("2 seconds");
5306
+ yield* Effect67.sleep("2 seconds");
5212
5307
  return yield* settle4(attempts - 1);
5213
5308
  });
5214
5309
  const after = yield* settle4(SETTLE_ATTEMPTS);
5215
5310
  if (after === undefined) {
5216
- return yield* Effect65.die(new Error(`${path2}: POST returned ${text(upid, "(no UPID)")} but the pool has not appeared. That ` + "POST only forks a `zfscreate` worker, so the task holds the real error -- read it " + `with \`pvesh get /nodes/${props.node}/tasks/<upid>/log\`. NOTHING WAS RETRIED AND ` + "NOTHING WAS CLEANED UP: if the worker reached `zpool create`, the declared devices " + "have already been written to."));
5311
+ return yield* Effect67.die(new Error(`nodes/${props.node}/disks/zfs/${props.name}: POST returned ${text(upid, "(no UPID)")} ` + "but the pool has not appeared. That POST only forks a `zfscreate` worker, so the task " + `holds the real error -- read it with \`pvesh get /nodes/${props.node}/tasks/<upid>/log\`. ` + "NOTHING WAS RETRIED AND NOTHING WAS CLEANED UP: if the worker reached `zpool create`, " + "the declared devices have already been written to. DO NOT RE-RUN THIS DEPLOY BEFORE " + 'READING THAT LOG: `read` cannot tell "the worker is still running" from "the pool is ' + 'genuinely gone", so a re-run this soon can POST a SECOND `zpool create` at the SAME ' + "devices while the first one is still mid-write -- confirm the task finished (one way " + "or the other) before trying again."));
5217
5312
  }
5218
5313
  return after;
5219
5314
  });
5220
- var destroyPool = (olds, path2) => pve(olds.target, "provision", "DELETE", path2);
5221
-
5222
- // src/proxmox/zfs-pool-spec.ts
5223
- var leafDevices = (children) => Array.isArray(children) ? children.flatMap((entry) => {
5224
- const vdev = entry;
5225
- const nested = leafDevices(vdev.children);
5226
- return nested.length > 0 ? nested : [text(vdev.name)].filter((name) => name !== "");
5227
- }) : [];
5228
- var spec2 = {
5229
- attributes: (live, props) => {
5230
- if (text(live["name"]) === "")
5231
- return;
5232
- return {
5233
- devices: leafDevices(live["children"]).join(","),
5234
- errors: text(live["errors"], "unknown"),
5235
- name: props.name,
5236
- node: props.node,
5237
- state: text(live["state"], "unknown")
5238
- };
5239
- },
5240
- collection: (props) => `nodes/${props.node}/disks/zfs`,
5241
- createForm: createForm10,
5242
- endpoint: zfsPoolEndpoint,
5243
- matches: () => true,
5244
- path: (props) => `nodes/${props.node}/disks/zfs/${props.name}`
5245
- };
5315
+ var destroyPool = (props) => runPve(props.target, "provision", true, nodes2.deleteNodeDiskZfs({ name: props.name, node: props.node }));
5246
5316
 
5247
5317
  // src/proxmox/zfs-pool.ts
5248
5318
  var ProxmoxZfsPool = Resource35("Proxmox.ZfsPool", {
5249
5319
  defaultRemovalPolicy: "retain"
5250
5320
  });
5251
- var ops3 = pveOperations(spec2);
5252
- var handlers26 = {
5253
- ...pveHandlers(spec2),
5254
- delete: Effect66.fn(function* ({ olds }) {
5255
- yield* destroyPool(olds, spec2.path(olds));
5321
+ var ProxmoxZfsPoolProvider = () => Provider35.effect(ProxmoxZfsPool, Effect68.succeed(ProxmoxZfsPool.Provider.of({
5322
+ list: () => Effect68.succeed([]),
5323
+ read: Effect68.fn(function* ({ olds, output }) {
5324
+ return dropUnreadable7(yield* output === undefined ? readPool(olds) : readPoolOrFail(olds));
5256
5325
  }),
5257
- reconcile: ({ news }) => createPool(news, spec2.collection(news), spec2.path(news), ops3.read)
5258
- };
5259
- var ProxmoxZfsPoolProvider = () => Provider35.effect(ProxmoxZfsPool, Effect66.succeed(ProxmoxZfsPool.Provider.of(handlers26)));
5326
+ diff: Effect68.fn(function* ({ news, output }) {
5327
+ if (!isResolved16(news))
5328
+ return;
5329
+ yield* guardForm(zfsPoolCreateEndpoint(news), asForm2(createForm11(news)), output === undefined);
5330
+ if (output === undefined)
5331
+ return;
5332
+ const live = yield* readPoolOrFail(news);
5333
+ if (live === UNREADABLE) {
5334
+ yield* unreadableWarning("Proxmox.ZfsPool", `${news.node}/${news.name}`);
5335
+ return { action: "noop" };
5336
+ }
5337
+ if (live === undefined) {
5338
+ yield* guardForm(zfsPoolCreateEndpoint(news), asForm2(createForm11(news)), true);
5339
+ return { action: "update" };
5340
+ }
5341
+ return { action: "noop" };
5342
+ }),
5343
+ reconcile: Effect68.fn(function* ({ news }) {
5344
+ return yield* createPool(news, (props) => readPool(props).pipe(Effect68.map(dropUnreadable7)));
5345
+ }),
5346
+ delete: Effect68.fn(function* ({ olds }) {
5347
+ yield* destroyPool(olds);
5348
+ })
5349
+ })));
5260
5350
  export {
5261
5351
  PROVISION_DEFAULTS,
5262
5352
  PROVISION_PRIVILEGES,
@@ -5333,5 +5423,5 @@ export {
5333
5423
  violations
5334
5424
  };
5335
5425
 
5336
- //# debugId=E83D3C3771546F7064756E2164756E21
5426
+ //# debugId=D100179D867AAA0364756E2164756E21
5337
5427
  //# sourceMappingURL=index.js.map