@homeflare/alchemy 0.37.0 → 0.37.2

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 (73) hide show
  1. package/dist/proxmox/ceph-daemon-wire.d.ts +5 -7
  2. package/dist/proxmox/ceph-daemon-wire.d.ts.map +1 -1
  3. package/dist/proxmox/ceph-daemon.d.ts +7 -8
  4. package/dist/proxmox/ceph-daemon.d.ts.map +1 -1
  5. package/dist/proxmox/ceph-fs-distilled.d.ts +31 -5
  6. package/dist/proxmox/ceph-fs-distilled.d.ts.map +1 -1
  7. package/dist/proxmox/ceph-fs-wire.d.ts +5 -22
  8. package/dist/proxmox/ceph-fs-wire.d.ts.map +1 -1
  9. package/dist/proxmox/ceph-fs.d.ts +5 -6
  10. package/dist/proxmox/ceph-fs.d.ts.map +1 -1
  11. package/dist/proxmox/ceph-pool-settle.d.ts +9 -8
  12. package/dist/proxmox/ceph-pool-settle.d.ts.map +1 -1
  13. package/dist/proxmox/ceph-pool-wire.d.ts +11 -20
  14. package/dist/proxmox/ceph-pool-wire.d.ts.map +1 -1
  15. package/dist/proxmox/group-wire.d.ts +8 -13
  16. package/dist/proxmox/group-wire.d.ts.map +1 -1
  17. package/dist/proxmox/index.js +296 -326
  18. package/dist/proxmox/index.js.map +14 -14
  19. package/dist/proxmox/node-network-wire.d.ts +1 -1
  20. package/dist/proxmox/node-network-wire.d.ts.map +1 -1
  21. package/dist/proxmox/storage-wire.d.ts +8 -11
  22. package/dist/proxmox/storage-wire.d.ts.map +1 -1
  23. package/dist/proxmox/unreadable-read.d.ts +7 -7
  24. package/dist/proxmox/user-wire.d.ts +8 -11
  25. package/dist/proxmox/user-wire.d.ts.map +1 -1
  26. package/dist/proxmox/user.d.ts +5 -5
  27. package/dist/proxmox/zfs-pool-wire.d.ts +1 -1
  28. package/dist/proxmox/zfs-pool-wire.d.ts.map +1 -1
  29. package/docs/changelog/README.md +22 -0
  30. package/docs/changelog/archive-01.md +176 -0
  31. package/docs/changelog/archive-02.md +180 -0
  32. package/docs/changelog/archive-03.md +179 -0
  33. package/docs/changelog/archive-04.md +178 -0
  34. package/docs/changelog/archive-05.md +177 -0
  35. package/docs/changelog/archive-06.md +180 -0
  36. package/docs/changelog/archive-07.md +180 -0
  37. package/docs/changelog/archive-08.md +178 -0
  38. package/docs/changelog/archive-09.md +181 -0
  39. package/docs/changelog/archive-10.md +182 -0
  40. package/docs/changelog/archive-11.md +182 -0
  41. package/docs/changelog/archive-12.md +183 -0
  42. package/docs/changelog/archive-13.md +180 -0
  43. package/docs/changelog/archive-14.md +178 -0
  44. package/docs/changelog/archive-15.md +181 -0
  45. package/docs/changelog/archive-16.md +182 -0
  46. package/docs/changelog/archive-17.md +183 -0
  47. package/docs/changelog/archive-18.md +55 -0
  48. package/docs/distilled-interim.md +15 -3
  49. package/docs/provider-standard.md +24 -6
  50. package/docs/proxmox.md +26 -0
  51. package/docs/upstream-conformance-bun.md +67 -0
  52. package/docs/upstream-conformance-conforms.md +55 -0
  53. package/docs/upstream-conformance-families.md +95 -0
  54. package/docs/upstream-conformance-grafana.md +106 -0
  55. package/docs/upstream-conformance.md +20 -298
  56. package/package.json +3 -3
  57. package/src/proxmox/ceph-daemon-wire.ts +4 -7
  58. package/src/proxmox/ceph-daemon.ts +7 -8
  59. package/src/proxmox/ceph-fs-delete.test.ts +5 -8
  60. package/src/proxmox/ceph-fs-destroy-sdk.test.ts +98 -0
  61. package/src/proxmox/ceph-fs-distilled.ts +45 -19
  62. package/src/proxmox/ceph-fs-wire.ts +5 -93
  63. package/src/proxmox/ceph-fs.ts +13 -15
  64. package/src/proxmox/ceph-pool-settle.ts +11 -10
  65. package/src/proxmox/ceph-pool-wire.ts +11 -20
  66. package/src/proxmox/ceph-pool-write.test.ts +9 -8
  67. package/src/proxmox/group-wire.ts +7 -12
  68. package/src/proxmox/read-failure-propagation.test.ts +5 -5
  69. package/src/proxmox/storage-wire.ts +9 -10
  70. package/src/proxmox/typed-absence.test.ts +146 -0
  71. package/src/proxmox/unreadable-read.ts +7 -7
  72. package/src/proxmox/user-wire.ts +7 -10
  73. package/src/proxmox/user.ts +5 -5
@@ -1690,9 +1690,7 @@ var listRows = (props) => {
1690
1690
  return runPve(props.target, "read", false, nodes.listNodeCephMds({ node })).pipe(Effect13.map((rows) => rows));
1691
1691
  }
1692
1692
  };
1693
- var readDaemon = (props) => listRows(props).pipe(Effect13.map((rows) => daemonAttributes(rows, props)), Effect13.orElseSucceed(() => {
1694
- return;
1695
- }));
1693
+ var readDaemon = (props) => listRows(props).pipe(Effect13.map((rows) => daemonAttributes(rows, props)));
1696
1694
  var createDaemon = (props) => {
1697
1695
  const node = props.node;
1698
1696
  const id = daemonId(props);
@@ -1790,14 +1788,13 @@ var ProxmoxCephFlagProvider = () => Provider5.effect(ProxmoxCephFlag, Effect15.s
1790
1788
  import { Resource as Resource6 } from "alchemy";
1791
1789
  import { isResolved as isResolved5 } from "alchemy/Diff";
1792
1790
  import * as Provider6 from "alchemy/Provider";
1793
- import * as Effect18 from "effect/Effect";
1791
+ import * as Effect17 from "effect/Effect";
1794
1792
 
1795
1793
  // src/proxmox/ceph-fs-distilled.ts
1796
1794
  import * as nodes2 from "@distilled.cloud/proxmox/nodes";
1797
- import * as Effect17 from "effect/Effect";
1795
+ import * as Effect16 from "effect/Effect";
1798
1796
 
1799
1797
  // src/proxmox/ceph-fs-wire.ts
1800
- import * as Effect16 from "effect/Effect";
1801
1798
  var readRow = (live, props) => {
1802
1799
  const row = (Array.isArray(live) ? live : []).filter((entry) => typeof entry === "object" && entry !== null).find((entry) => entry["name"] === props.name);
1803
1800
  if (row === undefined)
@@ -1819,77 +1816,58 @@ var createForm2 = (props) => ({
1819
1816
  ...field("add-storage", flag(props["add-storage"])),
1820
1817
  ...field("pg_num", props.pg_num === undefined ? undefined : String(props.pg_num))
1821
1818
  });
1822
- var destroyPath = (props) => {
1823
- const query = [
1824
- props["remove-pools"] === true ? "remove-pools=1" : undefined,
1825
- props["remove-storages"] === true ? "remove-storages=1" : undefined
1826
- ].filter((part) => part !== undefined);
1827
- return query.length === 0 ? objectPath(props) : `${objectPath(props)}?${query.join("&")}`;
1828
- };
1829
- var settle = (target, node, upid, what) => Effect16.gen(function* () {
1830
- for (let attempt = 0;attempt < POLL_ATTEMPTS; attempt += 1) {
1831
- const status = yield* pve(target, "read", "GET", `nodes/${node}/tasks/${encodeURIComponent(upid)}/status`).pipe(Effect16.orElseSucceed(() => {
1832
- return;
1833
- }));
1834
- if (status?.status === "stopped") {
1835
- const exit = text(status.exitstatus);
1836
- if (exit === "OK")
1837
- return;
1838
- return yield* Effect16.die(new Error(`${what}: PVE task ${upid} finished with "${exit === "" ? "no exit status" : exit}". ` + "The write returned HTTP 200 because it only forked the worker -- the real error is " + `in \`pvesh get /nodes/${node}/tasks/${upid}/log\`.`));
1839
- }
1840
- yield* Effect16.sleep(POLL_SECONDS * 1000);
1841
- }
1842
- return yield* Effect16.die(new Error(`${what}: PVE task ${upid} was still running after ` + `${String(POLL_ATTEMPTS * POLL_SECONDS)}s, or its ` + "status could not be read. Check the task log, and check that the `read` role holds " + `Sys.Audit on /nodes/${node} -- each call mints a new token, so the poller is never the ` + "task owner and is answered 403 rather than told to wait."));
1843
- });
1844
- var destroyFs = (props) => Effect16.gen(function* () {
1845
- const upid = text(yield* pve(props.target, "provision", "DELETE", destroyPath(props)));
1846
- if (upid !== "")
1847
- yield* settle(props.target, props.node, upid, destroyPath(props));
1848
- });
1849
1819
  var notCreated2 = (props) => new Error(`${objectPath(props)}: the create task finished but the filesystem is not in ` + `GET nodes/${props.node}/ceph/fs. Check the task log -- a PVE worker can exit having ` + "rolled back the pools it had just made.");
1850
1820
  var notDestroyed = (props) => new Error(`${objectPath(props)}: the destroy task finished but the filesystem is still in ` + `GET nodes/${props.node}/ceph/fs. PVE refuses to destroy a CephFS while a PVE storage entry ` + "of type cephfs still references it and is not disabled.");
1851
1821
 
1852
1822
  // src/proxmox/ceph-fs-distilled.ts
1853
- var readFs = (props) => runPve(props.target, "read", false, nodes2.listNodeCephFs({ node: props.node })).pipe(Effect17.map((rows) => readRow(rows, props)), Effect17.orElseSucceed(() => {
1854
- return;
1855
- }));
1823
+ var readFs = (props) => runPve(props.target, "read", false, nodes2.listNodeCephFs({ node: props.node })).pipe(Effect16.map((rows) => readRow(rows, props)));
1856
1824
  var toDistilledCreate = (props) => ({
1857
1825
  ...createForm2(props),
1858
1826
  name: props.name,
1859
1827
  node: props.node
1860
1828
  });
1861
- var settleCreate = (props, upid) => Effect17.gen(function* () {
1829
+ var settleTask = (props, upid) => Effect16.gen(function* () {
1862
1830
  for (let attempt = 0;attempt < POLL_ATTEMPTS; attempt += 1) {
1863
- const status = yield* runPve(props.target, "read", false, nodes2.getNodeTaskStatus({ node: props.node, upid })).pipe(Effect17.orElseSucceed(() => {
1831
+ const status = yield* runPve(props.target, "read", false, nodes2.getNodeTaskStatus({ node: props.node, upid })).pipe(Effect16.orElseSucceed(() => {
1864
1832
  return;
1865
1833
  }));
1866
1834
  if (status?.status === "stopped") {
1867
1835
  if (status.exitstatus === "OK")
1868
1836
  return;
1869
- return yield* Effect17.die(new Error(`${objectPath(props)}: PVE task ${upid} finished with "${status.exitstatus ?? "no exit status"}". ` + "The write returned HTTP 200 because it only forked the worker -- the real error is " + `in \`pvesh get /nodes/${props.node}/tasks/${upid}/log\`.`));
1837
+ return yield* Effect16.die(new Error(`${objectPath(props)}: PVE task ${upid} finished with "${status.exitstatus ?? "no exit status"}". ` + "The write returned HTTP 200 because it only forked the worker -- the real error is " + `in \`pvesh get /nodes/${props.node}/tasks/${upid}/log\`.`));
1870
1838
  }
1871
- yield* Effect17.sleep(POLL_SECONDS * 1000);
1839
+ yield* Effect16.sleep(POLL_SECONDS * 1000);
1872
1840
  }
1873
- return yield* Effect17.die(new Error(`${objectPath(props)}: PVE task ${upid} was still running after ` + `${String(POLL_ATTEMPTS * POLL_SECONDS)}s, or its status could not be read. Check the ` + "task log, and check that the `read` role holds Sys.Audit on " + `/nodes/${props.node} -- each call mints a new token, so the poller is never the task ` + "owner and is answered 403 rather than told to wait."));
1841
+ return yield* Effect16.die(new Error(`${objectPath(props)}: PVE task ${upid} was still running after ` + `${String(POLL_ATTEMPTS * POLL_SECONDS)}s, or its status could not be read. Check the ` + "task log, and check that the `read` role holds Sys.Audit on " + `/nodes/${props.node} -- each call mints a new token, so the poller is never the task ` + "owner and is answered 403 rather than told to wait."));
1874
1842
  });
1875
- var createFs = (props) => Effect17.gen(function* () {
1843
+ var createFs = (props) => Effect16.gen(function* () {
1876
1844
  const upid = yield* runPve(props.target, "provision", true, nodes2.updateNodeCephFs(toDistilledCreate(props)));
1877
1845
  if (upid === "") {
1878
- return yield* Effect17.die(new Error(`${objectPath(props)}: POST returned no task id. PVE wraps every answer in ` + '{"data":...} and can report success on a call that did nothing.'));
1846
+ return yield* Effect16.die(new Error(`${objectPath(props)}: POST returned no task id. PVE wraps every answer in ` + '{"data":...} and can report success on a call that did nothing.'));
1879
1847
  }
1880
- yield* settleCreate(props, upid);
1848
+ yield* settleTask(props, upid);
1849
+ });
1850
+ var destroyFs = (props) => Effect16.gen(function* () {
1851
+ const upid = yield* runPve(props.target, "provision", true, nodes2.deleteNodeCephFs({
1852
+ node: props.node,
1853
+ name: props.name,
1854
+ ...props["remove-pools"] === true ? { remove_pools: "1" } : {},
1855
+ ...props["remove-storages"] === true ? { remove_storages: "1" } : {}
1856
+ })).pipe(Effect16.catchTag("CephFsNotFound", () => Effect16.succeed("")));
1857
+ if (upid !== "")
1858
+ yield* settleTask(props, upid);
1881
1859
  });
1882
1860
 
1883
1861
  // src/proxmox/ceph-fs.ts
1884
1862
  var ProxmoxCephFs = Resource6("Proxmox.CephFs", {
1885
1863
  defaultRemovalPolicy: "retain"
1886
1864
  });
1887
- var ProxmoxCephFsProvider = () => Provider6.effect(ProxmoxCephFs, Effect18.succeed(ProxmoxCephFs.Provider.of({
1888
- list: () => Effect18.succeed([]),
1889
- read: Effect18.fn(function* ({ olds }) {
1865
+ var ProxmoxCephFsProvider = () => Provider6.effect(ProxmoxCephFs, Effect17.succeed(ProxmoxCephFs.Provider.of({
1866
+ list: () => Effect17.succeed([]),
1867
+ read: Effect17.fn(function* ({ olds }) {
1890
1868
  return yield* readFs(olds);
1891
1869
  }),
1892
- diff: Effect18.fn(function* ({ news, output }) {
1870
+ diff: Effect17.fn(function* ({ news, output }) {
1893
1871
  if (!isResolved5(news))
1894
1872
  return;
1895
1873
  yield* guardWrite2(CEPH_FS_CREATE, createForm2(news), output === undefined);
@@ -1905,34 +1883,34 @@ var ProxmoxCephFsProvider = () => Provider6.effect(ProxmoxCephFs, Effect18.succe
1905
1883
  }
1906
1884
  return { action: "noop" };
1907
1885
  }),
1908
- reconcile: Effect18.fn(function* ({ news }) {
1886
+ reconcile: Effect17.fn(function* ({ news }) {
1909
1887
  const live = yield* readFs(news);
1910
1888
  if (live !== undefined)
1911
1889
  return live;
1912
1890
  yield* createFs(news);
1913
1891
  const after = yield* readFs(news);
1914
1892
  if (after === undefined)
1915
- return yield* Effect18.die(notCreated2(news));
1893
+ return yield* Effect17.die(notCreated2(news));
1916
1894
  return after;
1917
1895
  }),
1918
- delete: Effect18.fn(function* ({ olds }) {
1896
+ delete: Effect17.fn(function* ({ olds }) {
1919
1897
  if ((yield* readFs(olds)) === undefined)
1920
1898
  return;
1921
1899
  yield* destroyFs(olds);
1922
1900
  const after = yield* readFs(olds);
1923
1901
  if (after !== undefined)
1924
- return yield* Effect18.die(notDestroyed(olds));
1902
+ return yield* Effect17.die(notDestroyed(olds));
1925
1903
  })
1926
1904
  })));
1927
1905
  // src/proxmox/ceph-osd.ts
1928
1906
  import { Resource as Resource7 } from "alchemy";
1929
1907
  import { isResolved as isResolved6 } from "alchemy/Diff";
1930
1908
  import * as Provider7 from "alchemy/Provider";
1931
- import * as Effect21 from "effect/Effect";
1909
+ import * as Effect20 from "effect/Effect";
1932
1910
 
1933
1911
  // src/proxmox/ceph-osd-tree.ts
1934
1912
  import * as nodes3 from "@distilled.cloud/proxmox/nodes";
1935
- import * as Effect19 from "effect/Effect";
1913
+ import * as Effect18 from "effect/Effect";
1936
1914
  var branches = (node) => (Array.isArray(node["children"]) ? node["children"] : []).filter((child) => typeof child === "object" && child !== null);
1937
1915
  var osdLeaves = (tree) => {
1938
1916
  const root = tree["root"];
@@ -1958,23 +1936,23 @@ var osdAttributes = (leaf, props) => ({
1958
1936
  status: text(leaf["status"]),
1959
1937
  total_space: num(leaf["total_space"], 0)
1960
1938
  });
1961
- var readOsd = (props) => runPve(props.target, "read", false, nodes3.getNodeCephOsd({ node: props.node })).pipe(Effect19.map((t) => {
1939
+ var readOsd = (props) => runPve(props.target, "read", false, nodes3.getNodeCephOsd({ node: props.node })).pipe(Effect18.map((t) => {
1962
1940
  const leaf = findOsd(t, props.osdid);
1963
1941
  return leaf === undefined ? undefined : osdAttributes(leaf, props);
1964
1942
  }));
1965
1943
 
1966
1944
  // src/proxmox/ceph-osd-write.ts
1967
1945
  import * as nodes4 from "@distilled.cloud/proxmox/nodes";
1968
- import * as Effect20 from "effect/Effect";
1946
+ import * as Effect19 from "effect/Effect";
1969
1947
  var OSD_CREATE_ENDPOINT = "pve:POST /nodes/{node}/ceph/osd";
1970
1948
  var describe = (props) => `osd.${String(props.osdid)} on ${props.node}`;
1971
1949
  var createOsdForm = (props, dev) => ({
1972
1950
  dev,
1973
1951
  ...props.device_class === undefined ? {} : { "crush-device-class": props.device_class }
1974
1952
  });
1975
- var createOsd = Effect20.fn(function* (news) {
1953
+ var createOsd = Effect19.fn(function* (news) {
1976
1954
  if (news.dev === undefined) {
1977
- return yield* Effect20.die(new Error(`${describe(news)}: no such OSD in the CRUSH tree, and no \`dev\` was declared. ` + "Without a device this resource is an ASSERTION over an OSD that must already " + "exist. Declare `dev` to let it create one -- which WIPES that device -- or fix " + "the declaration; if the disk was there yesterday, a replica is missing and Ceph " + "is degraded."));
1955
+ return yield* Effect19.die(new Error(`${describe(news)}: no such OSD in the CRUSH tree, and no \`dev\` was declared. ` + "Without a device this resource is an ASSERTION over an OSD that must already " + "exist. Declare `dev` to let it create one -- which WIPES that device -- or fix " + "the declaration; if the disk was there yesterday, a replica is missing and Ceph " + "is degraded."));
1978
1956
  }
1979
1957
  const form = createOsdForm(news, news.dev);
1980
1958
  yield* guardForm(OSD_CREATE_ENDPOINT, form, true);
@@ -1985,7 +1963,7 @@ var createOsd = Effect20.fn(function* (news) {
1985
1963
  }));
1986
1964
  const created = yield* readOsd(news);
1987
1965
  if (created === undefined) {
1988
- return yield* Effect20.die(new Error(`${describe(news)}: the create returned no error but osd.${String(news.osdid)} is ` + "still absent. Ceph allocates OSD ids and cannot be told which to use, so it most " + "likely assigned a different number -- check `ceph osd tree`, and declare the id it " + "actually gave the device rather than deploying again."));
1966
+ return yield* Effect19.die(new Error(`${describe(news)}: the create returned no error but osd.${String(news.osdid)} is ` + "still absent. Ceph allocates OSD ids and cannot be told which to use, so it most " + "likely assigned a different number -- check `ceph osd tree`, and declare the id it " + "actually gave the device rather than deploying again."));
1989
1967
  }
1990
1968
  return created;
1991
1969
  });
@@ -2002,11 +1980,11 @@ var ProxmoxCephOsd = Resource7("Proxmox.CephOsd", {
2002
1980
  var settled = (live, props) => (props.host === undefined || props.host === live.host) && (props.device_class === undefined || props.device_class === live.device_class);
2003
1981
  var describe2 = (props) => `osd.${String(props.osdid)} (read via nodes/${props.node}/ceph/osd)`;
2004
1982
  var handlers3 = {
2005
- list: () => Effect21.succeed([]),
2006
- read: Effect21.fn(function* ({ olds }) {
1983
+ list: () => Effect20.succeed([]),
1984
+ read: Effect20.fn(function* ({ olds }) {
2007
1985
  return yield* readOsd(olds);
2008
1986
  }),
2009
- diff: Effect21.fn(function* ({
1987
+ diff: Effect20.fn(function* ({
2010
1988
  news,
2011
1989
  output
2012
1990
  }) {
@@ -2019,27 +1997,27 @@ var handlers3 = {
2019
1997
  return { action: "update" };
2020
1998
  return settled(live, news) ? { action: "noop" } : { action: "update" };
2021
1999
  }),
2022
- reconcile: Effect21.fn(function* ({ news }) {
2000
+ reconcile: Effect20.fn(function* ({ news }) {
2023
2001
  const live = yield* readOsd(news);
2024
2002
  if (live === undefined) {
2025
2003
  return yield* createOsd(news);
2026
2004
  }
2027
2005
  if (!settled(live, news)) {
2028
- return yield* Effect21.die(new Error(`${describe2(news)}: exists but not as declared -- live host=${live.host} ` + `device_class=${live.device_class}. Nothing here moves an OSD between hosts or ` + "reclassifies it; fix the declaration, or move it deliberately with `ceph osd crush " + "move` / `ceph osd crush set-device-class` and deploy again."));
2006
+ return yield* Effect20.die(new Error(`${describe2(news)}: exists but not as declared -- live host=${live.host} ` + `device_class=${live.device_class}. Nothing here moves an OSD between hosts or ` + "reclassifies it; fix the declaration, or move it deliberately with `ceph osd crush " + "move` / `ceph osd crush set-device-class` and deploy again."));
2029
2007
  }
2030
2008
  return live;
2031
2009
  }),
2032
- delete: Effect21.fn(function* ({ olds }) {
2010
+ delete: Effect20.fn(function* ({ olds }) {
2033
2011
  yield* destroyOsd(olds);
2034
2012
  })
2035
2013
  };
2036
- var ProxmoxCephOsdProvider = () => Provider7.effect(ProxmoxCephOsd, Effect21.succeed(ProxmoxCephOsd.Provider.of(handlers3)));
2014
+ var ProxmoxCephOsdProvider = () => Provider7.effect(ProxmoxCephOsd, Effect20.succeed(ProxmoxCephOsd.Provider.of(handlers3)));
2037
2015
  // src/proxmox/ceph-pool.ts
2038
2016
  import { Resource as Resource8 } from "alchemy";
2039
2017
  import { isResolved as isResolved7 } from "alchemy/Diff";
2040
2018
  import * as Provider8 from "alchemy/Provider";
2041
2019
  import * as nodes7 from "@distilled.cloud/proxmox/nodes";
2042
- import * as Effect24 from "effect/Effect";
2020
+ import * as Effect23 from "effect/Effect";
2043
2021
 
2044
2022
  // src/proxmox/ceph-pool-form.ts
2045
2023
  var object = (props) => `nodes/${props.node}/ceph/pool/${props.name}`;
@@ -2068,21 +2046,21 @@ var createBody = (props) => ({
2068
2046
 
2069
2047
  // src/proxmox/ceph-pool-settle.ts
2070
2048
  import * as nodes5 from "@distilled.cloud/proxmox/nodes";
2071
- import * as Effect22 from "effect/Effect";
2072
- var confirmAbsent = (props, describe3) => runPve(props.target, "read", false, nodes5.listNodeCephPool({ node: props.node })).pipe(Effect22.flatMap((rows) => rows.some((row) => row.pool_name === props.name) ? Effect22.die(new Error(`${describe3}: the cluster lists this pool but its status could not be read, ` + "so this deploy will NOT create over it. Check that the node is up and that the " + "read role holds Sys.Audit or Datastore.Audit on / -- a create here would apply " + "pg_num to a live pool and start a PG merge.")) : Effect22.void));
2073
- var settle2 = (props, read, done) => Effect22.gen(function* () {
2049
+ import * as Effect21 from "effect/Effect";
2050
+ var confirmAbsent = (props, describe3) => runPve(props.target, "read", false, nodes5.listNodeCephPool({ node: props.node })).pipe(Effect21.flatMap((rows) => rows.some((row) => row.pool_name === props.name) ? Effect21.die(new Error(`${describe3}: the cluster lists this pool but its status could not be read, ` + "so this deploy will NOT create over it. Check that the node is up and that the " + "read role holds Sys.Audit or Datastore.Audit on / -- a create here would apply " + "pg_num to a live pool and start a PG merge.")) : Effect21.void));
2051
+ var settle = (props, read, done) => Effect21.gen(function* () {
2074
2052
  for (let attempt = 0;attempt < 30; attempt += 1) {
2075
2053
  const live = yield* read(props);
2076
2054
  if (done(live))
2077
2055
  return live;
2078
- yield* Effect22.sleep("2 seconds");
2056
+ yield* Effect21.sleep("2 seconds");
2079
2057
  }
2080
2058
  return yield* read(props);
2081
2059
  });
2082
2060
 
2083
2061
  // src/proxmox/ceph-pool-wire.ts
2084
2062
  import * as nodes6 from "@distilled.cloud/proxmox/nodes";
2085
- import * as Effect23 from "effect/Effect";
2063
+ import * as Effect22 from "effect/Effect";
2086
2064
  var attributesOf3 = (live, props) => {
2087
2065
  const row = live;
2088
2066
  if (typeof row["name"] !== "string")
@@ -2105,9 +2083,7 @@ var attributesOf3 = (live, props) => {
2105
2083
  target_size_ratio: num(row["target_size_ratio"], UNSET)
2106
2084
  };
2107
2085
  };
2108
- var readPoolStatus = (props) => runPve(props.target, "read", false, nodes6.getNodeCephPoolStatus({ name: props.name, node: props.node, verbose: "1" })).pipe(Effect23.map((live) => attributesOf3(live, props)), Effect23.orElseSucceed(() => {
2109
- return;
2110
- }));
2086
+ var readPoolStatus = (props) => runPve(props.target, "read", false, nodes6.getNodeCephPoolStatus({ name: props.name, node: props.node, verbose: "1" })).pipe(Effect22.map((live) => attributesOf3(live, props)), Effect22.catchTag("CephPoolNotFound", () => Effect22.succeed(undefined)));
2111
2087
  var CEPH_POOL_CREATE = "pve:POST /nodes/{node}/ceph/pool";
2112
2088
  var CEPH_POOL_UPDATE = "pve:PUT /nodes/{node}/ceph/pool/{name}";
2113
2089
  var toDistilledCreate2 = (props) => ({
@@ -2125,10 +2101,10 @@ var ProxmoxCephPool = Resource8("Proxmox.CephPool", {
2125
2101
  defaultRemovalPolicy: "retain"
2126
2102
  });
2127
2103
  var matches3 = (attributes, props) => same(props.size, attributes.size, attributes.nosizechange) && same(props.min_size, attributes.min_size, attributes.nosizechange) && same(props.pg_autoscale_mode, attributes.pg_autoscale_mode) && same(hint(props.pg_num_min), attributes.pg_num_min, attributes.nopgchange) && same(props.crush_rule, attributes.crush_rule, attributes.crush_rule === "") && same(hint(props.target_size), attributes.target_size);
2128
- var ProxmoxCephPoolProvider = () => Provider8.effect(ProxmoxCephPool, Effect24.succeed(ProxmoxCephPool.Provider.of({
2129
- list: () => Effect24.succeed([]),
2104
+ var ProxmoxCephPoolProvider = () => Provider8.effect(ProxmoxCephPool, Effect23.succeed(ProxmoxCephPool.Provider.of({
2105
+ list: () => Effect23.succeed([]),
2130
2106
  read: ({ olds }) => readPoolStatus(olds),
2131
- diff: Effect24.fn(function* ({ news, output }) {
2107
+ diff: Effect23.fn(function* ({ news, output }) {
2132
2108
  if (!isResolved7(news))
2133
2109
  return;
2134
2110
  yield* guardWrite2(CEPH_POOL_CREATE, createBody(news), output === undefined);
@@ -2142,7 +2118,7 @@ var ProxmoxCephPoolProvider = () => Provider8.effect(ProxmoxCephPool, Effect24.s
2142
2118
  }
2143
2119
  return matches3(live, news) ? { action: "noop" } : { action: "update" };
2144
2120
  }),
2145
- reconcile: Effect24.fn(function* ({ news }) {
2121
+ reconcile: Effect23.fn(function* ({ news }) {
2146
2122
  const live = yield* readPoolStatus(news);
2147
2123
  let upid;
2148
2124
  if (live === undefined) {
@@ -2156,17 +2132,17 @@ var ProxmoxCephPoolProvider = () => Provider8.effect(ProxmoxCephPool, Effect24.s
2156
2132
  upid = yield* runPve(news.target, "provision", true, nodes7.putNodeCephPool(toDistilledUpdate(news)));
2157
2133
  }
2158
2134
  }
2159
- const after = yield* settle2(news, readPoolStatus, (row) => row !== undefined && matches3(row, news));
2135
+ const after = yield* settle(news, readPoolStatus, (row) => row !== undefined && matches3(row, news));
2160
2136
  if (after === undefined || !matches3(after, news)) {
2161
- return yield* Effect24.die(new Error(`${object(news)}: the write returned no error but the pool still does not match ` + `the declaration after 60s. PVE answered with task ${upid ?? "(none)"} -- read ` + "its log with `pvesh get /nodes/<node>/tasks/<upid>/log` to see what Ceph " + "refused."));
2137
+ return yield* Effect23.die(new Error(`${object(news)}: the write returned no error but the pool still does not match ` + `the declaration after 60s. PVE answered with task ${upid ?? "(none)"} -- read ` + "its log with `pvesh get /nodes/<node>/tasks/<upid>/log` to see what Ceph " + "refused."));
2162
2138
  }
2163
2139
  return after;
2164
2140
  }),
2165
- delete: Effect24.fn(function* ({ olds }) {
2141
+ delete: Effect23.fn(function* ({ olds }) {
2166
2142
  yield* runPve(olds.target, "provision", true, nodes7.deleteNodeCephPool({ name: olds.name, node: olds.node }));
2167
- const left = yield* settle2(olds, readPoolStatus, (row) => row === undefined);
2143
+ const left = yield* settle(olds, readPoolStatus, (row) => row === undefined);
2168
2144
  if (left !== undefined) {
2169
- return yield* Effect24.die(new Error(`${object(olds)}: the DELETE returned no error but the pool is still there after ` + "60s. Either a storage on it still holds RBD images, or the mons are running " + "with mon_allow_pool_delete false."));
2145
+ return yield* Effect23.die(new Error(`${object(olds)}: the DELETE returned no error but the pool is still there after ` + "60s. Either a storage on it still holds RBD images, or the mons are running " + "with mon_allow_pool_delete false."));
2170
2146
  }
2171
2147
  })
2172
2148
  })));
@@ -2174,7 +2150,7 @@ var ProxmoxCephPoolProvider = () => Provider8.effect(ProxmoxCephPool, Effect24.s
2174
2150
  import { Resource as Resource9 } from "alchemy";
2175
2151
  import { isResolved as isResolved8 } from "alchemy/Diff";
2176
2152
  import * as Provider9 from "alchemy/Provider";
2177
- import * as Effect25 from "effect/Effect";
2153
+ import * as Effect24 from "effect/Effect";
2178
2154
 
2179
2155
  // src/proxmox/firewall-alias-form.ts
2180
2156
  var fold = (name) => name.trim().toLowerCase();
@@ -2214,9 +2190,9 @@ var handlers4 = pveHandlers({
2214
2190
  path: (props) => `cluster/firewall/aliases/${props.name}`,
2215
2191
  updateForm: body
2216
2192
  });
2217
- var ProxmoxFirewallAliasProvider = () => Provider9.effect(ProxmoxFirewallAlias, Effect25.succeed(ProxmoxFirewallAlias.Provider.of({
2193
+ var ProxmoxFirewallAliasProvider = () => Provider9.effect(ProxmoxFirewallAlias, Effect24.succeed(ProxmoxFirewallAlias.Provider.of({
2218
2194
  ...handlers4,
2219
- diff: Effect25.fn(function* ({ news, output }) {
2195
+ diff: Effect24.fn(function* ({ news, output }) {
2220
2196
  if (output !== undefined && isResolved8(news) && fold(news.name) !== fold(output.name)) {
2221
2197
  return { action: "replace" };
2222
2198
  }
@@ -2228,11 +2204,11 @@ import { Resource as Resource10 } from "alchemy";
2228
2204
  import { isResolved as isResolved9 } from "alchemy/Diff";
2229
2205
  import * as Provider10 from "alchemy/Provider";
2230
2206
  import * as access4 from "@distilled.cloud/proxmox/access";
2231
- import * as Effect27 from "effect/Effect";
2207
+ import * as Effect26 from "effect/Effect";
2232
2208
 
2233
2209
  // src/proxmox/group-wire.ts
2234
2210
  import * as access3 from "@distilled.cloud/proxmox/access";
2235
- import * as Effect26 from "effect/Effect";
2211
+ import * as Effect25 from "effect/Effect";
2236
2212
  var GROUP_CREATE = "pve:POST /access/groups";
2237
2213
  var GROUP_UPDATE = "pve:PUT /access/groups/{groupid}";
2238
2214
  var storedComment = (comment2) => {
@@ -2257,22 +2233,20 @@ var attributesOf4 = (live, props) => ({
2257
2233
  members: memberList(live.members)
2258
2234
  });
2259
2235
  var matches4 = (attributes, props) => attributes.comment === storedComment(props.comment);
2260
- var readGroupOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, access3.getAccessGroup({ groupid: props.groupid }))).pipe(Effect26.map((live) => live === UNREADABLE ? UNREADABLE : live.members === undefined ? undefined : attributesOf4(live, props)));
2261
- var readGroup = (props) => readGroupOrFail(props).pipe(Effect26.orElseSucceed(() => {
2262
- return;
2263
- }));
2236
+ var readGroupOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, access3.getAccessGroup({ groupid: props.groupid }))).pipe(Effect25.map((live) => live === UNREADABLE ? UNREADABLE : live.members === undefined ? undefined : attributesOf4(live, props)));
2237
+ var readGroup = (props) => readGroupOrFail(props).pipe(Effect25.catchTag("GroupNotFound", () => Effect25.succeed(undefined)));
2264
2238
  var dropUnreadable3 = (live) => live === UNREADABLE ? undefined : live;
2265
2239
 
2266
2240
  // src/proxmox/group.ts
2267
2241
  var ProxmoxGroup = Resource10("Proxmox.Group", {
2268
2242
  defaultRemovalPolicy: "retain"
2269
2243
  });
2270
- var ProxmoxGroupProvider = () => Provider10.effect(ProxmoxGroup, Effect27.succeed(ProxmoxGroup.Provider.of({
2271
- list: () => Effect27.succeed([]),
2272
- read: Effect27.fn(function* ({ olds, output }) {
2244
+ var ProxmoxGroupProvider = () => Provider10.effect(ProxmoxGroup, Effect26.succeed(ProxmoxGroup.Provider.of({
2245
+ list: () => Effect26.succeed([]),
2246
+ read: Effect26.fn(function* ({ olds, output }) {
2273
2247
  return dropUnreadable3(yield* output === undefined ? readGroup(olds) : readGroupOrFail(olds));
2274
2248
  }),
2275
- diff: Effect27.fn(function* ({ news, output }) {
2249
+ diff: Effect26.fn(function* ({ news, output }) {
2276
2250
  if (!isResolved9(news))
2277
2251
  return;
2278
2252
  yield* guardWrite2(GROUP_CREATE, createForm3(news), output === undefined);
@@ -2290,7 +2264,7 @@ var ProxmoxGroupProvider = () => Provider10.effect(ProxmoxGroup, Effect27.succee
2290
2264
  }
2291
2265
  return matches4(live, news) ? { action: "noop" } : { action: "update" };
2292
2266
  }),
2293
- reconcile: Effect27.fn(function* ({ news }) {
2267
+ reconcile: Effect26.fn(function* ({ news }) {
2294
2268
  const before = dropUnreadable3(yield* readGroup(news));
2295
2269
  yield* guardWrite2(GROUP_CREATE, createForm3(news), before === undefined);
2296
2270
  yield* guardWrite2(GROUP_UPDATE, updateForm(news), false);
@@ -2301,18 +2275,18 @@ var ProxmoxGroupProvider = () => Provider10.effect(ProxmoxGroup, Effect27.succee
2301
2275
  }
2302
2276
  const after = dropUnreadable3(yield* readGroup(news));
2303
2277
  if (after === undefined) {
2304
- return yield* Effect27.die(new Error(`access/groups/${news.groupid}: the write returned no error but the group 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."));
2278
+ return yield* Effect26.die(new Error(`access/groups/${news.groupid}: the write returned no error but the group 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."));
2305
2279
  }
2306
2280
  return after;
2307
2281
  }),
2308
- delete: Effect27.fn(function* ({ olds }) {
2282
+ delete: Effect26.fn(function* ({ olds }) {
2309
2283
  yield* runPve(olds.target, "provision", true, access4.deleteAccessGroup({ groupid: olds.groupid }));
2310
2284
  })
2311
2285
  })));
2312
2286
  // src/proxmox/ha-resource.ts
2313
2287
  import { Resource as Resource11 } from "alchemy";
2314
2288
  import * as Provider11 from "alchemy/Provider";
2315
- import * as Effect28 from "effect/Effect";
2289
+ import * as Effect27 from "effect/Effect";
2316
2290
  var ProxmoxHaResource = Resource11("Proxmox.HaResource");
2317
2291
  var kind = (sid) => sid.split(":")[0] ?? "";
2318
2292
  var shape3 = (props) => ({
@@ -2340,11 +2314,11 @@ var handlers5 = pveHandlers({
2340
2314
  path: (props) => `cluster/ha/resources/${props.sid}`,
2341
2315
  updateForm: shape3
2342
2316
  });
2343
- var ProxmoxHaResourceProvider = () => Provider11.effect(ProxmoxHaResource, Effect28.succeed(ProxmoxHaResource.Provider.of(handlers5)));
2317
+ var ProxmoxHaResourceProvider = () => Provider11.effect(ProxmoxHaResource, Effect27.succeed(ProxmoxHaResource.Provider.of(handlers5)));
2344
2318
  // src/proxmox/ha-rule.ts
2345
2319
  import { Resource as Resource12 } from "alchemy";
2346
2320
  import * as Provider12 from "alchemy/Provider";
2347
- import * as Effect29 from "effect/Effect";
2321
+ import * as Effect28 from "effect/Effect";
2348
2322
 
2349
2323
  // src/proxmox/ha-rule-form.ts
2350
2324
  var nodeList = (value) => {
@@ -2421,43 +2395,43 @@ var handlers6 = pveHandlers({
2421
2395
  return withClears(fields, clear);
2422
2396
  }
2423
2397
  });
2424
- var ProxmoxHaRuleProvider = () => Provider12.effect(ProxmoxHaRule, Effect29.succeed(ProxmoxHaRule.Provider.of(handlers6)));
2398
+ var ProxmoxHaRuleProvider = () => Provider12.effect(ProxmoxHaRule, Effect28.succeed(ProxmoxHaRule.Provider.of(handlers6)));
2425
2399
  // src/proxmox/lxc.ts
2426
2400
  import { Resource as Resource13 } from "alchemy";
2427
2401
  import { isResolved as isResolved10 } from "alchemy/Diff";
2428
2402
  import * as Provider13 from "alchemy/Provider";
2429
- import * as Effect39 from "effect/Effect";
2403
+ import * as Effect38 from "effect/Effect";
2430
2404
 
2431
2405
  // src/ownership/adopt.ts
2432
2406
  import { AdoptPolicy } from "alchemy/AdoptPolicy";
2433
2407
  import { AlchemyContext } from "alchemy/AlchemyContext";
2434
2408
  import { Stack as Stack3 } from "alchemy/Stack";
2435
- import * as Effect33 from "effect/Effect";
2409
+ import * as Effect32 from "effect/Effect";
2436
2410
  import * as Option5 from "effect/Option";
2437
2411
 
2438
2412
  // src/ownership/resume.ts
2439
2413
  import { Unowned } from "alchemy/AdoptPolicy";
2440
2414
  import { Artifacts } from "alchemy/Artifacts";
2441
- import * as Effect30 from "effect/Effect";
2415
+ import * as Effect29 from "effect/Effect";
2442
2416
  import * as Option2 from "effect/Option";
2443
2417
  var PROVEN = "homeflare/ownership/resumes";
2444
2418
  var UNFINISHED = "homeflare/ownership/unfinished";
2445
- var note = (key, instanceId) => Effect30.gen(function* () {
2446
- const bag = yield* Effect30.serviceOption(Artifacts);
2419
+ var note = (key, instanceId) => Effect29.gen(function* () {
2420
+ const bag = yield* Effect29.serviceOption(Artifacts);
2447
2421
  if (Option2.isSome(bag))
2448
2422
  yield* bag.value.set(key, instanceId);
2449
2423
  });
2450
- var noted = (key, instanceId) => Effect30.gen(function* () {
2451
- const bag = yield* Effect30.serviceOption(Artifacts);
2424
+ var noted = (key, instanceId) => Effect29.gen(function* () {
2425
+ const bag = yield* Effect29.serviceOption(Artifacts);
2452
2426
  if (Option2.isNone(bag))
2453
2427
  return false;
2454
2428
  return (yield* bag.value.get(key)) === instanceId;
2455
2429
  });
2456
- var noteUnfinished = (instanceId) => Effect30.as(note(UNFINISHED, instanceId), undefined);
2457
- var noteResume = (instanceId, recovered) => Effect30.gen(function* () {
2430
+ var noteUnfinished = (instanceId) => Effect29.as(note(UNFINISHED, instanceId), undefined);
2431
+ var noteResume = (instanceId, recovered) => Effect29.gen(function* () {
2458
2432
  yield* noteUnfinished(instanceId);
2459
- const unproven = () => Effect30.succeed(undefined);
2460
- const found = yield* recovered.pipe(Effect30.catch(unproven), Effect30.catchDefect(unproven));
2433
+ const unproven = () => Effect29.succeed(undefined);
2434
+ const found = yield* recovered.pipe(Effect29.catch(unproven), Effect29.catchDefect(unproven));
2461
2435
  if (found === undefined || found === null || Unowned.is(found))
2462
2436
  return;
2463
2437
  yield* note(PROVEN, instanceId);
@@ -2468,7 +2442,7 @@ var provingResumes = (service) => {
2468
2442
  const { diff, read } = service;
2469
2443
  if (diff === undefined || read === undefined)
2470
2444
  return service;
2471
- const proving = (input) => Effect30.gen(function* () {
2445
+ const proving = (input) => Effect29.gen(function* () {
2472
2446
  if (input.output === undefined) {
2473
2447
  yield* noteResume(input.instanceId, read({ ...input, output: undefined }));
2474
2448
  }
@@ -2480,12 +2454,12 @@ var provingResumes = (service) => {
2480
2454
  // src/ownership/rows.ts
2481
2455
  import { Stack as Stack2 } from "alchemy/Stack";
2482
2456
  import { State, isActionState } from "alchemy/State/State";
2483
- import * as Effect32 from "effect/Effect";
2457
+ import * as Effect31 from "effect/Effect";
2484
2458
  import * as Option4 from "effect/Option";
2485
2459
 
2486
2460
  // src/ownership/whole.ts
2487
2461
  import { Stack } from "alchemy/Stack";
2488
- import * as Effect31 from "effect/Effect";
2462
+ import * as Effect30 from "effect/Effect";
2489
2463
  import * as Option3 from "effect/Option";
2490
2464
  var absent = (value) => value === undefined || value === null;
2491
2465
  var isPlainObject = (value) => {
@@ -2511,22 +2485,22 @@ var carries = (declared, recorded) => {
2511
2485
  }
2512
2486
  return true;
2513
2487
  };
2514
- var wholeDeclaration = (fqn, props) => Effect31.map(Effect31.serviceOption(Stack), (stack) => {
2488
+ var wholeDeclaration = (fqn, props) => Effect30.map(Effect30.serviceOption(Stack), (stack) => {
2515
2489
  const declared = Option3.isSome(stack) ? stack.value.resources[fqn] : undefined;
2516
2490
  return declared !== undefined && carries(declared.Props, props);
2517
2491
  });
2518
2492
 
2519
2493
  // src/ownership/rows.ts
2520
- var storeOf = Effect32.gen(function* () {
2521
- const stack = yield* Effect32.serviceOption(Stack2);
2522
- const state = yield* Effect32.serviceOption(State);
2494
+ var storeOf = Effect31.gen(function* () {
2495
+ const stack = yield* Effect31.serviceOption(Stack2);
2496
+ const state = yield* Effect31.serviceOption(State);
2523
2497
  if (Option4.isNone(stack) || Option4.isNone(state))
2524
2498
  return;
2525
2499
  const store = yield* state.value;
2526
2500
  const where = { stack: stack.value.name, stage: stack.value.stage };
2527
2501
  return { resources: stack.value.resources, store, where };
2528
2502
  });
2529
- var rowAt = (store, where, fqn) => store.get({ ...where, fqn }).pipe(Effect32.orElseSucceed(() => {
2503
+ var rowAt = (store, where, fqn) => store.get({ ...where, fqn }).pipe(Effect31.orElseSucceed(() => {
2530
2504
  return;
2531
2505
  }));
2532
2506
  var generationOf = (row, instanceId) => {
@@ -2539,7 +2513,7 @@ var generationOf = (row, instanceId) => {
2539
2513
  }
2540
2514
  return;
2541
2515
  };
2542
- var recordedGeneration = (fqn, instanceId) => Effect32.gen(function* () {
2516
+ var recordedGeneration = (fqn, instanceId) => Effect31.gen(function* () {
2543
2517
  const found = yield* storeOf;
2544
2518
  if (found === undefined)
2545
2519
  return;
@@ -2550,14 +2524,14 @@ var recordedGeneration = (fqn, instanceId) => Effect32.gen(function* () {
2550
2524
  }
2551
2525
  return;
2552
2526
  });
2553
- var recordedInstance = (fqn, instanceId) => Effect32.gen(function* () {
2527
+ var recordedInstance = (fqn, instanceId) => Effect31.gen(function* () {
2554
2528
  const generation = yield* recordedGeneration(fqn, instanceId);
2555
2529
  if (generation === undefined)
2556
2530
  return "absent";
2557
2531
  return (yield* wholeDeclaration(fqn, generation.props)) ? "whole" : "partial";
2558
2532
  });
2559
- var isCreate = (fqn, instanceId) => Effect32.map(recordedGeneration(fqn, instanceId), (generation) => generation?.status === "creating");
2560
- var forgetRefusedCreate = (fqn, instanceId) => Effect32.gen(function* () {
2533
+ var isCreate = (fqn, instanceId) => Effect31.map(recordedGeneration(fqn, instanceId), (generation) => generation?.status === "creating");
2534
+ var forgetRefusedCreate = (fqn, instanceId) => Effect31.gen(function* () {
2561
2535
  const found = yield* storeOf;
2562
2536
  if (found === undefined)
2563
2537
  return;
@@ -2566,32 +2540,32 @@ var forgetRefusedCreate = (fqn, instanceId) => Effect32.gen(function* () {
2566
2540
  if (mine?.status !== "creating" || mine.instanceId !== instanceId || mine.attr !== undefined) {
2567
2541
  return;
2568
2542
  }
2569
- yield* found.store.delete({ ...found.where, fqn }).pipe(Effect32.ignore);
2543
+ yield* found.store.delete({ ...found.where, fqn }).pipe(Effect31.ignore);
2570
2544
  });
2571
2545
 
2572
2546
  // src/ownership/adopt.ts
2573
- var adoptEnabled = (fqn) => Effect33.gen(function* () {
2574
- const stack = yield* Effect33.serviceOption(Stack3);
2547
+ var adoptEnabled = (fqn) => Effect32.gen(function* () {
2548
+ const stack = yield* Effect32.serviceOption(Stack3);
2575
2549
  const scoped = Option5.isSome(stack) ? stack.value.resources[fqn]?.Adopt : undefined;
2576
2550
  if (scoped !== undefined)
2577
2551
  return scoped;
2578
- const policy = yield* Effect33.serviceOption(AdoptPolicy);
2552
+ const policy = yield* Effect32.serviceOption(AdoptPolicy);
2579
2553
  if (Option5.isSome(policy))
2580
2554
  return policy.value;
2581
- const context = yield* Effect33.serviceOption(AlchemyContext);
2555
+ const context = yield* Effect32.serviceOption(AlchemyContext);
2582
2556
  return Option5.isSome(context) ? context.value.adopt : false;
2583
2557
  });
2584
- var adoptable = (owner) => Effect33.gen(function* () {
2558
+ var adoptable = (owner) => Effect32.gen(function* () {
2585
2559
  if (yield* isCreate(owner.fqn, owner.instanceId))
2586
2560
  return true;
2587
2561
  return yield* unfinished(owner.instanceId);
2588
2562
  });
2589
- var adoptsAtApply = (owner) => Effect33.gen(function* () {
2563
+ var adoptsAtApply = (owner) => Effect32.gen(function* () {
2590
2564
  if (!(yield* adoptEnabled(owner.fqn)))
2591
2565
  return false;
2592
2566
  return yield* adoptable(owner);
2593
2567
  });
2594
- var refuseTakeover = (owner, what) => Effect33.gen(function* () {
2568
+ var refuseTakeover = (owner, what) => Effect32.gen(function* () {
2595
2569
  if (owner.output !== undefined)
2596
2570
  return;
2597
2571
  if (yield* resumes(owner.instanceId))
@@ -2601,25 +2575,25 @@ var refuseTakeover = (owner, what) => Effect33.gen(function* () {
2601
2575
  return;
2602
2576
  yield* forgetRefusedCreate(owner.fqn, owner.instanceId);
2603
2577
  const remedy = may ? "Deploy with --adopt (or wrap the resource in adopt(true)) to take it over, or remove it first." : "It is the new identity of a replace, which --adopt does not cover: remove it first.";
2604
- return yield* Effect33.die(new Error(`${what}: already exists, and this stack holds no state for it — the plan could not ask ` + "first (a prop was still an Output, a replace moved onto it, or it appeared after the " + `plan). Nothing was written. ${remedy}`));
2578
+ return yield* Effect32.die(new Error(`${what}: already exists, and this stack holds no state for it — the plan could not ask ` + "first (a prop was still an Output, a replace moved onto it, or it appeared after the " + `plan). Nothing was written. ${remedy}`));
2605
2579
  });
2606
2580
  var claimFor = (owner) => (what) => refuseTakeover(owner, what);
2607
2581
 
2608
2582
  // src/ownership/probe.ts
2609
2583
  import { Unowned as Unowned2 } from "alchemy/AdoptPolicy";
2610
- import * as Effect34 from "effect/Effect";
2611
- var provenOurs = (ask, settled2) => Effect34.gen(function* () {
2584
+ import * as Effect33 from "effect/Effect";
2585
+ var provenOurs = (ask, settled2) => Effect33.gen(function* () {
2612
2586
  const recorded = yield* recordedInstance(ask.fqn, ask.instanceId);
2613
2587
  if (recorded === "absent")
2614
2588
  return false;
2615
2589
  if (recorded === "partial") {
2616
- yield* Effect34.logWarning(`${ask.fqn}: the interrupted create's state row lacks part of the declaration (a prop ` + "was still an Output when it was written), so the live object is not proven ours");
2590
+ yield* Effect33.logWarning(`${ask.fqn}: the interrupted create's state row lacks part of the declaration (a prop ` + "was still an Output when it was written), so the live object is not proven ours");
2617
2591
  return false;
2618
2592
  }
2619
- const unproven = (reason) => Effect34.as(Effect34.logWarning(`${ask.fqn}: the interrupted create's object could not be compared with its props ` + `(${reason instanceof Error ? reason.message : String(reason)}), so it is not treated as ours`), false);
2620
- return yield* settled2.pipe(Effect34.catch(unproven), Effect34.catchDefect(unproven));
2593
+ const unproven = (reason) => Effect33.as(Effect33.logWarning(`${ask.fqn}: the interrupted create's object could not be compared with its props ` + `(${reason instanceof Error ? reason.message : String(reason)}), so it is not treated as ours`), false);
2594
+ return yield* settled2.pipe(Effect33.catch(unproven), Effect33.catchDefect(unproven));
2621
2595
  });
2622
- var ownedRead = (ask, found, settled2) => Effect34.gen(function* () {
2596
+ var ownedRead = (ask, found, settled2) => Effect33.gen(function* () {
2623
2597
  if (found === undefined || ask.output !== undefined)
2624
2598
  return found;
2625
2599
  return (yield* provenOurs(ask, settled2)) ? found : Unowned2(found);
@@ -3074,11 +3048,11 @@ var identityRefusals = (news, olds, output) => {
3074
3048
  };
3075
3049
 
3076
3050
  // src/proxmox/lxc-adoption.ts
3077
- import * as Effect38 from "effect/Effect";
3051
+ import * as Effect37 from "effect/Effect";
3078
3052
 
3079
3053
  // src/ownership/adopting.ts
3080
- import * as Effect35 from "effect/Effect";
3081
- var adopting = (owner, settled2) => Effect35.gen(function* () {
3054
+ import * as Effect34 from "effect/Effect";
3055
+ var adopting = (owner, settled2) => Effect34.gen(function* () {
3082
3056
  if (owner.output === undefined)
3083
3057
  return false;
3084
3058
  const generation = yield* recordedGeneration(owner.fqn, owner.instanceId);
@@ -3090,11 +3064,11 @@ var adopting = (owner, settled2) => Effect35.gen(function* () {
3090
3064
  });
3091
3065
 
3092
3066
  // src/proxmox/lxc-lifecycle.ts
3093
- import * as Effect37 from "effect/Effect";
3067
+ import * as Effect36 from "effect/Effect";
3094
3068
 
3095
3069
  // src/proxmox/network-apply-read.ts
3096
- import * as Effect36 from "effect/Effect";
3097
- var stagedDiff = (target, node) => Effect36.gen(function* () {
3070
+ import * as Effect35 from "effect/Effect";
3071
+ var stagedDiff = (target, node) => Effect35.gen(function* () {
3098
3072
  const path = `nodes/${node}/network`;
3099
3073
  const credential = yield* leased(target, "read");
3100
3074
  const envelope = yield* pveEnvelopeWith(target, credential, "GET", path);
@@ -3107,8 +3081,8 @@ var pendingLines = (diff) => {
3107
3081
  `).filter((line) => (line.startsWith("+") || line.startsWith("-")) && !line.startsWith("+++") && !line.startsWith("---")).length;
3108
3082
  return Math.max(changed, 1);
3109
3083
  };
3110
- var pendingCount = (target, node) => stagedDiff(target, node).pipe(Effect36.map(pendingLines));
3111
- var clusterHealth = (target) => pve(target, "read", "GET", "cluster/status").pipe(Effect36.map((rows) => {
3084
+ var pendingCount = (target, node) => stagedDiff(target, node).pipe(Effect35.map(pendingLines));
3085
+ var clusterHealth = (target) => pve(target, "read", "GET", "cluster/status").pipe(Effect35.map((rows) => {
3112
3086
  const all = rows ?? [];
3113
3087
  const cluster = all.find((row) => row.type === "cluster");
3114
3088
  return {
@@ -3116,21 +3090,21 @@ var clusterHealth = (target) => pve(target, "read", "GET", "cluster/status").pip
3116
3090
  quorate: cluster === undefined ? true : bool(cluster.quorate)
3117
3091
  };
3118
3092
  }));
3119
- var degradedReason = (target) => clusterHealth(target).pipe(Effect36.map((health) => health.quorate && health.offline.length === 0 ? undefined : `quorate=${String(health.quorate)} offline=[${health.offline.join(", ")}]`));
3093
+ var degradedReason = (target) => clusterHealth(target).pipe(Effect35.map((health) => health.quorate && health.offline.length === 0 ? undefined : `quorate=${String(health.quorate)} offline=[${health.offline.join(", ")}]`));
3120
3094
  var UNREACHABLE = "the task could not be read -- the node stopped answering, or this lease cannot see it";
3121
3095
  var STILL_RUNNING = "still running when this provider stopped waiting";
3122
3096
  var ATTEMPTS = 30;
3123
- var awaitTask = (target, credential, node, upid, attempts = ATTEMPTS) => Effect36.gen(function* () {
3097
+ var awaitTask = (target, credential, node, upid, attempts = ATTEMPTS) => Effect35.gen(function* () {
3124
3098
  const path = `nodes/${node}/tasks/${upid}/status`;
3125
3099
  for (let attempt = 0;attempt < attempts; attempt += 1) {
3126
- const status = yield* pveWith(target, credential, "GET", path).pipe(Effect36.orElseSucceed(() => {
3100
+ const status = yield* pveWith(target, credential, "GET", path).pipe(Effect35.orElseSucceed(() => {
3127
3101
  return;
3128
3102
  }));
3129
3103
  if (status === undefined)
3130
3104
  return UNREACHABLE;
3131
3105
  if (status.status === "stopped")
3132
3106
  return text(status.exitstatus, "stopped with no exitstatus");
3133
- yield* Effect36.sleep("1 second");
3107
+ yield* Effect35.sleep("1 second");
3134
3108
  }
3135
3109
  return STILL_RUNNING;
3136
3110
  });
@@ -3148,17 +3122,17 @@ var LXC_ENDPOINTS = {
3148
3122
  var CREATE_POLLS = 180;
3149
3123
  var TASK_POLLS = 60;
3150
3124
  var isServerError = (error) => error instanceof PveError && error.status === 500;
3151
- var readLive = (where) => Effect37.gen(function* () {
3152
- const answer = yield* pve(where.target, "read", "GET", `${guestPath(where)}/config`).pipe(Effect37.map((data) => ({ data, error: undefined })), Effect37.catchIf(isServerError, (error) => Effect37.succeed({ data: undefined, error })));
3125
+ var readLive = (where) => Effect36.gen(function* () {
3126
+ const answer = yield* pve(where.target, "read", "GET", `${guestPath(where)}/config`).pipe(Effect36.map((data) => ({ data, error: undefined })), Effect36.catchIf(isServerError, (error) => Effect36.succeed({ data: undefined, error })));
3153
3127
  if (answer.data !== undefined && answer.data !== null)
3154
3128
  return answer.data;
3155
3129
  const rows = yield* pve(where.target, "read", "GET", "cluster/resources?type=vm");
3156
3130
  const found = (rows ?? []).find((row) => Number(row.vmid) === where.vmid);
3157
3131
  if (found !== undefined && found.node === where.node && found.type === "lxc") {
3158
- return yield* Effect37.fail(answer.error ?? new LxcRefusedError(`CT ${String(where.vmid)} is listed but its config read empty.`));
3132
+ return yield* Effect36.fail(answer.error ?? new LxcRefusedError(`CT ${String(where.vmid)} is listed but its config read empty.`));
3159
3133
  }
3160
3134
  if (found !== undefined) {
3161
- return yield* Effect37.fail(new LxcRefusedError(`vmid ${String(where.vmid)} is a ${text(found.type, "guest")} on ` + `${text(found.node, "?")}, not a container on ${where.node}. A migration is not an ` + "update and vmids are cluster-wide: declare the node it is on, or pick a free vmid."));
3135
+ return yield* Effect36.fail(new LxcRefusedError(`vmid ${String(where.vmid)} is a ${text(found.type, "guest")} on ` + `${text(found.node, "?")}, not a container on ${where.node}. A migration is not an ` + "update and vmids are cluster-wide: declare the node it is on, or pick a free vmid."));
3162
3136
  }
3163
3137
  return;
3164
3138
  });
@@ -3168,23 +3142,23 @@ var attributesOf5 = (where, live) => ({
3168
3142
  rawKeys: rawKeysOf(live),
3169
3143
  vmid: where.vmid
3170
3144
  });
3171
- var task = (where, method, path, what, polls, form) => Effect37.gen(function* () {
3145
+ var task = (where, method, path, what, polls, form) => Effect36.gen(function* () {
3172
3146
  const credential = yield* mint(where.target, "provision");
3173
3147
  const upid = text(yield* pveWith(where.target, credential, method, path, form));
3174
3148
  if (upid === "") {
3175
- return yield* Effect37.fail(new LxcRefusedError(`${what}: PVE returned no task id, so the write cannot be confirmed and is not claimed.`));
3149
+ return yield* Effect36.fail(new LxcRefusedError(`${what}: PVE returned no task id, so the write cannot be confirmed and is not claimed.`));
3176
3150
  }
3177
3151
  const exit = yield* awaitTask(where.target, credential, where.node, upid, polls);
3178
3152
  if (exit !== "OK") {
3179
- return yield* Effect37.fail(new LxcRefusedError(`${what}: task ${upid} ended "${exit}". Read \`pvesh get /nodes/${where.node}/tasks/` + `${upid}/log\` before running the deploy again.`));
3153
+ return yield* Effect36.fail(new LxcRefusedError(`${what}: task ${upid} ended "${exit}". Read \`pvesh get /nodes/${where.node}/tasks/` + `${upid}/log\` before running the deploy again.`));
3180
3154
  }
3181
3155
  });
3182
- var createGuest = (props) => Effect37.gen(function* () {
3156
+ var createGuest = (props) => Effect36.gen(function* () {
3183
3157
  const form = createForm4(props);
3184
3158
  yield* guardForm(LXC_ENDPOINTS.create, form, true);
3185
3159
  return yield* task(props, "POST", `nodes/${props.node}/lxc`, `create CT ${String(props.vmid)}`, CREATE_POLLS, form);
3186
3160
  });
3187
- var updateGuest = (props, change, digest) => Effect37.gen(function* () {
3161
+ var updateGuest = (props, change, digest) => Effect36.gen(function* () {
3188
3162
  if (Object.keys(change.put).length > 0 || change.clear.length > 0) {
3189
3163
  const form = withClears({ ...change.put, ...digest === "" ? {} : { digest } }, change.clear);
3190
3164
  yield* guardForm(LXC_ENDPOINTS.update, form, false);
@@ -3196,33 +3170,33 @@ var updateGuest = (props, change, digest) => Effect37.gen(function* () {
3196
3170
  yield* task(props, "PUT", `${guestPath(props)}/resize`, `grow ${grow.disk} of CT ${String(props.vmid)} to ${grow.size}`, TASK_POLLS, grown);
3197
3171
  }
3198
3172
  });
3199
- var destroyGuest = (where, declared) => Effect37.gen(function* () {
3173
+ var destroyGuest = (where, declared) => Effect36.gen(function* () {
3200
3174
  const live = yield* readLive(where);
3201
3175
  if (live === undefined)
3202
3176
  return;
3203
3177
  const drift = judge(declared, live).drift;
3204
3178
  if (drift.length > 0) {
3205
- return yield* Effect37.fail(new LxcRefusedError(`destroy CT ${String(where.vmid)}: the guest on ${where.node} no longer matches its last ` + `declaration (${drift.join(", ")}), so it may not be the guest this stack made. ` + "Nothing was deleted. Delete it by hand if it should go, or declare it again."));
3179
+ return yield* Effect36.fail(new LxcRefusedError(`destroy CT ${String(where.vmid)}: the guest on ${where.node} no longer matches its last ` + `declaration (${drift.join(", ")}), so it may not be the guest this stack made. ` + "Nothing was deleted. Delete it by hand if it should go, or declare it again."));
3206
3180
  }
3207
3181
  yield* task(where, "DELETE", guestPath(where), `destroy CT ${String(where.vmid)}`, TASK_POLLS);
3208
3182
  });
3209
3183
 
3210
3184
  // src/proxmox/lxc-adoption.ts
3211
3185
  var adoptionRefusal = (props, drift) => `CT ${String(props.vmid)} on ${props.node}: adopting it would change ${drift.join(", ")}. An ` + "adoption never changes a guest, so nothing is written. Declare what is live for these keys " + "(the plan names keys, never values) and plan again; change them after the adoption, as an " + "update.";
3212
- var refuseAdoptedDrift = (owner, props, live, change) => Effect38.gen(function* () {
3186
+ var refuseAdoptedDrift = (owner, props, live, change) => Effect37.gen(function* () {
3213
3187
  if (change.drift.length === 0)
3214
3188
  return;
3215
- const settled2 = (recorded) => Effect38.sync(() => judge(recorded, live).drift.length === 0);
3189
+ const settled2 = (recorded) => Effect37.sync(() => judge(recorded, live).drift.length === 0);
3216
3190
  if (!(yield* adopting(owner, settled2)))
3217
3191
  return;
3218
- return yield* Effect38.fail(new LxcRefusedError(adoptionRefusal(props, change.drift)));
3192
+ return yield* Effect37.fail(new LxcRefusedError(adoptionRefusal(props, change.drift)));
3219
3193
  });
3220
3194
 
3221
3195
  // src/proxmox/lxc.ts
3222
3196
  var ProxmoxLxc = Resource13("Proxmox.Lxc", { defaultRemovalPolicy: "retain" });
3223
- var refused = (reasons) => Effect39.fail(new LxcRefusedError(reasons.join(`
3197
+ var refused = (reasons) => Effect38.fail(new LxcRefusedError(reasons.join(`
3224
3198
  `)));
3225
- var diff = (owner, news, olds) => Effect39.gen(function* () {
3199
+ var diff = (owner, news, olds) => Effect38.gen(function* () {
3226
3200
  const { output } = owner;
3227
3201
  const identity2 = identityRefusals(news, olds, output);
3228
3202
  if (identity2.length > 0)
@@ -3236,7 +3210,7 @@ var diff = (owner, news, olds) => Effect39.gen(function* () {
3236
3210
  const refusals = createRefusals(news);
3237
3211
  if (refusals.length > 0)
3238
3212
  return yield* refused(refusals);
3239
- yield* Effect39.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: the cluster lists no guest with this ` + "vmid -- a deploy CREATES it again from ostemplate, with new, empty volumes.");
3213
+ yield* Effect38.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: the cluster lists no guest with this ` + "vmid -- a deploy CREATES it again from ostemplate, with new, empty volumes.");
3240
3214
  return { action: "update" };
3241
3215
  }
3242
3216
  const change = judge(news, live);
@@ -3247,10 +3221,10 @@ var diff = (owner, news, olds) => Effect39.gen(function* () {
3247
3221
  if (change.drift.length === 0 && !moved)
3248
3222
  return { action: "noop" };
3249
3223
  const what = change.drift.length === 0 ? `the guest is on ${news.node} now, not ${output.node} -- a deploy re-records it, ` + "writing nothing." : `live config differs from the declaration in ${change.drift.join(", ")} -- a ` + "deploy writes these.";
3250
- yield* Effect39.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: ${what}`);
3224
+ yield* Effect38.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: ${what}`);
3251
3225
  return { action: "update" };
3252
3226
  });
3253
- var reconcile = (owner, news) => Effect39.gen(function* () {
3227
+ var reconcile = (owner, news) => Effect38.gen(function* () {
3254
3228
  const { output } = owner;
3255
3229
  const identity2 = identityRefusals(news, news, output);
3256
3230
  if (identity2.length > 0)
@@ -3296,12 +3270,12 @@ var whereOf = (olds, output) => ({
3296
3270
  target: olds.target,
3297
3271
  vmid: output?.vmid ?? olds.vmid
3298
3272
  });
3299
- var read = (owner, olds) => Effect39.gen(function* () {
3273
+ var read = (owner, olds) => Effect38.gen(function* () {
3300
3274
  const where = whereOf(olds, owner.output);
3301
3275
  const live = yield* readLive(where);
3302
3276
  if (live === undefined)
3303
3277
  return;
3304
- const settled2 = Effect39.sync(() => judge(olds, live).drift.length === 0);
3278
+ const settled2 = Effect38.sync(() => judge(olds, live).drift.length === 0);
3305
3279
  return yield* ownedRead(owner, attributesOf5(where, live), settled2);
3306
3280
  });
3307
3281
  var handlers7 = {
@@ -3313,7 +3287,7 @@ var handlers7 = {
3313
3287
  olds,
3314
3288
  output
3315
3289
  }) => diff({ fqn, instanceId, output }, news, olds),
3316
- list: () => Effect39.succeed([]),
3290
+ list: () => Effect38.succeed([]),
3317
3291
  read: ({
3318
3292
  fqn,
3319
3293
  instanceId,
@@ -3327,11 +3301,11 @@ var handlers7 = {
3327
3301
  output
3328
3302
  }) => reconcile({ fqn, instanceId, output }, news)
3329
3303
  };
3330
- var ProxmoxLxcProvider = () => Provider13.effect(ProxmoxLxc, Effect39.succeed(ProxmoxLxc.Provider.of(handlers7)).pipe(Effect39.map(provingResumes)));
3304
+ var ProxmoxLxcProvider = () => Provider13.effect(ProxmoxLxc, Effect38.succeed(ProxmoxLxc.Provider.of(handlers7)).pipe(Effect38.map(provingResumes)));
3331
3305
  // src/proxmox/metric-server.ts
3332
3306
  import { Resource as Resource14 } from "alchemy";
3333
3307
  import * as Provider14 from "alchemy/Provider";
3334
- import * as Effect40 from "effect/Effect";
3308
+ import * as Effect39 from "effect/Effect";
3335
3309
 
3336
3310
  // src/proxmox/metric-server-form.ts
3337
3311
  var UNSET2 = -1;
@@ -3444,12 +3418,12 @@ var handlers8 = pveHandlers({
3444
3418
  path: (props) => `cluster/metrics/server/${props.id}`,
3445
3419
  updateForm: update
3446
3420
  });
3447
- var ProxmoxMetricServerProvider = () => Provider14.effect(ProxmoxMetricServer, Effect40.succeed(ProxmoxMetricServer.Provider.of(handlers8)));
3421
+ var ProxmoxMetricServerProvider = () => Provider14.effect(ProxmoxMetricServer, Effect39.succeed(ProxmoxMetricServer.Provider.of(handlers8)));
3448
3422
  // src/proxmox/network-apply.ts
3449
3423
  import { Resource as Resource15 } from "alchemy";
3450
3424
  import { isResolved as isResolved11 } from "alchemy/Diff";
3451
3425
  import * as Provider15 from "alchemy/Provider";
3452
- import * as Effect41 from "effect/Effect";
3426
+ import * as Effect40 from "effect/Effect";
3453
3427
 
3454
3428
  // src/proxmox/apply-endpoints.ts
3455
3429
  var NETWORK_APPLY_ENDPOINT = "pve:PUT /nodes/{node}/network";
@@ -3459,15 +3433,15 @@ var guardSdnApply = guardForm(SDN_APPLY_ENDPOINT, {}, true);
3459
3433
 
3460
3434
  // src/proxmox/network-apply.ts
3461
3435
  var ProxmoxNetworkApply = Resource15("Proxmox.NetworkApply");
3462
- var read2 = (props) => pendingCount(props.target, props.node).pipe(Effect41.map((pending) => ({ node: props.node, pending })));
3463
- var diff2 = (news) => Effect41.gen(function* () {
3436
+ var read2 = (props) => pendingCount(props.target, props.node).pipe(Effect40.map((pending) => ({ node: props.node, pending })));
3437
+ var diff2 = (news) => Effect40.gen(function* () {
3464
3438
  if (!isResolved11(news))
3465
3439
  return;
3466
3440
  const { pending } = yield* read2(news);
3467
3441
  return pending === 0 ? { action: "noop" } : { action: "update" };
3468
3442
  });
3469
- var refuse = (node, why) => Effect41.die(new Error(`Proxmox.NetworkApply ${node}: ${why}`));
3470
- var apply = (props) => Effect41.gen(function* () {
3443
+ var refuse = (node, why) => Effect40.die(new Error(`Proxmox.NetworkApply ${node}: ${why}`));
3444
+ var apply = (props) => Effect40.gen(function* () {
3471
3445
  const node = props.node;
3472
3446
  const staged = yield* pendingCount(props.target, node);
3473
3447
  if (staged === 0)
@@ -3497,19 +3471,19 @@ var apply = (props) => Effect41.gen(function* () {
3497
3471
  return { node, pending: left };
3498
3472
  });
3499
3473
  var handlers9 = {
3500
- delete: () => Effect41.void,
3474
+ delete: () => Effect40.void,
3501
3475
  diff: ({ news }) => diff2(news),
3502
- list: () => Effect41.succeed([]),
3476
+ list: () => Effect40.succeed([]),
3503
3477
  read: ({ olds }) => read2(olds),
3504
3478
  reconcile: ({ news }) => apply(news)
3505
3479
  };
3506
- var ProxmoxNetworkApplyProvider = () => Provider15.effect(ProxmoxNetworkApply, Effect41.succeed(ProxmoxNetworkApply.Provider.of(handlers9)));
3480
+ var ProxmoxNetworkApplyProvider = () => Provider15.effect(ProxmoxNetworkApply, Effect40.succeed(ProxmoxNetworkApply.Provider.of(handlers9)));
3507
3481
  // src/proxmox/node-network.ts
3508
3482
  import { Resource as Resource16 } from "alchemy";
3509
3483
  import { isResolved as isResolved12 } from "alchemy/Diff";
3510
3484
  import * as Provider16 from "alchemy/Provider";
3511
3485
  import * as nodes9 from "@distilled.cloud/proxmox/nodes";
3512
- import * as Effect43 from "effect/Effect";
3486
+ import * as Effect42 from "effect/Effect";
3513
3487
 
3514
3488
  // src/proxmox/node-network-form.ts
3515
3489
  var NODE_NETWORK_CREATE = "pve:POST /nodes/{node}/network";
@@ -3552,7 +3526,7 @@ var updateForm2 = (props) => {
3552
3526
 
3553
3527
  // src/proxmox/node-network-wire.ts
3554
3528
  import * as nodes8 from "@distilled.cloud/proxmox/nodes";
3555
- import * as Effect42 from "effect/Effect";
3529
+ import * as Effect41 from "effect/Effect";
3556
3530
  var attributesOf6 = (live, props) => {
3557
3531
  const data = live;
3558
3532
  const liveType = text(data["type"]);
@@ -3586,12 +3560,12 @@ var attributesOf6 = (live, props) => {
3586
3560
  "vlan-raw-device": text(data["vlan-raw-device"])
3587
3561
  };
3588
3562
  };
3589
- var readInterfaceOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, nodes8.getNodeNetwork({ iface: props.iface, node: props.node })).pipe(Effect42.catchTag("ParameterVerificationFailed", (error) => error.errors["iface"] === "interface does not exist" ? Effect42.succeed(undefined) : Effect42.fail(error)))).pipe(Effect42.map((live) => {
3563
+ var readInterfaceOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, nodes8.getNodeNetwork({ iface: props.iface, node: props.node })).pipe(Effect41.catchTag("ParameterVerificationFailed", (error) => error.errors["iface"] === "interface does not exist" ? Effect41.succeed(undefined) : Effect41.fail(error)))).pipe(Effect41.map((live) => {
3590
3564
  if (live === UNREADABLE)
3591
3565
  return UNREADABLE;
3592
3566
  return live === undefined ? undefined : attributesOf6(live, props);
3593
3567
  }));
3594
- var readInterface = (props) => readInterfaceOrFail(props).pipe(Effect42.orElseSucceed(() => {
3568
+ var readInterface = (props) => readInterfaceOrFail(props).pipe(Effect41.orElseSucceed(() => {
3595
3569
  return;
3596
3570
  }));
3597
3571
  var dropUnreadable4 = (live) => live === UNREADABLE ? undefined : live;
@@ -3616,12 +3590,12 @@ var toDistilledUpdate2 = (props) => ({
3616
3590
  iface: props.iface,
3617
3591
  node: props.node
3618
3592
  });
3619
- var ProxmoxNodeNetworkProvider = () => Provider16.effect(ProxmoxNodeNetwork, Effect43.succeed(ProxmoxNodeNetwork.Provider.of({
3620
- list: () => Effect43.succeed([]),
3621
- read: Effect43.fn(function* ({ olds, output }) {
3593
+ var ProxmoxNodeNetworkProvider = () => Provider16.effect(ProxmoxNodeNetwork, Effect42.succeed(ProxmoxNodeNetwork.Provider.of({
3594
+ list: () => Effect42.succeed([]),
3595
+ read: Effect42.fn(function* ({ olds, output }) {
3622
3596
  return dropUnreadable4(yield* output === undefined ? readInterface(olds) : readInterfaceOrFail(olds));
3623
3597
  }),
3624
- diff: Effect43.fn(function* ({ news, output }) {
3598
+ diff: Effect42.fn(function* ({ news, output }) {
3625
3599
  if (!isResolved12(news))
3626
3600
  return;
3627
3601
  yield* guardWrite2(NODE_NETWORK_CREATE, createForm5(news), output === undefined);
@@ -3639,7 +3613,7 @@ var ProxmoxNodeNetworkProvider = () => Provider16.effect(ProxmoxNodeNetwork, Eff
3639
3613
  }
3640
3614
  return matches5(live, news) ? { action: "noop" } : { action: "update" };
3641
3615
  }),
3642
- reconcile: Effect43.fn(function* ({ news }) {
3616
+ reconcile: Effect42.fn(function* ({ news }) {
3643
3617
  const before = dropUnreadable4(yield* readInterface(news));
3644
3618
  yield* guardWrite2(NODE_NETWORK_CREATE, createForm5(news), before === undefined);
3645
3619
  yield* guardWrite2(NODE_NETWORK_UPDATE, updateForm2(news), false);
@@ -3650,18 +3624,18 @@ var ProxmoxNodeNetworkProvider = () => Provider16.effect(ProxmoxNodeNetwork, Eff
3650
3624
  }
3651
3625
  const after = dropUnreadable4(yield* readInterface(news));
3652
3626
  if (after === undefined) {
3653
- return yield* Effect43.die(new Error(`nodes/${news.node}/network/${news.iface}: wrote with no error, but the ` + 'interface is still absent -- PVE wraps every answer in {"data":...} and can ' + "report success on a call that did nothing, so read back rather than trust it."));
3627
+ return yield* Effect42.die(new Error(`nodes/${news.node}/network/${news.iface}: wrote with no error, but the ` + 'interface is still absent -- PVE wraps every answer in {"data":...} and can ' + "report success on a call that did nothing, so read back rather than trust it."));
3654
3628
  }
3655
3629
  return after;
3656
3630
  }),
3657
- delete: Effect43.fn(function* ({ olds }) {
3631
+ delete: Effect42.fn(function* ({ olds }) {
3658
3632
  yield* runPve(olds.target, "provision", true, nodes9.deleteNodeNetwork2({ iface: olds.iface, node: olds.node }));
3659
3633
  })
3660
3634
  })));
3661
3635
  // src/proxmox/notification-matcher.ts
3662
3636
  import { Resource as Resource17 } from "alchemy";
3663
3637
  import * as Provider17 from "alchemy/Provider";
3664
- import * as Effect44 from "effect/Effect";
3638
+ import * as Effect43 from "effect/Effect";
3665
3639
 
3666
3640
  // src/proxmox/notification-matcher-form.ts
3667
3641
  var list = (value) => Array.isArray(value) ? value.map((item) => String(item)) : [];
@@ -3751,11 +3725,11 @@ var handlers10 = pveHandlers({
3751
3725
  path: (props) => `cluster/notifications/matchers/${props.name}`,
3752
3726
  updateForm: matcherUpdateForm
3753
3727
  });
3754
- var ProxmoxNotificationMatcherProvider = () => Provider17.effect(ProxmoxNotificationMatcher, Effect44.succeed(ProxmoxNotificationMatcher.Provider.of(handlers10)));
3728
+ var ProxmoxNotificationMatcherProvider = () => Provider17.effect(ProxmoxNotificationMatcher, Effect43.succeed(ProxmoxNotificationMatcher.Provider.of(handlers10)));
3755
3729
  // src/proxmox/notification-target.ts
3756
3730
  import { Resource as Resource18 } from "alchemy";
3757
3731
  import * as Provider18 from "alchemy/Provider";
3758
- import * as Effect45 from "effect/Effect";
3732
+ import * as Effect44 from "effect/Effect";
3759
3733
 
3760
3734
  // src/proxmox/notification-target-endpoint.ts
3761
3735
  var ENDPOINTS = {
@@ -3837,15 +3811,15 @@ var handlers11 = pveHandlers({
3837
3811
  path: (props) => `cluster/notifications/endpoints/${props.type}/${props.name}`,
3838
3812
  updateForm: shape4
3839
3813
  });
3840
- var ProxmoxNotificationTargetProvider = () => Provider18.effect(ProxmoxNotificationTarget, Effect45.succeed(ProxmoxNotificationTarget.Provider.of(handlers11)));
3814
+ var ProxmoxNotificationTargetProvider = () => Provider18.effect(ProxmoxNotificationTarget, Effect44.succeed(ProxmoxNotificationTarget.Provider.of(handlers11)));
3841
3815
  // src/proxmox/pbs-datastore.ts
3842
3816
  import { Resource as Resource19 } from "alchemy";
3843
3817
  import { isResolved as isResolved13 } from "alchemy/Diff";
3844
3818
  import * as Provider19 from "alchemy/Provider";
3845
- import * as Effect49 from "effect/Effect";
3819
+ import * as Effect48 from "effect/Effect";
3846
3820
 
3847
3821
  // src/proxmox/pbs-datastore-form.ts
3848
- import * as Effect46 from "effect/Effect";
3822
+ import * as Effect45 from "effect/Effect";
3849
3823
  var attributes = (live, props) => ({
3850
3824
  backend: propertyString(live["backend"]),
3851
3825
  comment: text(live["comment"]),
@@ -3897,35 +3871,35 @@ var createForm6 = (props) => ({
3897
3871
  });
3898
3872
  var updateForm3 = (props) => mutable(props);
3899
3873
  var object2 = (props) => `config/datastore/${props.name}`;
3900
- var readOne = (props) => pve(props.target, "read", "GET", object2(props)).pipe(Effect46.map((live) => live === undefined || typeof live["name"] !== "string" ? undefined : attributes(live, props)), Effect46.orElseSucceed(() => {
3874
+ var readOne = (props) => pve(props.target, "read", "GET", object2(props)).pipe(Effect45.map((live) => live === undefined || typeof live["name"] !== "string" ? undefined : attributes(live, props)), Effect45.orElseSucceed(() => {
3901
3875
  return;
3902
3876
  }));
3903
3877
 
3904
3878
  // src/proxmox/pbs-datastore-guard.ts
3905
- import * as Effect47 from "effect/Effect";
3879
+ import * as Effect46 from "effect/Effect";
3906
3880
  var samePath = (left, right) => {
3907
3881
  const trim = (value) => value.length > 1 ? value.replace(/\/+$/, "") : value;
3908
3882
  return trim(left) === trim(right);
3909
3883
  };
3910
- var guardPath = (live, props) => live.path === "" || samePath(live.path, props.path) ? Effect47.void : Effect47.die(new Error(`${object2(props)}: declared path ${props.path} but PBS holds ${live.path}. \`path\` ` + "is create-only, so this cannot be reconciled and will NOT be planned as a silent " + "noop: backups would keep landing in the old directory behind a green plan. Correct " + "the declaration, or remove the datastore and declare a new one -- the contents live, " + "because `destroy-data` is never sent."));
3911
- var guardBackend = (live, props) => props.backend === undefined || propertyString(props.backend) === live.backend ? Effect47.void : Effect47.die(new Error(`${object2(props)}: declared backend ${props.backend} but PBS holds ` + `${live.backend === "" ? "(none — a local datastore)" : live.backend}. \`backend\` ` + "is create-only: PBS has no update for it, so this cannot be reconciled and will NOT " + "be planned as a silent noop. Correct the declaration to match what is really there, " + "or remove the datastore and declare a new one -- the contents live, because " + "`destroy-data` is never sent."));
3912
- var settle3 = (read3, done) => Effect47.gen(function* () {
3884
+ var guardPath = (live, props) => live.path === "" || samePath(live.path, props.path) ? Effect46.void : Effect46.die(new Error(`${object2(props)}: declared path ${props.path} but PBS holds ${live.path}. \`path\` ` + "is create-only, so this cannot be reconciled and will NOT be planned as a silent " + "noop: backups would keep landing in the old directory behind a green plan. Correct " + "the declaration, or remove the datastore and declare a new one -- the contents live, " + "because `destroy-data` is never sent."));
3885
+ var guardBackend = (live, props) => props.backend === undefined || propertyString(props.backend) === live.backend ? Effect46.void : Effect46.die(new Error(`${object2(props)}: declared backend ${props.backend} but PBS holds ` + `${live.backend === "" ? "(none — a local datastore)" : live.backend}. \`backend\` ` + "is create-only: PBS has no update for it, so this cannot be reconciled and will NOT " + "be planned as a silent noop. Correct the declaration to match what is really there, " + "or remove the datastore and declare a new one -- the contents live, because " + "`destroy-data` is never sent."));
3886
+ var settle2 = (read3, done) => Effect46.gen(function* () {
3913
3887
  for (let attempt = 0;attempt < 60; attempt += 1) {
3914
3888
  const live = yield* read3;
3915
3889
  if (done(live))
3916
3890
  return live;
3917
- yield* Effect47.sleep("2 seconds");
3891
+ yield* Effect46.sleep("2 seconds");
3918
3892
  }
3919
3893
  return yield* read3;
3920
3894
  });
3921
3895
 
3922
3896
  // src/proxmox/pbs-datastore-endpoint.ts
3923
- import * as Effect48 from "effect/Effect";
3897
+ import * as Effect47 from "effect/Effect";
3924
3898
  var DATASTORE_ENDPOINT = {
3925
3899
  create: "pbs:POST /config/datastore",
3926
3900
  update: "pbs:PUT /config/datastore/{name}"
3927
3901
  };
3928
- var guardDatastoreForms = (props) => Effect48.gen(function* () {
3902
+ var guardDatastoreForms = (props) => Effect47.gen(function* () {
3929
3903
  yield* guardForm(DATASTORE_ENDPOINT.create, createForm6(props), true);
3930
3904
  yield* guardForm(DATASTORE_ENDPOINT.update, updateForm3(props), false);
3931
3905
  });
@@ -3934,10 +3908,10 @@ var guardDatastoreForms = (props) => Effect48.gen(function* () {
3934
3908
  var PbsDatastore = Resource19("Pbs.Datastore", {
3935
3909
  defaultRemovalPolicy: "retain"
3936
3910
  });
3937
- var PbsDatastoreProvider = () => Provider19.effect(PbsDatastore, Effect49.succeed(PbsDatastore.Provider.of({
3938
- list: () => Effect49.succeed([]),
3911
+ var PbsDatastoreProvider = () => Provider19.effect(PbsDatastore, Effect48.succeed(PbsDatastore.Provider.of({
3912
+ list: () => Effect48.succeed([]),
3939
3913
  read: ({ olds }) => readOne(olds),
3940
- diff: ({ news, output }) => Effect49.gen(function* () {
3914
+ diff: ({ news, output }) => Effect48.gen(function* () {
3941
3915
  if (!isResolved13(news))
3942
3916
  return;
3943
3917
  yield* guardDatastoreForms(news);
@@ -3950,7 +3924,7 @@ var PbsDatastoreProvider = () => Provider19.effect(PbsDatastore, Effect49.succee
3950
3924
  yield* guardBackend(live, news);
3951
3925
  return matches6(live, news) ? { action: "noop" } : { action: "update" };
3952
3926
  }),
3953
- reconcile: Effect49.fn(function* ({ news }) {
3927
+ reconcile: Effect48.fn(function* ({ news }) {
3954
3928
  yield* guardDatastoreForms(news);
3955
3929
  const live = yield* readOne(news);
3956
3930
  let upid;
@@ -3964,24 +3938,24 @@ var PbsDatastoreProvider = () => Provider19.effect(PbsDatastore, Effect49.succee
3964
3938
  yield* pve(news.target, "provision", "PUT", object2(news), form);
3965
3939
  }
3966
3940
  }
3967
- const after = yield* settle3(readOne(news), (row) => row !== undefined && matches6(row, news));
3941
+ const after = yield* settle2(readOne(news), (row) => row !== undefined && matches6(row, news));
3968
3942
  if (after === undefined || !matches6(after, news)) {
3969
- return yield* Effect49.die(new Error(`${object2(news)}: the write returned no error but the datastore still does not ` + `match the declaration after 120s. PBS answered with task ${upid ?? "(none)"} ` + "-- read it with `proxmox-backup-manager task log <upid>`. A slow disk is a " + "plausible cause (see `settle`); a create over an existing chunk store is not, " + "because PBS refuses that outright rather than timing out."));
3943
+ return yield* Effect48.die(new Error(`${object2(news)}: the write returned no error but the datastore still does not ` + `match the declaration after 120s. PBS answered with task ${upid ?? "(none)"} ` + "-- read it with `proxmox-backup-manager task log <upid>`. A slow disk is a " + "plausible cause (see `settle`); a create over an existing chunk store is not, " + "because PBS refuses that outright rather than timing out."));
3970
3944
  }
3971
3945
  return after;
3972
3946
  }),
3973
- delete: Effect49.fn(function* ({ olds }) {
3947
+ delete: Effect48.fn(function* ({ olds }) {
3974
3948
  yield* pve(olds.target, "provision", "DELETE", object2(olds));
3975
- const left = yield* settle3(readOne(olds), (row) => row === undefined);
3949
+ const left = yield* settle2(readOne(olds), (row) => row === undefined);
3976
3950
  if (left !== undefined) {
3977
- return yield* Effect49.die(new Error(`${object2(olds)}: the DELETE returned no error but the datastore is still in ` + "datastore.cfg after 120s. Either a backup, verify or GC task still holds it, " + "or the provision role lacks Datastore.Allocate on /datastore/" + `${olds.name}. Read the task log with \`proxmox-backup-manager task log <upid>\`.`));
3951
+ return yield* Effect48.die(new Error(`${object2(olds)}: the DELETE returned no error but the datastore is still in ` + "datastore.cfg after 120s. Either a backup, verify or GC task still holds it, " + "or the provision role lacks Datastore.Allocate on /datastore/" + `${olds.name}. Read the task log with \`proxmox-backup-manager task log <upid>\`.`));
3978
3952
  }
3979
3953
  })
3980
3954
  })));
3981
3955
  // src/proxmox/pbs-notification-matcher.ts
3982
3956
  import { Resource as Resource20 } from "alchemy";
3983
3957
  import * as Provider20 from "alchemy/Provider";
3984
- import * as Effect50 from "effect/Effect";
3958
+ import * as Effect49 from "effect/Effect";
3985
3959
  var PbsNotificationMatcher = Resource20("Pbs.NotificationMatcher");
3986
3960
  var handlers12 = pveHandlers({
3987
3961
  attributes: (live, props) => matcherAttributes(live, props.name),
@@ -3995,15 +3969,15 @@ var handlers12 = pveHandlers({
3995
3969
  path: (props) => `config/notifications/matchers/${props.name}`,
3996
3970
  updateForm: matcherUpdateForm
3997
3971
  });
3998
- var PbsNotificationMatcherProvider = () => Provider20.effect(PbsNotificationMatcher, Effect50.succeed(PbsNotificationMatcher.Provider.of(handlers12)));
3972
+ var PbsNotificationMatcherProvider = () => Provider20.effect(PbsNotificationMatcher, Effect49.succeed(PbsNotificationMatcher.Provider.of(handlers12)));
3999
3973
  // src/proxmox/pbs-notification-target.ts
4000
3974
  import { Resource as Resource21 } from "alchemy";
4001
3975
  import * as Provider21 from "alchemy/Provider";
4002
- import * as Effect52 from "effect/Effect";
3976
+ import * as Effect51 from "effect/Effect";
4003
3977
 
4004
3978
  // src/proxmox/pbs-notification-target-lifecycle.ts
4005
3979
  import { isResolved as isResolved14 } from "alchemy/Diff";
4006
- import * as Effect51 from "effect/Effect";
3980
+ import * as Effect50 from "effect/Effect";
4007
3981
 
4008
3982
  // src/proxmox/pbs-notification-target-endpoint.ts
4009
3983
  var ENDPOINTS2 = {
@@ -4280,12 +4254,12 @@ var targetForm = (props, groups, carry, mode) => {
4280
4254
 
4281
4255
  // src/proxmox/pbs-notification-target-lifecycle.ts
4282
4256
  var path = (props) => `config/notifications/endpoints/${props.type}/${props.name}`;
4283
- var readLive2 = (props) => pve(props.target, "read", "GET", path(props)).pipe(Effect51.map((data) => data == null ? undefined : targetAttributes(data, props)), Effect51.orElseSucceed(() => {
4257
+ var readLive2 = (props) => pve(props.target, "read", "GET", path(props)).pipe(Effect50.map((data) => data == null ? undefined : targetAttributes(data, props)), Effect50.orElseSucceed(() => {
4284
4258
  return;
4285
4259
  }));
4286
4260
  var refuse2 = (props) => {
4287
4261
  const reasons = refusals(props);
4288
- return reasons.length === 0 ? Effect51.void : Effect51.die(new Error(`${path(props)}: ${reasons.join("; ")}.`));
4262
+ return reasons.length === 0 ? Effect50.void : Effect50.die(new Error(`${path(props)}: ${reasons.join("; ")}.`));
4289
4263
  };
4290
4264
  var toCarry = (live, props, groups, sealed) => {
4291
4265
  const header = headerState(live, props, groups) === "stale";
@@ -4297,16 +4271,16 @@ var requireValues = (props, groups, carry) => {
4297
4271
  ...carry.header ? groups.header.missing : [],
4298
4272
  ...carry.sealed ? groups.sealed.missing : []
4299
4273
  ];
4300
- return missing.length === 0 ? Effect51.void : Effect51.die(new Error(`${path(props)}: this write must send write-only values, and ${missing.join(", ")} ` + "is unset or empty in the deploying environment. Export it and deploy again."));
4274
+ return missing.length === 0 ? Effect50.void : Effect50.die(new Error(`${path(props)}: this write must send write-only values, and ${missing.join(", ")} ` + "is unset or empty in the deploying environment. Export it and deploy again."));
4301
4275
  };
4302
4276
  var handlers13 = {
4303
- list: () => Effect51.succeed([]),
4304
- read: ({ olds, output }) => (output === undefined ? refuse2(olds) : Effect51.void).pipe(Effect51.andThen(readLive2(olds)), Effect51.map((live) => live === undefined ? undefined : { ...live, sealed: output?.sealed ?? "" })),
4277
+ list: () => Effect50.succeed([]),
4278
+ read: ({ olds, output }) => (output === undefined ? refuse2(olds) : Effect50.void).pipe(Effect50.andThen(readLive2(olds)), Effect50.map((live) => live === undefined ? undefined : { ...live, sealed: output?.sealed ?? "" })),
4305
4279
  diff: ({
4306
4280
  news,
4307
4281
  olds,
4308
4282
  output
4309
- }) => Effect51.gen(function* () {
4283
+ }) => Effect50.gen(function* () {
4310
4284
  if (output === undefined || !isResolved14(news))
4311
4285
  return;
4312
4286
  if (olds !== undefined && (olds.type !== news.type || olds.name !== news.name)) {
@@ -4318,7 +4292,7 @@ var handlers13 = {
4318
4292
  return { action: "update" };
4319
4293
  return toCarry(live, news, resolveGroups(news), output.sealed) === undefined ? { action: "noop" } : { action: "update" };
4320
4294
  }),
4321
- reconcile: ({ news, output }) => Effect51.gen(function* () {
4295
+ reconcile: ({ news, output }) => Effect50.gen(function* () {
4322
4296
  yield* refuse2(news);
4323
4297
  const groups = resolveGroups(news);
4324
4298
  const live = yield* readLive2(news);
@@ -4344,7 +4318,7 @@ var handlers13 = {
4344
4318
  }
4345
4319
  const after = yield* readLive2(news);
4346
4320
  if (after === undefined) {
4347
- return yield* Effect51.die(new Error(`${path(news)}: the write returned no error but the target is still absent.`));
4321
+ return yield* Effect50.die(new Error(`${path(news)}: the write returned no error but the target is still absent.`));
4348
4322
  }
4349
4323
  return { ...after, sealed };
4350
4324
  }),
@@ -4353,11 +4327,11 @@ var handlers13 = {
4353
4327
 
4354
4328
  // src/proxmox/pbs-notification-target.ts
4355
4329
  var PbsNotificationTarget = Resource21("Pbs.NotificationTarget");
4356
- var PbsNotificationTargetProvider = () => Provider21.effect(PbsNotificationTarget, Effect52.succeed(PbsNotificationTarget.Provider.of(handlers13)));
4330
+ var PbsNotificationTargetProvider = () => Provider21.effect(PbsNotificationTarget, Effect51.succeed(PbsNotificationTarget.Provider.of(handlers13)));
4357
4331
  // src/proxmox/pbs-prune-job.ts
4358
4332
  import { Resource as Resource22 } from "alchemy";
4359
4333
  import * as Provider22 from "alchemy/Provider";
4360
- import * as Effect53 from "effect/Effect";
4334
+ import * as Effect52 from "effect/Effect";
4361
4335
 
4362
4336
  // src/proxmox/pbs-prune-job-form.ts
4363
4337
  var KEEP_KEYS = [
@@ -4433,11 +4407,11 @@ var handlers14 = pveHandlers({
4433
4407
  path: (props) => `config/prune/${props.id}`,
4434
4408
  updateForm: updateBody2
4435
4409
  });
4436
- var PbsPruneJobProvider = () => Provider22.effect(PbsPruneJob, Effect53.succeed(PbsPruneJob.Provider.of(handlers14)));
4410
+ var PbsPruneJobProvider = () => Provider22.effect(PbsPruneJob, Effect52.succeed(PbsPruneJob.Provider.of(handlers14)));
4437
4411
  // src/proxmox/pbs-sync-job.ts
4438
4412
  import { Resource as Resource23 } from "alchemy";
4439
4413
  import * as Provider23 from "alchemy/Provider";
4440
- import * as Effect54 from "effect/Effect";
4414
+ import * as Effect53 from "effect/Effect";
4441
4415
 
4442
4416
  // src/proxmox/pbs-sync-job-form.ts
4443
4417
  var UNSET4 = -1;
@@ -4514,11 +4488,11 @@ var handlers15 = pveHandlers({
4514
4488
 
4515
4489
  // src/proxmox/pbs-sync-job.ts
4516
4490
  var PbsSyncJob = Resource23("Pbs.SyncJob");
4517
- var PbsSyncJobProvider = () => Provider23.effect(PbsSyncJob, Effect54.succeed(PbsSyncJob.Provider.of(handlers15)));
4491
+ var PbsSyncJobProvider = () => Provider23.effect(PbsSyncJob, Effect53.succeed(PbsSyncJob.Provider.of(handlers15)));
4518
4492
  // src/proxmox/pbs-verify-job.ts
4519
4493
  import { Resource as Resource24 } from "alchemy";
4520
4494
  import * as Provider24 from "alchemy/Provider";
4521
- import * as Effect55 from "effect/Effect";
4495
+ import * as Effect54 from "effect/Effect";
4522
4496
 
4523
4497
  // src/proxmox/pbs-verify-job-form.ts
4524
4498
  var rechecks = (ignoreVerified, outdatedAfter) => {
@@ -4563,11 +4537,11 @@ var handlers16 = pveHandlers({
4563
4537
  path: (props) => `config/verify/${props.id}`,
4564
4538
  updateForm: shape7
4565
4539
  });
4566
- var PbsVerifyJobProvider = () => Provider24.effect(PbsVerifyJob, Effect55.succeed(PbsVerifyJob.Provider.of(handlers16)));
4540
+ var PbsVerifyJobProvider = () => Provider24.effect(PbsVerifyJob, Effect54.succeed(PbsVerifyJob.Provider.of(handlers16)));
4567
4541
  // src/proxmox/pool.ts
4568
4542
  import { Resource as Resource25 } from "alchemy";
4569
4543
  import * as Provider25 from "alchemy/Provider";
4570
- import * as Effect56 from "effect/Effect";
4544
+ import * as Effect55 from "effect/Effect";
4571
4545
  var ProxmoxPool = Resource25("Proxmox.Pool");
4572
4546
  var poolCreateForm = (props) => ({
4573
4547
  comment: props.comment ?? "",
@@ -4592,7 +4566,7 @@ var handlers17 = pveHandlers({
4592
4566
  path: (props) => `pools/${props.poolid}`,
4593
4567
  updateForm: poolUpdateForm
4594
4568
  });
4595
- var ProxmoxPoolProvider = () => Provider25.effect(ProxmoxPool, Effect56.succeed(ProxmoxPool.Provider.of(handlers17)));
4569
+ var ProxmoxPoolProvider = () => Provider25.effect(ProxmoxPool, Effect55.succeed(ProxmoxPool.Provider.of(handlers17)));
4596
4570
  // src/proxmox/provision-baseline.ts
4597
4571
  var PROVISION_PRIVILEGES = Object.freeze([
4598
4572
  "Datastore.Allocate",
@@ -4785,14 +4759,14 @@ echo 'provision baseline: done. Next: point the OpenBao proxmox mount at these u
4785
4759
  // src/proxmox/provision-declare.ts
4786
4760
  import { adopt } from "alchemy/AdoptPolicy";
4787
4761
  import * as RemovalPolicy from "alchemy/RemovalPolicy";
4788
- import * as Effect60 from "effect/Effect";
4762
+ import * as Effect59 from "effect/Effect";
4789
4763
 
4790
4764
  // src/proxmox/role.ts
4791
4765
  import { Resource as Resource26 } from "alchemy";
4792
4766
  import { isResolved as isResolved15 } from "alchemy/Diff";
4793
4767
  import * as Provider26 from "alchemy/Provider";
4794
4768
  import * as access5 from "@distilled.cloud/proxmox/access";
4795
- import * as Effect57 from "effect/Effect";
4769
+ import * as Effect56 from "effect/Effect";
4796
4770
 
4797
4771
  // src/proxmox/role-wire.ts
4798
4772
  var ROLE_CREATE = "pve:POST /access/roles";
@@ -4815,19 +4789,19 @@ var matches7 = (attributes2, props) => canonical2(attributes2.privs).join(",") =
4815
4789
 
4816
4790
  // src/proxmox/role.ts
4817
4791
  var ProxmoxRole = Resource26("Proxmox.Role");
4818
- var readRole = (props) => readOrUnreadable(runPve(props.target, "read", false, access5.listAccessRoles({}))).pipe(Effect57.map((rows) => {
4792
+ var readRole = (props) => readOrUnreadable(runPve(props.target, "read", false, access5.listAccessRoles({}))).pipe(Effect56.map((rows) => {
4819
4793
  if (rows === UNREADABLE)
4820
4794
  return UNREADABLE;
4821
4795
  const row = find2(rows, props.roleid);
4822
4796
  return row === undefined ? undefined : attributesOf7(row, props);
4823
4797
  }));
4824
4798
  var dropUnreadable5 = (live) => live === UNREADABLE ? undefined : live;
4825
- var ProxmoxRoleProvider = () => Provider26.effect(ProxmoxRole, Effect57.succeed(ProxmoxRole.Provider.of({
4826
- list: () => Effect57.succeed([]),
4827
- read: Effect57.fn(function* ({ olds }) {
4799
+ var ProxmoxRoleProvider = () => Provider26.effect(ProxmoxRole, Effect56.succeed(ProxmoxRole.Provider.of({
4800
+ list: () => Effect56.succeed([]),
4801
+ read: Effect56.fn(function* ({ olds }) {
4828
4802
  return dropUnreadable5(yield* readRole(olds));
4829
4803
  }),
4830
- diff: Effect57.fn(function* ({ news, output }) {
4804
+ diff: Effect56.fn(function* ({ news, output }) {
4831
4805
  if (!isResolved15(news))
4832
4806
  return;
4833
4807
  yield* guardWrite2(ROLE_CREATE, createForm7(news), output === undefined);
@@ -4845,7 +4819,7 @@ var ProxmoxRoleProvider = () => Provider26.effect(ProxmoxRole, Effect57.succeed(
4845
4819
  }
4846
4820
  return matches7(live, news) ? { action: "noop" } : { action: "update" };
4847
4821
  }),
4848
- reconcile: Effect57.fn(function* ({ news }) {
4822
+ reconcile: Effect56.fn(function* ({ news }) {
4849
4823
  const before = dropUnreadable5(yield* readRole(news));
4850
4824
  yield* guardWrite2(ROLE_CREATE, createForm7(news), before === undefined);
4851
4825
  yield* guardWrite2(ROLE_UPDATE, updateForm4(news), false);
@@ -4856,11 +4830,11 @@ var ProxmoxRoleProvider = () => Provider26.effect(ProxmoxRole, Effect57.succeed(
4856
4830
  }
4857
4831
  const after = dropUnreadable5(yield* readRole(news));
4858
4832
  if (after === undefined) {
4859
- return yield* Effect57.die(new Error(`access/roles/${news.roleid}: the write returned no error but the role 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."));
4833
+ return yield* Effect56.die(new Error(`access/roles/${news.roleid}: the write returned no error but the role 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."));
4860
4834
  }
4861
4835
  return after;
4862
4836
  }),
4863
- delete: Effect57.fn(function* ({ olds }) {
4837
+ delete: Effect56.fn(function* ({ olds }) {
4864
4838
  yield* runPve(olds.target, "provision", true, access5.deleteAccessRole({ roleid: olds.roleid }));
4865
4839
  })
4866
4840
  })));
@@ -4870,11 +4844,11 @@ import { Resource as Resource27 } from "alchemy";
4870
4844
  import { isResolved as isResolved16 } from "alchemy/Diff";
4871
4845
  import * as Provider27 from "alchemy/Provider";
4872
4846
  import * as access7 from "@distilled.cloud/proxmox/access";
4873
- import * as Effect59 from "effect/Effect";
4847
+ import * as Effect58 from "effect/Effect";
4874
4848
 
4875
4849
  // src/proxmox/user-wire.ts
4876
4850
  import * as access6 from "@distilled.cloud/proxmox/access";
4877
- import * as Effect58 from "effect/Effect";
4851
+ import * as Effect57 from "effect/Effect";
4878
4852
  var USER_CREATE = "pve:POST /access/users";
4879
4853
  var USER_UPDATE = "pve:PUT /access/users/{userid}";
4880
4854
  var int2 = (value) => {
@@ -4916,20 +4890,18 @@ var attributesOf8 = (live, props) => ({
4916
4890
  userid: props.userid
4917
4891
  });
4918
4892
  var matches8 = (attributes2, props) => attributes2.comment === (props.comment ?? "") && attributes2.email === (props.email ?? "") && attributes2.enable === (props.enable !== false) && attributes2.expire === (props.expire ?? 0) && attributes2.firstname === (props.firstname ?? "") && attributes2.lastname === (props.lastname ?? "") && attributes2.groups.join(",") === groupSet(props.groups).join(",");
4919
- var readUserOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, access6.getAccessUser({ userid: props.userid }))).pipe(Effect58.map((live) => live === UNREADABLE ? UNREADABLE : attributesOf8(live, props)));
4920
- var readUser = (props) => readUserOrFail(props).pipe(Effect58.orElseSucceed(() => {
4921
- return;
4922
- }));
4893
+ var readUserOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, access6.getAccessUser({ userid: props.userid }))).pipe(Effect57.map((live) => live === UNREADABLE ? UNREADABLE : attributesOf8(live, props)));
4894
+ var readUser = (props) => readUserOrFail(props).pipe(Effect57.catchTag("UserNotFound", () => Effect57.succeed(undefined)));
4923
4895
  var dropUnreadable6 = (live) => live === UNREADABLE ? undefined : live;
4924
4896
 
4925
4897
  // src/proxmox/user.ts
4926
4898
  var ProxmoxUser = Resource27("Proxmox.User");
4927
- var ProxmoxUserProvider = () => Provider27.effect(ProxmoxUser, Effect59.succeed(ProxmoxUser.Provider.of({
4928
- list: () => Effect59.succeed([]),
4929
- read: Effect59.fn(function* ({ olds, output }) {
4899
+ var ProxmoxUserProvider = () => Provider27.effect(ProxmoxUser, Effect58.succeed(ProxmoxUser.Provider.of({
4900
+ list: () => Effect58.succeed([]),
4901
+ read: Effect58.fn(function* ({ olds, output }) {
4930
4902
  return dropUnreadable6(yield* output === undefined ? readUser(olds) : readUserOrFail(olds));
4931
4903
  }),
4932
- diff: Effect59.fn(function* ({ news, output }) {
4904
+ diff: Effect58.fn(function* ({ news, output }) {
4933
4905
  if (!isResolved16(news))
4934
4906
  return;
4935
4907
  yield* guardWrite2(USER_CREATE, createForm8(news), output === undefined);
@@ -4947,7 +4919,7 @@ var ProxmoxUserProvider = () => Provider27.effect(ProxmoxUser, Effect59.succeed(
4947
4919
  }
4948
4920
  return matches8(live, news) ? { action: "noop" } : { action: "update" };
4949
4921
  }),
4950
- reconcile: Effect59.fn(function* ({ news }) {
4922
+ reconcile: Effect58.fn(function* ({ news }) {
4951
4923
  const before = dropUnreadable6(yield* readUser(news));
4952
4924
  yield* guardWrite2(USER_CREATE, createForm8(news), before === undefined);
4953
4925
  yield* guardWrite2(USER_UPDATE, updateForm5(news), false);
@@ -4958,18 +4930,18 @@ var ProxmoxUserProvider = () => Provider27.effect(ProxmoxUser, Effect59.succeed(
4958
4930
  }
4959
4931
  const after = dropUnreadable6(yield* readUser(news));
4960
4932
  if (after === undefined) {
4961
- return yield* Effect59.die(new Error(`access/users/${news.userid}: the write returned no error but the account 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."));
4933
+ return yield* Effect58.die(new Error(`access/users/${news.userid}: the write returned no error but the account 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."));
4962
4934
  }
4963
4935
  return after;
4964
4936
  }),
4965
- delete: Effect59.fn(function* ({ olds }) {
4937
+ delete: Effect58.fn(function* ({ olds }) {
4966
4938
  yield* runPve(olds.target, "provision", true, access7.deleteAccessUser({ userid: olds.userid }));
4967
4939
  })
4968
4940
  })));
4969
4941
 
4970
4942
  // src/proxmox/provision-declare.ts
4971
- var declareProvisionBaseline = (id, target, names2 = {}, options = {}) => Effect60.gen(function* () {
4972
- const baseline = yield* Effect60.try({
4943
+ var declareProvisionBaseline = (id, target, names2 = {}, options = {}) => Effect59.gen(function* () {
4944
+ const baseline = yield* Effect59.try({
4973
4945
  catch: (cause) => cause instanceof Error ? cause : new Error(String(cause)),
4974
4946
  try: () => provisionBaseline(names2)
4975
4947
  });
@@ -4983,13 +4955,13 @@ var declareProvisionBaseline = (id, target, names2 = {}, options = {}) => Effect
4983
4955
  target
4984
4956
  }));
4985
4957
  const group = yield* owned(ProxmoxGroup(`${id}-mint-group`, { ...baseline.group, target }));
4986
- const users = yield* Effect60.all(baseline.users.map((user) => owned(ProxmoxUser(`${id}-${user.lane}-user`, {
4958
+ const users = yield* Effect59.all(baseline.users.map((user) => owned(ProxmoxUser(`${id}-${user.lane}-user`, {
4987
4959
  comment: user.comment,
4988
4960
  groups: [...user.groups],
4989
4961
  target,
4990
4962
  userid: user.userid
4991
4963
  }))));
4992
- const grants = yield* Effect60.all(baseline.grants.map((grant) => owned(ProxmoxAcl(`${id}-${grant.lane}-grant`, {
4964
+ const grants = yield* Effect59.all(baseline.grants.map((grant) => owned(ProxmoxAcl(`${id}-${grant.lane}-grant`, {
4993
4965
  path: "/",
4994
4966
  propagate: true,
4995
4967
  roleid: grant.roleid,
@@ -5002,7 +4974,7 @@ var declareProvisionBaseline = (id, target, names2 = {}, options = {}) => Effect
5002
4974
  // src/proxmox/qemu.ts
5003
4975
  import { Resource as Resource28 } from "alchemy";
5004
4976
  import * as Provider28 from "alchemy/Provider";
5005
- import * as Effect61 from "effect/Effect";
4977
+ import * as Effect60 from "effect/Effect";
5006
4978
  var ProxmoxVm = Resource28("Proxmox.Vm");
5007
4979
  var createForm9 = (props) => ({ ...shape9(props), vmid: String(props.vmid) });
5008
4980
  var shape9 = (props) => ({
@@ -5033,11 +5005,11 @@ var handlers18 = pveHandlers({
5033
5005
  path: (props) => `nodes/${props.node}/qemu/${String(props.vmid)}/config`,
5034
5006
  updateForm: shape9
5035
5007
  });
5036
- var ProxmoxVmProvider = () => Provider28.effect(ProxmoxVm, Effect61.succeed(ProxmoxVm.Provider.of(handlers18)));
5008
+ var ProxmoxVmProvider = () => Provider28.effect(ProxmoxVm, Effect60.succeed(ProxmoxVm.Provider.of(handlers18)));
5037
5009
  // src/proxmox/replication-job.ts
5038
5010
  import { Resource as Resource29 } from "alchemy";
5039
5011
  import * as Provider29 from "alchemy/Provider";
5040
- import * as Effect62 from "effect/Effect";
5012
+ import * as Effect61 from "effect/Effect";
5041
5013
 
5042
5014
  // src/proxmox/replication-job-form.ts
5043
5015
  var DEFAULT_SCHEDULE = "*/15";
@@ -5091,15 +5063,15 @@ var handlers19 = pveHandlers({
5091
5063
  path: (props) => `cluster/replication/${jobId(props)}`,
5092
5064
  updateForm: updateBody4
5093
5065
  });
5094
- var ProxmoxReplicationJobProvider = () => Provider29.effect(ProxmoxReplicationJob, Effect62.succeed(ProxmoxReplicationJob.Provider.of(handlers19)));
5066
+ var ProxmoxReplicationJobProvider = () => Provider29.effect(ProxmoxReplicationJob, Effect61.succeed(ProxmoxReplicationJob.Provider.of(handlers19)));
5095
5067
  // src/proxmox/sdn-apply.ts
5096
5068
  import { Resource as Resource30 } from "alchemy";
5097
5069
  import { isResolved as isResolved17 } from "alchemy/Diff";
5098
5070
  import * as Provider30 from "alchemy/Provider";
5099
- import * as Effect64 from "effect/Effect";
5071
+ import * as Effect63 from "effect/Effect";
5100
5072
 
5101
5073
  // src/proxmox/sdn-apply-read.ts
5102
- import * as Effect63 from "effect/Effect";
5074
+ import * as Effect62 from "effect/Effect";
5103
5075
  var MARKED = [
5104
5076
  "cluster/sdn/zones",
5105
5077
  "cluster/sdn/vnets",
@@ -5108,7 +5080,7 @@ var MARKED = [
5108
5080
  "cluster/sdn/route-maps"
5109
5081
  ];
5110
5082
  var subsystemAbsent = (error) => error instanceof PveError && error.status === 501;
5111
- var markedPending = (target) => Effect63.all(MARKED.map((collection) => pve(target, "read", "GET", `${collection}?pending=1`).pipe(Effect63.map((rows) => (rows ?? []).filter((row) => row.state !== undefined).length), Effect63.catchIf(subsystemAbsent, () => Effect63.succeed(0)))), { concurrency: "unbounded" }).pipe(Effect63.map((counts) => counts.reduce((total, count2) => total + count2, 0)));
5083
+ var markedPending = (target) => Effect62.all(MARKED.map((collection) => pve(target, "read", "GET", `${collection}?pending=1`).pipe(Effect62.map((rows) => (rows ?? []).filter((row) => row.state !== undefined).length), Effect62.catchIf(subsystemAbsent, () => Effect62.succeed(0)))), { concurrency: "unbounded" }).pipe(Effect62.map((counts) => counts.reduce((total, count2) => total + count2, 0)));
5112
5084
  var fabricStaged = (staged, running) => {
5113
5085
  if (staged === undefined && running === undefined)
5114
5086
  return 0;
@@ -5116,9 +5088,9 @@ var fabricStaged = (staged, running) => {
5116
5088
  return "inconsistent";
5117
5089
  return staged === running ? 0 : 1;
5118
5090
  };
5119
- var fabricPending = (target) => Effect63.all(["pending", "running"].map((view) => pve(target, "read", "GET", `cluster/sdn/fabrics/all?${view}=1`).pipe(Effect63.map(canonical3), Effect63.catchIf(subsystemAbsent, () => Effect63.succeed(undefined)))), { concurrency: "unbounded" }).pipe(Effect63.flatMap(([staged, running]) => {
5091
+ var fabricPending = (target) => Effect62.all(["pending", "running"].map((view) => pve(target, "read", "GET", `cluster/sdn/fabrics/all?${view}=1`).pipe(Effect62.map(canonical3), Effect62.catchIf(subsystemAbsent, () => Effect62.succeed(undefined)))), { concurrency: "unbounded" }).pipe(Effect62.flatMap(([staged, running]) => {
5120
5092
  const verdict = fabricStaged(staged, running);
5121
- return verdict === "inconsistent" ? Effect63.die(new Error("cluster/sdn/fabrics/all answered 501 for one of ?pending=1 and ?running=1 and not " + "the other. Refusing to read that as a staged fabric change.")) : Effect63.succeed(verdict);
5093
+ return verdict === "inconsistent" ? Effect62.die(new Error("cluster/sdn/fabrics/all answered 501 for one of ?pending=1 and ?running=1 and not " + "the other. Refusing to read that as a staged fabric change.")) : Effect62.succeed(verdict);
5122
5094
  }));
5123
5095
  var canonical3 = (value) => JSON.stringify(sortDeep(value));
5124
5096
  var sortDeep = (value) => {
@@ -5131,23 +5103,23 @@ var sortDeep = (value) => {
5131
5103
  }
5132
5104
  return value;
5133
5105
  };
5134
- var sdnPendingCount = (target) => Effect63.all([markedPending(target), fabricPending(target)], { concurrency: "unbounded" }).pipe(Effect63.map(([marked, fabric]) => marked + fabric));
5106
+ var sdnPendingCount = (target) => Effect62.all([markedPending(target), fabricPending(target)], { concurrency: "unbounded" }).pipe(Effect62.map(([marked, fabric]) => marked + fabric));
5135
5107
 
5136
5108
  // src/proxmox/sdn-apply.ts
5137
5109
  var ProxmoxSdnApply = Resource30("Proxmox.SdnApply");
5138
- var read3 = (props) => sdnPendingCount(props.target).pipe(Effect64.map((pending) => ({ pending })));
5139
- var ProxmoxSdnApplyProvider = () => Provider30.effect(ProxmoxSdnApply, Effect64.succeed(ProxmoxSdnApply.Provider.of({
5140
- list: () => Effect64.succeed([]),
5141
- read: Effect64.fn(function* ({ olds }) {
5110
+ var read3 = (props) => sdnPendingCount(props.target).pipe(Effect63.map((pending) => ({ pending })));
5111
+ var ProxmoxSdnApplyProvider = () => Provider30.effect(ProxmoxSdnApply, Effect63.succeed(ProxmoxSdnApply.Provider.of({
5112
+ list: () => Effect63.succeed([]),
5113
+ read: Effect63.fn(function* ({ olds }) {
5142
5114
  return yield* read3(olds);
5143
5115
  }),
5144
- diff: Effect64.fn(function* ({ news }) {
5116
+ diff: Effect63.fn(function* ({ news }) {
5145
5117
  if (!isResolved17(news))
5146
5118
  return;
5147
5119
  const { pending } = yield* read3(news);
5148
5120
  return pending === 0 ? { action: "noop" } : { action: "update" };
5149
5121
  }),
5150
- reconcile: Effect64.fn(function* ({ news }) {
5122
+ reconcile: Effect63.fn(function* ({ news }) {
5151
5123
  const staged = yield* read3(news);
5152
5124
  if (staged.pending === 0)
5153
5125
  return staged;
@@ -5155,16 +5127,16 @@ var ProxmoxSdnApplyProvider = () => Provider30.effect(ProxmoxSdnApply, Effect64.
5155
5127
  yield* pve(news.target, "provision", "PUT", "cluster/sdn");
5156
5128
  const after = yield* read3(news);
5157
5129
  if (after.pending !== 0) {
5158
- return yield* Effect64.die(new Error(`PUT /cluster/sdn returned no error but ${String(after.pending)} SDN object(s) ` + "are still staged. The running config does not match the declared one -- check " + "`pvesh get /cluster/sdn/zones --pending 1` for the objects PVE refused."));
5130
+ return yield* Effect63.die(new Error(`PUT /cluster/sdn returned no error but ${String(after.pending)} SDN object(s) ` + "are still staged. The running config does not match the declared one -- check " + "`pvesh get /cluster/sdn/zones --pending 1` for the objects PVE refused."));
5159
5131
  }
5160
5132
  return after;
5161
5133
  }),
5162
- delete: () => Effect64.void
5134
+ delete: () => Effect63.void
5163
5135
  })));
5164
5136
  // src/proxmox/sdn-subnet.ts
5165
5137
  import { Resource as Resource31 } from "alchemy";
5166
5138
  import * as Provider31 from "alchemy/Provider";
5167
- import * as Effect65 from "effect/Effect";
5139
+ import * as Effect64 from "effect/Effect";
5168
5140
 
5169
5141
  // src/proxmox/sdn-subnet-form.ts
5170
5142
  var subnetId = (props) => `${props.zone}-${props.cidr.replace("/", "-")}`;
@@ -5224,11 +5196,11 @@ var handlers20 = pveHandlers({
5224
5196
  path: (props) => `cluster/sdn/vnets/${props.vnet}/subnets/${subnetId(props)}`,
5225
5197
  updateForm: updateForm6
5226
5198
  });
5227
- var ProxmoxSdnSubnetProvider = () => Provider31.effect(ProxmoxSdnSubnet, Effect65.succeed(ProxmoxSdnSubnet.Provider.of(handlers20)));
5199
+ var ProxmoxSdnSubnetProvider = () => Provider31.effect(ProxmoxSdnSubnet, Effect64.succeed(ProxmoxSdnSubnet.Provider.of(handlers20)));
5228
5200
  // src/proxmox/sdn-vnet.ts
5229
5201
  import { Resource as Resource32 } from "alchemy";
5230
5202
  import * as Provider32 from "alchemy/Provider";
5231
- import * as Effect66 from "effect/Effect";
5203
+ import * as Effect65 from "effect/Effect";
5232
5204
  var ProxmoxSdnVnet = Resource32("Proxmox.SdnVnet");
5233
5205
  var tagOf = (value) => typeof value === "number" ? value : undefined;
5234
5206
  var shape11 = (props) => {
@@ -5266,11 +5238,11 @@ var handlers21 = pveHandlers({
5266
5238
  path: (props) => `cluster/sdn/vnets/${props.vnet}`,
5267
5239
  updateForm: updateForm7
5268
5240
  });
5269
- var ProxmoxSdnVnetProvider = () => Provider32.effect(ProxmoxSdnVnet, Effect66.succeed(ProxmoxSdnVnet.Provider.of(handlers21)));
5241
+ var ProxmoxSdnVnetProvider = () => Provider32.effect(ProxmoxSdnVnet, Effect65.succeed(ProxmoxSdnVnet.Provider.of(handlers21)));
5270
5242
  // src/proxmox/sdn-zone.ts
5271
5243
  import { Resource as Resource33 } from "alchemy";
5272
5244
  import * as Provider33 from "alchemy/Provider";
5273
- import * as Effect67 from "effect/Effect";
5245
+ import * as Effect66 from "effect/Effect";
5274
5246
  var ProxmoxSdnZone = Resource33("Proxmox.SdnZone");
5275
5247
  var sameIpam = (live, declared2) => (live === "" ? "pve" : live) === (declared2 === undefined || declared2 === "" ? "pve" : declared2);
5276
5248
  var body6 = (props) => ({
@@ -5323,13 +5295,13 @@ var handlers22 = pveHandlers({
5323
5295
  return withClears(fields, clear);
5324
5296
  }
5325
5297
  });
5326
- var ProxmoxSdnZoneProvider = () => Provider33.effect(ProxmoxSdnZone, Effect67.succeed(ProxmoxSdnZone.Provider.of(handlers22)));
5298
+ var ProxmoxSdnZoneProvider = () => Provider33.effect(ProxmoxSdnZone, Effect66.succeed(ProxmoxSdnZone.Provider.of(handlers22)));
5327
5299
  // src/proxmox/storage.ts
5328
5300
  import { Resource as Resource34 } from "alchemy";
5329
5301
  import { isResolved as isResolved18 } from "alchemy/Diff";
5330
5302
  import * as Provider34 from "alchemy/Provider";
5331
5303
  import * as storage2 from "@distilled.cloud/proxmox/storage";
5332
- import * as Effect69 from "effect/Effect";
5304
+ import * as Effect68 from "effect/Effect";
5333
5305
 
5334
5306
  // src/proxmox/storage-form.ts
5335
5307
  var STORAGE_CREATE = "pve:POST /storage";
@@ -5361,7 +5333,7 @@ var toDistilledUpdate3 = (props) => underscored(updateForm8(props));
5361
5333
 
5362
5334
  // src/proxmox/storage-wire.ts
5363
5335
  import * as storage from "@distilled.cloud/proxmox/storage";
5364
- import * as Effect68 from "effect/Effect";
5336
+ import * as Effect67 from "effect/Effect";
5365
5337
  var str2 = (value, fallback = "") => typeof value === "string" ? value : fallback;
5366
5338
  var tokens = (value) => value.split(",").map((part) => part.trim()).filter((part) => part !== "").sort().join(",");
5367
5339
  var sameList2 = (declared2, live) => declared2 === undefined || tokens(declared2) === tokens(live);
@@ -5380,10 +5352,8 @@ var attributesOf9 = (live, props) => {
5380
5352
  type: str2(data["type"], props.type)
5381
5353
  };
5382
5354
  };
5383
- var readStorageOrFail = (props) => readOrUnreadable(runPve(props.target, "provision", false, storage.getStorage({ storage: props.storage }))).pipe(Effect68.map((live) => live === UNREADABLE ? UNREADABLE : attributesOf9(live, props)));
5384
- var readStorage = (props) => readStorageOrFail(props).pipe(Effect68.orElseSucceed(() => {
5385
- return;
5386
- }));
5355
+ var readStorageOrFail = (props) => readOrUnreadable(runPve(props.target, "provision", false, storage.getStorage({ storage: props.storage }))).pipe(Effect67.map((live) => live === UNREADABLE ? UNREADABLE : attributesOf9(live, props)));
5356
+ var readStorage = (props) => readStorageOrFail(props).pipe(Effect67.catchTag("StorageNotFound", () => Effect67.succeed(undefined)));
5387
5357
  var dropUnreadable7 = (live) => live === UNREADABLE ? undefined : live;
5388
5358
  var matches9 = (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);
5389
5359
 
@@ -5391,12 +5361,12 @@ var matches9 = (attributes2, props) => sameList2(props.content, attributes2.cont
5391
5361
  var ProxmoxStorage = Resource34("Proxmox.Storage", {
5392
5362
  defaultRemovalPolicy: "retain"
5393
5363
  });
5394
- var ProxmoxStorageProvider = () => Provider34.effect(ProxmoxStorage, Effect69.succeed(ProxmoxStorage.Provider.of({
5395
- list: () => Effect69.succeed([]),
5396
- read: Effect69.fn(function* ({ olds, output }) {
5364
+ var ProxmoxStorageProvider = () => Provider34.effect(ProxmoxStorage, Effect68.succeed(ProxmoxStorage.Provider.of({
5365
+ list: () => Effect68.succeed([]),
5366
+ read: Effect68.fn(function* ({ olds, output }) {
5397
5367
  return dropUnreadable7(yield* output === undefined ? readStorage(olds) : readStorageOrFail(olds));
5398
5368
  }),
5399
- diff: Effect69.fn(function* ({ news, output }) {
5369
+ diff: Effect68.fn(function* ({ news, output }) {
5400
5370
  if (!isResolved18(news))
5401
5371
  return;
5402
5372
  yield* guardWrite2(STORAGE_CREATE, createForm11(news), output === undefined);
@@ -5414,7 +5384,7 @@ var ProxmoxStorageProvider = () => Provider34.effect(ProxmoxStorage, Effect69.su
5414
5384
  }
5415
5385
  return matches9(live, news) ? { action: "noop" } : { action: "update" };
5416
5386
  }),
5417
- reconcile: Effect69.fn(function* ({ news }) {
5387
+ reconcile: Effect68.fn(function* ({ news }) {
5418
5388
  const before = dropUnreadable7(yield* readStorage(news));
5419
5389
  yield* guardWrite2(STORAGE_CREATE, createForm11(news), before === undefined);
5420
5390
  yield* guardWrite2(STORAGE_UPDATE, updateForm8(news), false);
@@ -5425,11 +5395,11 @@ var ProxmoxStorageProvider = () => Provider34.effect(ProxmoxStorage, Effect69.su
5425
5395
  }
5426
5396
  const after = dropUnreadable7(yield* readStorage(news));
5427
5397
  if (after === undefined) {
5428
- return yield* Effect69.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."));
5398
+ return yield* Effect68.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."));
5429
5399
  }
5430
5400
  return after;
5431
5401
  }),
5432
- delete: Effect69.fn(function* ({ olds }) {
5402
+ delete: Effect68.fn(function* ({ olds }) {
5433
5403
  yield* runPve(olds.target, "provision", true, storage2.deleteStorage({ storage: olds.storage }));
5434
5404
  })
5435
5405
  })));
@@ -5437,11 +5407,11 @@ var ProxmoxStorageProvider = () => Provider34.effect(ProxmoxStorage, Effect69.su
5437
5407
  import { Resource as Resource35 } from "alchemy";
5438
5408
  import { isResolved as isResolved19 } from "alchemy/Diff";
5439
5409
  import * as Provider35 from "alchemy/Provider";
5440
- import * as Effect72 from "effect/Effect";
5410
+ import * as Effect71 from "effect/Effect";
5441
5411
 
5442
5412
  // src/proxmox/zfs-pool-wire.ts
5443
5413
  import * as nodes10 from "@distilled.cloud/proxmox/nodes";
5444
- import * as Effect70 from "effect/Effect";
5414
+ import * as Effect69 from "effect/Effect";
5445
5415
  var leafDevices = (children) => Array.isArray(children) ? children.flatMap((entry) => {
5446
5416
  const vdev = entry;
5447
5417
  const nested = leafDevices(vdev.children);
@@ -5454,18 +5424,18 @@ var attributesOf10 = (live, props) => ({
5454
5424
  node: props.node,
5455
5425
  state: text(live.state, "unknown")
5456
5426
  });
5457
- var readPoolOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, nodes10.getNodeDiskZfs({ name: props.name, node: props.node }))).pipe(Effect70.map((live) => {
5427
+ var readPoolOrFail = (props) => readOrUnreadable(runPve(props.target, "read", false, nodes10.getNodeDiskZfs({ name: props.name, node: props.node }))).pipe(Effect69.map((live) => {
5458
5428
  if (live === UNREADABLE)
5459
5429
  return UNREADABLE;
5460
5430
  return text(live.name) === "" ? undefined : attributesOf10(live, props);
5461
5431
  }));
5462
- var readPool = (props) => readPoolOrFail(props).pipe(Effect70.orElseSucceed(() => {
5432
+ var readPool = (props) => readPoolOrFail(props).pipe(Effect69.orElseSucceed(() => {
5463
5433
  return;
5464
5434
  }));
5465
5435
  var dropUnreadable8 = (live) => live === UNREADABLE ? undefined : live;
5466
5436
 
5467
5437
  // src/proxmox/zfs-pool-form.ts
5468
- import * as Effect71 from "effect/Effect";
5438
+ import * as Effect70 from "effect/Effect";
5469
5439
  import * as nodes11 from "@distilled.cloud/proxmox/nodes";
5470
5440
  var ZFS_POOL_CREATE = "pve:POST /nodes/{node}/disks/zfs";
5471
5441
  var zfsPoolCreateEndpoint = (props) => props.devices === undefined || props.raidlevel === undefined ? undefined : ZFS_POOL_CREATE;
@@ -5486,25 +5456,25 @@ var toDistilledCreate5 = (props) => {
5486
5456
  };
5487
5457
  };
5488
5458
  var SETTLE_ATTEMPTS = 30;
5489
- var createPool = (props, read4) => Effect71.gen(function* () {
5459
+ var createPool = (props, read4) => Effect70.gen(function* () {
5490
5460
  const existing = yield* read4(props);
5491
5461
  if (existing !== undefined)
5492
5462
  return existing;
5493
5463
  if (props.devices === undefined || props.raidlevel === undefined) {
5494
- return yield* Effect71.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."));
5464
+ return yield* Effect70.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."));
5495
5465
  }
5496
5466
  yield* guardForm(zfsPoolCreateEndpoint(props), asForm2(createForm12(props)), true);
5497
5467
  const upid = yield* runPve(props.target, "provision", true, nodes11.createNodeDiskZfs(toDistilledCreate5(props)));
5498
- const settle4 = (attempts) => Effect71.gen(function* () {
5468
+ const settle3 = (attempts) => Effect70.gen(function* () {
5499
5469
  const live = yield* read4(props);
5500
5470
  if (live !== undefined || attempts <= 0)
5501
5471
  return live;
5502
- yield* Effect71.sleep("2 seconds");
5503
- return yield* settle4(attempts - 1);
5472
+ yield* Effect70.sleep("2 seconds");
5473
+ return yield* settle3(attempts - 1);
5504
5474
  });
5505
- const after = yield* settle4(SETTLE_ATTEMPTS);
5475
+ const after = yield* settle3(SETTLE_ATTEMPTS);
5506
5476
  if (after === undefined) {
5507
- return yield* Effect71.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."));
5477
+ return yield* Effect70.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."));
5508
5478
  }
5509
5479
  return after;
5510
5480
  });
@@ -5514,12 +5484,12 @@ var destroyPool = (props) => runPve(props.target, "provision", true, nodes11.del
5514
5484
  var ProxmoxZfsPool = Resource35("Proxmox.ZfsPool", {
5515
5485
  defaultRemovalPolicy: "retain"
5516
5486
  });
5517
- var ProxmoxZfsPoolProvider = () => Provider35.effect(ProxmoxZfsPool, Effect72.succeed(ProxmoxZfsPool.Provider.of({
5518
- list: () => Effect72.succeed([]),
5519
- read: Effect72.fn(function* ({ olds, output }) {
5487
+ var ProxmoxZfsPoolProvider = () => Provider35.effect(ProxmoxZfsPool, Effect71.succeed(ProxmoxZfsPool.Provider.of({
5488
+ list: () => Effect71.succeed([]),
5489
+ read: Effect71.fn(function* ({ olds, output }) {
5520
5490
  return dropUnreadable8(yield* output === undefined ? readPool(olds) : readPoolOrFail(olds));
5521
5491
  }),
5522
- diff: Effect72.fn(function* ({ news, output }) {
5492
+ diff: Effect71.fn(function* ({ news, output }) {
5523
5493
  if (!isResolved19(news))
5524
5494
  return;
5525
5495
  yield* guardForm(zfsPoolCreateEndpoint(news), asForm2(createForm12(news)), output === undefined);
@@ -5536,10 +5506,10 @@ var ProxmoxZfsPoolProvider = () => Provider35.effect(ProxmoxZfsPool, Effect72.su
5536
5506
  }
5537
5507
  return { action: "noop" };
5538
5508
  }),
5539
- reconcile: Effect72.fn(function* ({ news }) {
5540
- return yield* createPool(news, (props) => readPool(props).pipe(Effect72.map(dropUnreadable8)));
5509
+ reconcile: Effect71.fn(function* ({ news }) {
5510
+ return yield* createPool(news, (props) => readPool(props).pipe(Effect71.map(dropUnreadable8)));
5541
5511
  }),
5542
- delete: Effect72.fn(function* ({ olds }) {
5512
+ delete: Effect71.fn(function* ({ olds }) {
5543
5513
  yield* destroyPool(olds);
5544
5514
  })
5545
5515
  })));
@@ -5619,5 +5589,5 @@ export {
5619
5589
  violations
5620
5590
  };
5621
5591
 
5622
- //# debugId=483DD0A45E397D2364756E2164756E21
5592
+ //# debugId=7C16E956F2A3150864756E2164756E21
5623
5593
  //# sourceMappingURL=index.js.map