@aopslabs/aops 0.3.26 → 0.3.27
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.
- package/agent-assets-release/agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/manifest.json +2 -2
- package/agent-assets-release/agent-assets/inventory.json +3 -3
- package/agent-assets-release/agent-assets-release.json +8 -8
- package/agent-assets-release/agent-assets-release.sigstore.json +26 -25
- package/dist/commands/community-server.js +78 -0
- package/dist/commands/global-update.js +115 -2
- package/dist/lib/agent-assets/native-fs.js +2 -2
- package/dist/lib/community-native-backup.js +2 -48
- package/dist/lib/pg-tool-location.js +112 -0
- package/native/manifest.json +1 -1
- package/native/qualifications/win32-x64.json +1 -1
- package/package.json +3 -3
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"name": "aops",
|
|
11
11
|
"optional": false,
|
|
12
12
|
"packageSha256": "bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb",
|
|
13
|
-
"version": "0.3.
|
|
14
|
-
"versionId": "community-core-0.3.
|
|
13
|
+
"version": "0.3.27",
|
|
14
|
+
"versionId": "community-core-0.3.27"
|
|
15
15
|
},
|
|
16
16
|
"gateway": {
|
|
17
17
|
"byteLength": 621,
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"kind": "aops-community-agent-assets-inventory-v1",
|
|
23
23
|
"schemaVersion": 1,
|
|
24
24
|
"source": {
|
|
25
|
-
"commit": "
|
|
25
|
+
"commit": "4787e531f33f55bfa3b8c4c28e8244a38abaeb6b",
|
|
26
26
|
"repository": "git+https://github.com/eeemzs/aops-platform",
|
|
27
27
|
"root": "apps/aops-cli/assets/agent-assets"
|
|
28
28
|
}
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"name": "aops",
|
|
12
12
|
"optional": false,
|
|
13
13
|
"packageSha256": "bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb",
|
|
14
|
-
"version": "0.3.
|
|
15
|
-
"versionId": "community-core-0.3.
|
|
14
|
+
"version": "0.3.27",
|
|
15
|
+
"versionId": "community-core-0.3.27"
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
{
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
{
|
|
119
119
|
"byteLength": 3811,
|
|
120
120
|
"ref": "agent-assets/core/bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb/manifest.json",
|
|
121
|
-
"sha256": "
|
|
121
|
+
"sha256": "0ff0b66ff505b3d6d8672e1d19aa8c5bfe041e3849319b752494d3b84cce283a"
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
124
|
"byteLength": 621,
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
{
|
|
129
129
|
"byteLength": 926,
|
|
130
130
|
"ref": "agent-assets/inventory.json",
|
|
131
|
-
"sha256": "
|
|
131
|
+
"sha256": "697dac2568b453e08a3f869911d73dce9690d24b8a5a4e23b5ede7107a1ea66c"
|
|
132
132
|
},
|
|
133
133
|
{
|
|
134
134
|
"byteLength": 281,
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
},
|
|
145
145
|
"inventory": {
|
|
146
146
|
"ref": "agent-assets/inventory.json",
|
|
147
|
-
"sha256": "
|
|
147
|
+
"sha256": "697dac2568b453e08a3f869911d73dce9690d24b8a5a4e23b5ede7107a1ea66c"
|
|
148
148
|
},
|
|
149
149
|
"kind": "aops-community-agent-assets-release-v1",
|
|
150
150
|
"projection": {
|
|
@@ -153,7 +153,7 @@
|
|
|
153
153
|
},
|
|
154
154
|
"root": "agent-assets",
|
|
155
155
|
"schemaVersion": 1,
|
|
156
|
-
"setSha256": "
|
|
156
|
+
"setSha256": "9d0dee44c2531e55e8023bb11a06333f52ced7651a37e4ac412c0cd214782b96"
|
|
157
157
|
},
|
|
158
158
|
"evidence": {
|
|
159
159
|
"signature": {
|
|
@@ -161,10 +161,10 @@
|
|
|
161
161
|
}
|
|
162
162
|
},
|
|
163
163
|
"kind": "aops-community-agent-assets-bundle-v1",
|
|
164
|
-
"releaseVersion": "0.3.
|
|
164
|
+
"releaseVersion": "0.3.27",
|
|
165
165
|
"schemaVersion": 1,
|
|
166
166
|
"source": {
|
|
167
|
-
"commit": "
|
|
167
|
+
"commit": "4787e531f33f55bfa3b8c4c28e8244a38abaeb6b",
|
|
168
168
|
"repository": "git+https://github.com/eeemzs/aops-platform",
|
|
169
169
|
"root": "apps/aops-cli/assets/agent-assets"
|
|
170
170
|
}
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
"x509CertificateChain": {
|
|
5
5
|
"certificates": [
|
|
6
6
|
{
|
|
7
|
-
"rawBytes": "
|
|
7
|
+
"rawBytes": "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"
|
|
8
8
|
}
|
|
9
9
|
]
|
|
10
10
|
},
|
|
11
11
|
"tlogEntries": [
|
|
12
12
|
{
|
|
13
|
-
"logIndex": "
|
|
13
|
+
"logIndex": "2553178141",
|
|
14
14
|
"logId": {
|
|
15
15
|
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
|
|
16
16
|
},
|
|
@@ -18,38 +18,39 @@
|
|
|
18
18
|
"kind": "hashedrekord",
|
|
19
19
|
"version": "0.0.1"
|
|
20
20
|
},
|
|
21
|
-
"integratedTime": "
|
|
21
|
+
"integratedTime": "1787342921",
|
|
22
22
|
"inclusionPromise": {
|
|
23
|
-
"signedEntryTimestamp": "
|
|
23
|
+
"signedEntryTimestamp": "MEYCIQCee5Wed+UEwne5gGRsns8vttd6Fh5iJakwaDqmcEfh4gIhAIZ0hCBDw4sf1VyXYwrvjPQanbci5oB1R5CM5pbrBKnj"
|
|
24
24
|
},
|
|
25
25
|
"inclusionProof": {
|
|
26
|
-
"logIndex": "
|
|
27
|
-
"rootHash": "+
|
|
28
|
-
"treeSize": "
|
|
26
|
+
"logIndex": "2431273879",
|
|
27
|
+
"rootHash": "2XyGUmnJWgDxbNiyLiB73MkMe5El87RlUbgYu+6MfTk=",
|
|
28
|
+
"treeSize": "2431273907",
|
|
29
29
|
"hashes": [
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
30
|
+
"8gMKN9aOLLWsjPT3PvQv7PoAq+VrnJ/Fpommxp6rqTg=",
|
|
31
|
+
"/Orbvjm03Qo3V9z1diSnCrnaRl6m40BTskvHzv8NF88=",
|
|
32
|
+
"Vk9RVBe9kNT781XMp8tS8DTpcko4XBl71cBukeVjkwc=",
|
|
33
|
+
"UQWQhSjdQxQDCKXudkGJLLE28GZjH+OidyImQaK9OC4=",
|
|
34
|
+
"P9GkuSWPSPRucx8JDkhB4JHOUV8FODtMU2a5X2mIw2w=",
|
|
35
|
+
"DJUcCbfFaQesa8LbApiHB67fApbOV08sij1IDbtVfMM=",
|
|
36
|
+
"PFfmG059BEJ/812MXXbY5/0vW7zhlYVFtiLTUc57TBU=",
|
|
37
|
+
"QjUheA/uRcU++iSf4WAbD/RjjviABR0rlAGnkxB8KsM=",
|
|
38
|
+
"q6H9/Vf7Sa04fwaiP/lzs2cJJI2u+CQoYKgJMS5GLjc=",
|
|
39
|
+
"qqxkJzAU2CVmos07YmHcElqrBOHc1wXsPxkbLjHV+7M=",
|
|
40
|
+
"6G3AK1+2CWs3TqAwJV6YH281UuodnSFa0qbj0Aaa20s=",
|
|
41
|
+
"NNUbUnztR4LkmVrpHik9kp1MkzVWL6ncjeKPTGf1Wtg=",
|
|
42
|
+
"yqyiMHfdl4qv1WrmtBYfbvpXnXVW3U2mKAE7FuRLIgc=",
|
|
43
|
+
"V26C/ZbgRB037k4IypmNXaS2AKEAq+mYdBpCYzUHZaI=",
|
|
44
|
+
"9573PZDNoVVnalVG+4BpJVrKEFneAwqHLpVdOEfbE0Y=",
|
|
44
45
|
"RhRQJE8gq9XjV+FJY/OHh6ZhCnS6INvqNxL9MyobX54=",
|
|
45
46
|
"SndbMKVtcTenAkwi2JBfGzD+mhexp1qJbRIY+A1JRIU=",
|
|
46
47
|
"xH/DCseLHr9eKoYT8qsORZK7zVdEGYWHuVtsVrD95wY="
|
|
47
48
|
],
|
|
48
49
|
"checkpoint": {
|
|
49
|
-
"envelope": "rekor.sigstore.dev - 1193050959916656506\
|
|
50
|
+
"envelope": "rekor.sigstore.dev - 1193050959916656506\n2431273907\n2XyGUmnJWgDxbNiyLiB73MkMe5El87RlUbgYu+6MfTk=\n\n— rekor.sigstore.dev wNI9ajBGAiEAmjN2WcuZd3AxnbMhkcQXlkFGQ/6nMrnUxZ7+ixDpIWoCIQCFIrhYFjo+4E305v29z4KMXtTu7q3yaEz05Yz12pk7FQ==\n"
|
|
50
51
|
}
|
|
51
52
|
},
|
|
52
|
-
"canonicalizedBody": "
|
|
53
|
+
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI5MWQwZmYxODIwNWQyOWY2MTY1NTQ4ZmVmYzAzMzBiNGI4NjVmMThjY2VkNzBkMzQ1OWU1NWU4Y2U4YmFjYzY3In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUURvbWVQWThXaU5lcGxPVjR1VGVuNlQ2M2xsRnpxemovWGhEUFQ2UnVZb293SWdUTGpzMnQ0eSsyelhUREY1blZ2SXVQclppSGN4UGxKUmVUalRCclVTMEY4PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVaGtha05EUW5aMVowRjNTVUpCWjBsVlEwNDNhMjQ0Wml0a1prZFdWVE5FUWpCdVUwVlBTWEZ3VG0xTmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFpkMDlFU1hoTmFrRjNUMFJSZUZkb1kwNU5hbGwzVDBSSmVFMXFRWGhQUkZGNFYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZPVUVnclpHdFFOeTlsTDJ4b2JsQmxUbW8wWlVzelpVRk5iR2d6WlcxUWVHMUpaV0VLU2padVNIaHBOVkZxVVhaRFVYaFJRbEZrYlM4NFlYSnFjVFZHZVRaR1RVSnphREpaVWpOWFpIcFNkVTFOZWpKbldFdFBRMEpvYjNkbloxbFhUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZUVnpaS0NsQnJiSEZGWVcxeWNURTBkV2hUT0U1WWRGZ3ZOVFpWZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDJSQldVUldVakJTUVZGSUwwSkhiM2RoU1ZwdFlVaFNNR05JVFRaTWVUbHVZVmhTYjJSWFNYVlpNamwwVERKV2JGcFhNVFpqZVRsb1lqTkNlZ3BNV0VKeldWaFNiV0l6U25STWVUVnVZVmhTYjJSWFNYWmtNamw1WVRKYWMySXpaSHBNTTA1d1dqSTBkR05JVm1saVIyeHFURmRHYmxwWE5UQk1WMFo2Q21NeVZqQmplVFUxWWxkNFFXTnRWbTFqZVRsdldsZEdhMk41T1hSWlYyeDFUVVJyUjBOcGMwZEJVVkZDWnpjNGQwRlJSVVZMTW1nd1pFaENlazlwT0hZS1pFYzVjbHBYTkhWWlYwNHdZVmM1ZFdONU5XNWhXRkp2WkZkS01XTXlWbmxaTWpsMVpFZFdkV1JETldwaU1qQjNTSGRaUzB0M1dVSkNRVWRFZG5wQlFncEJaMUZTWkRJNWVXRXlXbk5pTTJSbVdrZHNlbU5IUmpCWk1tZDNUbWRaUzB0M1dVSkNRVWRFZG5wQlFrRjNVVzlPUkdNMFRqSlZNVTE2Um0xTmVrNXRDazVVVm1sYWJVVjZXV3BvYWs1SFRYbFBSMVUwVFdwUk1GbFVUVFJaVjBwb1dsZEpNbGxxUVhoQ1oyOXlRbWRGUlVGWlR5OU5RVVZGUWtOT1ZHRlhaSFVLU1VkV05GbFhUakJKU0VJeFdXMTRjRmw1UWtKVU1VSlVTVWRHYmxwWE5UQkpSMFo2WXpKV01HTjZRV2xDWjI5eVFtZEZSVUZaVHk5TlFVVkdRa0pTYkFwYVYxWjBaVzVOZGxsWE9YZGplVEYzWWtkR01GcHRPWGxpVkVGa1FtZHZja0puUlVWQldVOHZUVUZGUjBKQk9YbGFWMXA2VERKb2JGbFhVbnBNTWpGb0NtRlhOSGRQZDFsTFMzZFpRa0pCUjBSMmVrRkNRMEZSZEVSRGRHOWtTRkozWTNwdmRrd3pVblpoTWxaMVRHMUdhbVJIYkhaaWJrMTFXakpzTUdGSVZta0taRmhPYkdOdFRuWmlibEpzWW01UmRWa3lPWFJOU0ZsSFEybHpSMEZSVVVKbk56aDNRVkZyUldGQmVHMWhTRkl3WTBoTk5reDVPVzVoV0ZKdlpGZEpkUXBaTWpsMFRESldiRnBYTVRaamVUbG9Zak5DZWt4WVFuTlpXRkp0WWpOS2RFeDVOVzVoV0ZKdlpGZEpkbVF5T1hsaE1scHpZak5rZWt3elRuQmFNalIwQ21OSVZtbGlSMnhxVEZkR2JscFhOVEJNVjBaNll6SldNR041TlRWaVYzaEJZMjFXYldONU9XOWFWMFpyWTNrNWRGbFhiSFZOUkdkSFEybHpSMEZSVVVJS1p6YzRkMEZSYjBWTFozZHZUa1JqTkU0eVZURk5la1p0VFhwT2JVNVVWbWxhYlVWNldXcG9hazVIVFhsUFIxVTBUV3BSTUZsVVRUUlpWMHBvV2xkSk1ncFpha0ZrUW1kdmNrSm5SVVZCV1U4dlRVRkZURUpCT0UxRVYyUndaRWRvTVZscE1XOWlNMDR3V2xkUmQwNTNXVXRMZDFsQ1FrRkhSSFo2UVVKRVFWRndDa1JEWkc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFphVjFac1lsaHdla3d5Um5aalNFMTBZMGQ0YUdSSFduWmpiVEIzVDBGWlMwdDNXVUlLUWtGSFJIWjZRVUpFVVZGeFJFTm5NRTU2WnpOYVZGVjZUVmRaZWsweVdURk9WMHB0V1ZST2FVOUhUVEJaZWtrMFdsUm5lVTVFVW1oTmVtaG9XVzFHYkFwWmFscHBUVUk0UjBOcGMwZEJVVkZDWnpjNGQwRlJORVZGVVhkUVkyMVdiV041T1c5YVYwWnJZM2s1ZEZsWGJIVk5RbTlIUTJselIwRlJVVUpuTnpoM0NrRlJPRVZFUVhkTFRWUk5lRTVxU1RGT1ZFRjVUbXBCY0VKbmIzSkNaMFZGUVZsUEwwMUJSVkZDUW5OTlIxZG9NR1JJUW5wUGFUaDJXakpzTUdGSVZta0tURzFPZG1KVE9XeGFWMVowWlc1TmQwZFJXVXRMZDFsQ1FrRkhSSFo2UVVKRlVWRk1SRUZyZUUxRWEzcE5WRUV6VG5wUmQyUm5XVXRMZDFsQ1FrRkhSQXAyZWtGQ1JXZFNiMFJIV205a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFphVjFac1lsaHdla3d5Um5aalNFMTBZMGQ0YUdSSFduWmpiVEIyQ2t4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbU15Ykc1aWFURjNaRmRLYzJGWFRYUlpWMlJzWW01UmRGbFlUbnBhV0ZKNlRHNXNkR0pGUW5rS1dsZGFla3d5YUd4WlYxSjZUREl4YUdGWE5IZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1JYZFJjVVJEWnpCT2VtY3pXbFJWZWsxWFdYcE5NbGt4VGxkS2JRcFpWRTVwVDBkTk1GbDZTVFJhVkdkNVRrUlNhRTE2YUdoWmJVWnNXV3BhYVUxRFJVZERhWE5IUVZGUlFtYzNPSGRCVWxGRlJYZDNVbVF5T1hsaE1scHpDbUl6WkdaYVIyeDZZMGRHTUZreVozZFhkMWxMUzNkWlFrSkJSMFIyZWtGQ1JsRlNUa1JGZEc5a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFlLV2xkV2JHSlljSHBNTWtaMlkwaE5kR05IZUdoa1IxcDJZMjB3ZGxsWFRqQmhWemwxWTNrNWVXUlhOWHBNZWsxNVRsUkplRTlVWXpOTmVtZDZUREpHTUFwa1IxWjBZMGhTZWt4NlJYZEdkMWxMUzNkWlFrSkJSMFIyZWtGQ1JtZFJTa1JCWkhkamJXd3lXVmhTYkUxR1NVZERhWE5IUVZGUlFtYzNPSGRCVW1kRkNsSkJlRU5qYlZaM1lucHdiRnBYVm5SbGJrNUJUVlJCTlUxNlJYZE9lbU13VERKR2RtTklUWFJqUjNob1pFZGFkbU50TVVGTlZFMTRUbXBKTVU1VVFYa0tUbXB3ZVZwWFdUWmpiVlp0WTNrNWIxcFhSbXRqZVRsMFdWZHNkVTFKUjB4Q1oyOXlRbWRGUlVGa1dqVkJaMUZEUWtnd1JXVjNRalZCU0dOQk0xUXdkd3BoYzJKSVJWUktha2RTTkdOdFYyTXpRWEZLUzFoeWFtVlFTek12YURSd2VXZERPSEEzYnpSQlFVRkhaMHBtUTJWblVVRkJRa0ZOUVZORVFrZEJhVVZCQ21zNE1ESnpRbWRwUkU1VVQyUnRRWFpQZW1NMVlVc3lNWFpZZFdnNFZFZENkbEp5VWtkdVJHaDJZemhEU1ZGREwyOXFZak5ETm5KUFUzTnRXVTkzV0VzS2FVZFZVbTlKTWxsSWVXeFNXRGxJWkhsa1pXNXllbVJPVEhwQlMwSm5aM0ZvYTJwUFVGRlJSRUYzVG5CQlJFSnRRV3BGUVd0Q1kyYzNNbVJOYnpsV1Z3cEJaM0YyZVV0SU5reHRTRTFJWlRaNGFVWkdORmgzVWpKV2FGRXdXbk53UjJSNFFWVTNkazU1VG5oRGIyRklOSGh2WldKcFFXcEZRU3RwUldoTFEzWnhDa0Z2YW1SM2NWUndZbkJwU3pKNmNVMUJkSFJTUVN0dVdHbENPR3hLWmxwTWFGZ3hZM1pxTTA5bGVFeEZhRE5YYUU1UVF6WnVVMkZKQ2kwdExTMHRSVTVFSUVORlVsUkpSa2xEUVZSRkxTMHRMUzBLIn19fX0="
|
|
53
54
|
}
|
|
54
55
|
],
|
|
55
56
|
"timestampVerificationData": {}
|
|
@@ -57,8 +58,8 @@
|
|
|
57
58
|
"messageSignature": {
|
|
58
59
|
"messageDigest": {
|
|
59
60
|
"algorithm": "SHA2_256",
|
|
60
|
-
"digest": "
|
|
61
|
+
"digest": "kdD/GCBdKfYWVUj+/AMwtLhl8YzO1w00WeVejOi6zGc="
|
|
61
62
|
},
|
|
62
|
-
"signature": "
|
|
63
|
+
"signature": "MEUCIQDomePY8WiNeplOV4uTen6T63llFzqzj/XhDPT6RuYoowIgTLjs2t4y+2zXTDF5nVvIuPrZiHcxPlJReTjTBrUS0F8="
|
|
63
64
|
}
|
|
64
65
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
1
2
|
import { existsSync, lstatSync, mkdirSync, readdirSync, realpathSync, rmSync, } from 'node:fs';
|
|
2
3
|
import os from 'node:os';
|
|
3
4
|
import path from 'node:path';
|
|
@@ -17,6 +18,8 @@ import { inspectCommunityDoctor } from './community-doctor.js';
|
|
|
17
18
|
import { buildCommunityInstanceContract, } from '../lib/community-instance-contract.js';
|
|
18
19
|
import { asCommunityDiagnosticError } from '../lib/community-diagnostic.js';
|
|
19
20
|
import { assertCommunityNativePathLayout, attestCommunityNativeExternalSnapshot, inspectCommunityNativeInstall, inspectCommunityNativeRuntime, loadExternalPostgresUrl, loadExternalServerAuthConfig, planCommunityNativeInstalledMigration, readCommunityNativeLogs, rollbackCommunityNativeApplication, resolveCommunityNativeInstalledNpmSourceRoot, resolveCommunityNativeLaunchMode, resolveCommunityNativePaths, setupCommunityNativeInstall, startCommunityNativeInstall, stopCommunityNativeInstall, } from '../lib/community-native-lifecycle.js';
|
|
21
|
+
import { inspectPgToolchain, locatePgTool, pgEnvironmentFromUrl } from '../lib/pg-tool-location.js';
|
|
22
|
+
import { readAopsServerEnvConfig } from '../utils/community-host-runtime.js';
|
|
20
23
|
import { inspectCommunityNativeApplicationRecoveryStatus } from '../lib/community-native-application-recovery.js';
|
|
21
24
|
import { inspectCommunityNativeDatabaseRecoveryStatus, restoreCommunityNativeDatabaseForUpdate, } from '../lib/community-native-database-recovery.js';
|
|
22
25
|
import { inspectCommunityNativePostgres, removeCommunityNativePostgresContainerForReset, removeCommunityNativeManagedPostgres, } from '../lib/community-native-postgres.js';
|
|
@@ -265,6 +268,78 @@ function journalPathsForMode(options, runtimeMode) {
|
|
|
265
268
|
function inspectFrom(options) {
|
|
266
269
|
return inspectCommunityInstall(installSelection(options));
|
|
267
270
|
}
|
|
271
|
+
const BACKUP_READINESS_CONTRACT = 'aops.backup-readiness/v1';
|
|
272
|
+
function computeCommunityBackupReadiness(options) {
|
|
273
|
+
const envelope = (body) => ({
|
|
274
|
+
schemaVersion: 1,
|
|
275
|
+
contract: BACKUP_READINESS_CONTRACT,
|
|
276
|
+
...body,
|
|
277
|
+
});
|
|
278
|
+
const native = inspectNativeFrom(options);
|
|
279
|
+
const state = native.status === 'installed' ? native.state : undefined;
|
|
280
|
+
if (!state) {
|
|
281
|
+
const dialect = readAopsServerEnvConfig().repoDialect;
|
|
282
|
+
if (dialect === 'sqlite')
|
|
283
|
+
return envelope({ provider: 'no-host-backup', ready: true });
|
|
284
|
+
return envelope({
|
|
285
|
+
provider: 'unknown',
|
|
286
|
+
ready: false,
|
|
287
|
+
cause: `community_backup_readiness_state_unavailable:${native.status}`,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
const postgres = state.postgres;
|
|
291
|
+
if (postgres.mode === 'container')
|
|
292
|
+
return envelope({ provider: 'managed-container', ready: true });
|
|
293
|
+
if (postgres.mode !== 'external' || !postgres.configRef || !postgres.tlsPolicy) {
|
|
294
|
+
return envelope({
|
|
295
|
+
provider: 'unknown',
|
|
296
|
+
ready: false,
|
|
297
|
+
cause: 'community_backup_readiness_postgres_state_incomplete',
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
let serverMajor;
|
|
301
|
+
try {
|
|
302
|
+
const url = loadExternalPostgresUrl(postgres.configRef, postgres.tlsPolicy);
|
|
303
|
+
const psql = locatePgTool('psql');
|
|
304
|
+
if (!psql) {
|
|
305
|
+
return envelope({ provider: 'unknown', ready: false, cause: 'community_backup_readiness_psql_missing' });
|
|
306
|
+
}
|
|
307
|
+
const probe = spawnSync(psql, ['--tuples-only', '--no-align', '--command', 'SHOW server_version_num'], {
|
|
308
|
+
encoding: 'utf8',
|
|
309
|
+
env: { ...process.env, ...pgEnvironmentFromUrl(String(url)) },
|
|
310
|
+
});
|
|
311
|
+
if (probe.error || probe.status !== 0) {
|
|
312
|
+
return envelope({ provider: 'unknown', ready: false, cause: 'community_backup_readiness_server_unreachable' });
|
|
313
|
+
}
|
|
314
|
+
const reported = Number(`${probe.stdout ?? ''}`.trim());
|
|
315
|
+
if (!Number.isFinite(reported) || reported <= 0) {
|
|
316
|
+
return envelope({ provider: 'unknown', ready: false, cause: 'community_backup_readiness_server_version_unreadable' });
|
|
317
|
+
}
|
|
318
|
+
serverMajor = Math.floor(reported / 10_000);
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
321
|
+
return envelope({ provider: 'unknown', ready: false, cause: 'community_backup_readiness_postgres_config_unusable' });
|
|
322
|
+
}
|
|
323
|
+
const readiness = inspectPgToolchain({
|
|
324
|
+
serverMajor,
|
|
325
|
+
run: (command, args) => {
|
|
326
|
+
const result = spawnSync(command, args, { encoding: 'utf8' });
|
|
327
|
+
if (result.error || result.status !== 0)
|
|
328
|
+
throw new Error('community_backup_readiness_tool_failed');
|
|
329
|
+
return `${result.stdout ?? ''}`;
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
return envelope({
|
|
333
|
+
provider: 'host-tools',
|
|
334
|
+
ready: readiness.ready,
|
|
335
|
+
serverMajor: readiness.requiredMajor,
|
|
336
|
+
tools: readiness.tools.map((evidence) => ({ tool: evidence.tool, major: evidence.major ?? null })),
|
|
337
|
+
...(readiness.cause ? { cause: readiness.cause } : {}),
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
function runCommunityServerBackupReadiness(options) {
|
|
341
|
+
writeResult(computeCommunityBackupReadiness(options), true, options);
|
|
342
|
+
}
|
|
268
343
|
function inspectNativeFrom(options) {
|
|
269
344
|
return inspectCommunityNativeInstall(installSelection(options));
|
|
270
345
|
}
|
|
@@ -2195,6 +2270,9 @@ export function makeCommunityServerCommand(identity = {}) {
|
|
|
2195
2270
|
.action((options) => runCommunityServerRestart(options, dependencies));
|
|
2196
2271
|
common(command.command('status').description('Show install and runtime status')).action(runCommunityServerStatus);
|
|
2197
2272
|
common(command.command('health').description('Check the installed server health without mutation')).action(runCommunityServerHealth);
|
|
2273
|
+
common(command.command('backup-readiness')
|
|
2274
|
+
.description('Report whether this host can take the backup an update depends on, without mutation'))
|
|
2275
|
+
.action(runCommunityServerBackupReadiness);
|
|
2198
2276
|
common(command.command('migration-plan').description('Read the exact pending native database migration plan without mutation'))
|
|
2199
2277
|
.action((options) => runCommunityServerMigrationPlan(options, dependencies));
|
|
2200
2278
|
common(command.command('attest-external-snapshot').description('Optionally record an operator-owned external PostgreSQL snapshot for one risky migration plan'))
|
|
@@ -358,12 +358,118 @@ function defaultUpdateRoot(configRoot) {
|
|
|
358
358
|
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
359
359
|
return plainDirectory(root, 'AOPS config root');
|
|
360
360
|
}
|
|
361
|
-
|
|
361
|
+
function assertKnownDependencies(provided, known, label) {
|
|
362
|
+
for (const key of Object.keys(provided)) {
|
|
363
|
+
assert.ok(known.includes(key), `${label} received an unknown dependency: ${key}`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
const BACKUP_READINESS_CONTRACT = 'aops.backup-readiness/v1';
|
|
367
|
+
function resolveBackupProvider(run, entrypoint) {
|
|
368
|
+
let document;
|
|
369
|
+
try {
|
|
370
|
+
document = parseJson(run(process.execPath, [entrypoint, 'server', 'backup-readiness', '--json']), 'backup_readiness');
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
return { kind: 'unknown', reason: 'readiness_command_failed' };
|
|
374
|
+
}
|
|
375
|
+
if (document.contract !== BACKUP_READINESS_CONTRACT || document.schemaVersion !== 1) {
|
|
376
|
+
return { kind: 'unknown', reason: 'readiness_contract_unrecognised' };
|
|
377
|
+
}
|
|
378
|
+
const knownAnywhere = ['schemaVersion', 'contract', 'provider', 'ready', 'serverMajor', 'tools', 'cause'];
|
|
379
|
+
for (const key of Object.keys(document)) {
|
|
380
|
+
if (!knownAnywhere.includes(key))
|
|
381
|
+
return { kind: 'unknown', reason: 'readiness_document_unexpected_field' };
|
|
382
|
+
}
|
|
383
|
+
const exactKeys = (allowed) => {
|
|
384
|
+
const keys = Object.keys(document).sort();
|
|
385
|
+
return keys.length === allowed.length && allowed.slice().sort().every((key, index) => keys[index] === key);
|
|
386
|
+
};
|
|
387
|
+
const base = ['schemaVersion', 'contract', 'provider', 'ready'];
|
|
388
|
+
if (document.provider === 'managed-container' || document.provider === 'no-host-backup') {
|
|
389
|
+
if (!exactKeys(base) || document.ready !== true) {
|
|
390
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
391
|
+
}
|
|
392
|
+
return { kind: document.provider === 'managed-container' ? 'managed-container' : 'no-host-backup' };
|
|
393
|
+
}
|
|
394
|
+
if (document.provider === 'unknown') {
|
|
395
|
+
if (!exactKeys([...base, 'cause']) || document.ready !== false || typeof document.cause !== 'string' ||
|
|
396
|
+
document.cause.length === 0) {
|
|
397
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
398
|
+
}
|
|
399
|
+
return { kind: 'unknown', reason: `readiness_${document.cause}` };
|
|
400
|
+
}
|
|
401
|
+
if (document.provider !== 'host-tools') {
|
|
402
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
403
|
+
}
|
|
404
|
+
const serverMajor = document.serverMajor;
|
|
405
|
+
if (!Number.isSafeInteger(serverMajor) || Number(serverMajor) <= 0) {
|
|
406
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
407
|
+
}
|
|
408
|
+
const tools = document.tools;
|
|
409
|
+
if (!Array.isArray(tools) || tools.length !== 2) {
|
|
410
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
411
|
+
}
|
|
412
|
+
const evidence = tools.map((entry) => entry);
|
|
413
|
+
const named = evidence.map((entry) => String(entry.tool)).sort();
|
|
414
|
+
if (named[0] !== 'pg_dump' || named[1] !== 'pg_restore') {
|
|
415
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
416
|
+
}
|
|
417
|
+
for (const entry of evidence) {
|
|
418
|
+
if (Object.keys(entry).sort().join(',') !== 'major,tool') {
|
|
419
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
const detail = `required_major_${String(serverMajor)} ` +
|
|
423
|
+
evidence.map((entry) => `${String(entry.tool)}=${entry.major === null ? 'missing' : String(entry.major)}`).join(' ');
|
|
424
|
+
if (document.ready === true) {
|
|
425
|
+
if (!exactKeys([...base, 'serverMajor', 'tools'])) {
|
|
426
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
427
|
+
}
|
|
428
|
+
for (const entry of evidence) {
|
|
429
|
+
if (!Number.isSafeInteger(entry.major) || Number(entry.major) < Number(serverMajor)) {
|
|
430
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return { kind: 'host-tools', ready: true, detail };
|
|
434
|
+
}
|
|
435
|
+
if (document.ready !== false || !exactKeys([...base, 'serverMajor', 'tools', 'cause']) ||
|
|
436
|
+
typeof document.cause !== 'string' || document.cause.length === 0) {
|
|
437
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
438
|
+
}
|
|
439
|
+
for (const entry of evidence) {
|
|
440
|
+
if (entry.major !== null && !Number.isSafeInteger(entry.major)) {
|
|
441
|
+
return { kind: 'unknown', reason: 'readiness_document_variant_invalid' };
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return { kind: 'host-tools', ready: false, cause: document.cause, detail };
|
|
445
|
+
}
|
|
446
|
+
function assertBackupToolchainReady(resolveProvider) {
|
|
447
|
+
const provider = resolveProvider();
|
|
448
|
+
if (provider.kind === 'managed-container' || provider.kind === 'no-host-backup')
|
|
449
|
+
return false;
|
|
450
|
+
if (provider.kind === 'unknown') {
|
|
451
|
+
throw new Error(`community_pg_toolchain_server_major_unknown:${provider.reason}; the server host must let this ` +
|
|
452
|
+
'command report whether it can back up its own database before an update that dumps it can begin');
|
|
453
|
+
}
|
|
454
|
+
if (!provider.ready) {
|
|
455
|
+
throw new Error(`${provider.cause ?? 'community_pg_toolchain_not_ready'}; the server host must provide PostgreSQL ` +
|
|
456
|
+
`client tools able to serve its own database before this server can be updated (${provider.detail})`);
|
|
457
|
+
}
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
function serverApplicationUpdateRequired(priorServer, targetServer) {
|
|
461
|
+
return priorServer !== targetServer;
|
|
462
|
+
}
|
|
463
|
+
export function prepareGlobalUpdate(options = {}, run = defaultRunner, dependencies = {}) {
|
|
464
|
+
assertKnownDependencies(dependencies, ['resolveBackupProvider'], 'prepareGlobalUpdate');
|
|
362
465
|
const check = inspectGlobalUpdate(run);
|
|
363
466
|
assert.equal(check.updateAvailable, true, 'aops_global_update_not_available');
|
|
364
467
|
const installed = inspectGlobalInstall(run);
|
|
365
468
|
const services = serviceSnapshot(run, installed.cliPath);
|
|
366
469
|
assertHealthyServices(services);
|
|
470
|
+
if (serverApplicationUpdateRequired(installed.packages.server, check.available.server)) {
|
|
471
|
+
assertBackupToolchainReady(dependencies.resolveBackupProvider ?? (() => resolveBackupProvider(run, installed.cliPath)));
|
|
472
|
+
}
|
|
367
473
|
const configRoot = defaultUpdateRoot(options.configRoot);
|
|
368
474
|
const updatesRoot = path.join(configRoot, 'global-updates');
|
|
369
475
|
mkdirSync(updatesRoot, { recursive: true, mode: 0o700 });
|
|
@@ -1108,6 +1214,7 @@ export async function recoverGlobalUpdate(options, run = defaultRunner, executio
|
|
|
1108
1214
|
}
|
|
1109
1215
|
}
|
|
1110
1216
|
export async function applyGlobalUpdate(options, run = defaultRunner, execution = defaultExecutionDependencies) {
|
|
1217
|
+
assertKnownDependencies(execution, ['fetch', 'sleep', 'now', 'resolveBackupProvider'], 'applyGlobalUpdate');
|
|
1111
1218
|
const plan = readGlobalUpdatePlan(options.plan);
|
|
1112
1219
|
assert.equal(options.confirm, plan.planId, 'global update confirmation does not match the exact plan');
|
|
1113
1220
|
assert.equal(existsSync(path.join(plan.operationRoot, RESULT_FILE)), false, 'global_update_plan_already_terminal');
|
|
@@ -1117,6 +1224,12 @@ export async function applyGlobalUpdate(options, run = defaultRunner, execution
|
|
|
1117
1224
|
assert.equal(current.globalPrefix, plan.globalPrefix, 'global npm prefix changed after update planning');
|
|
1118
1225
|
assertHealthyServices(serviceSnapshot(run, current.cliPath));
|
|
1119
1226
|
const events = new GlobalUpdateEventLog(execution.now ?? (() => new Date()));
|
|
1227
|
+
if (serverApplicationUpdateRequired(plan.prior.packages.server, plan.target.packages.server)) {
|
|
1228
|
+
const candidateEntrypoint = path.join(plan.operationRoot, 'executor', 'node_modules', '@aopslabs', 'aops', 'dist', 'main.js');
|
|
1229
|
+
if (assertBackupToolchainReady(execution.resolveBackupProvider ?? (() => resolveBackupProvider(run, candidateEntrypoint)))) {
|
|
1230
|
+
events.push('verified:backup-toolchain');
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1120
1233
|
let applicationUpdateId = null;
|
|
1121
1234
|
let applicationUpdateAttempted = false;
|
|
1122
1235
|
let failedStage = 'stop-cockpit';
|
|
@@ -1133,7 +1246,7 @@ export async function applyGlobalUpdate(options, run = defaultRunner, execution
|
|
|
1133
1246
|
const updated = inspectGlobalInstall(run);
|
|
1134
1247
|
assert.deepEqual(updated.packages, plan.target.packages, 'installed candidate closure is not exact');
|
|
1135
1248
|
assert.deepEqual(updated.topology, plan.target.topology, 'installed candidate topology is not canonical');
|
|
1136
|
-
if (plan.prior.packages.server
|
|
1249
|
+
if (!serverApplicationUpdateRequired(plan.prior.packages.server, plan.target.packages.server)) {
|
|
1137
1250
|
failedStage = 'start-unchanged-server';
|
|
1138
1251
|
startService(run, updated.cliPath, 'server');
|
|
1139
1252
|
events.push('started:server-unchanged');
|
|
@@ -543,9 +543,9 @@ function defaultNativeRoot() {
|
|
|
543
543
|
return moduleDirectory.endsWith(`${path.sep}dist`) ? bundled : compiledOrSource;
|
|
544
544
|
}
|
|
545
545
|
function injectedNativeManifestSha256() {
|
|
546
|
-
return typeof "
|
|
546
|
+
return typeof "7f232c413710060253a8f61f7b9b977106d8f71df4fadb408f77b12bbdf2bc29" === 'undefined'
|
|
547
547
|
? undefined
|
|
548
|
-
: "
|
|
548
|
+
: "7f232c413710060253a8f61f7b9b977106d8f71df4fadb408f77b12bbdf2bc29";
|
|
549
549
|
}
|
|
550
550
|
function sha256(bytes) {
|
|
551
551
|
return createHash('sha256').update(bytes).digest('hex');
|
|
@@ -3,6 +3,8 @@ import { closeSync, constants, existsSync, lstatSync, mkdirSync, openSync, readF
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
import { assertBackupUnchanged, hashHeldFile, openBackupForVerify } from './community-migration-snapshot.js';
|
|
6
|
+
import { pgEnvironmentFromUrl, resolvePgTool } from './pg-tool-location.js';
|
|
7
|
+
export { pgEnvironmentFromUrl, resolvePgTool };
|
|
6
8
|
export async function runNativePgProcess(params) {
|
|
7
9
|
return await new Promise((resolve, reject) => {
|
|
8
10
|
const child = spawn(params.tool, params.args, {
|
|
@@ -18,54 +20,6 @@ export async function runNativePgProcess(params) {
|
|
|
18
20
|
child.on('close', (exitCode, signal) => resolve({ exitCode, signal }));
|
|
19
21
|
});
|
|
20
22
|
}
|
|
21
|
-
export function pgEnvironmentFromUrl(repoUrl) {
|
|
22
|
-
let parsed;
|
|
23
|
-
try {
|
|
24
|
-
parsed = new URL(repoUrl);
|
|
25
|
-
}
|
|
26
|
-
catch {
|
|
27
|
-
throw new Error('community_native_backup_repo_url_invalid');
|
|
28
|
-
}
|
|
29
|
-
if (parsed.protocol !== 'postgres:' && parsed.protocol !== 'postgresql:') {
|
|
30
|
-
throw new Error('community_native_backup_repo_url_invalid');
|
|
31
|
-
}
|
|
32
|
-
const database = decodeURIComponent(parsed.pathname.replace(/^\//, ''));
|
|
33
|
-
if (!database)
|
|
34
|
-
throw new Error('community_native_backup_repo_url_invalid');
|
|
35
|
-
const env = {
|
|
36
|
-
PGHOST: parsed.hostname,
|
|
37
|
-
PGDATABASE: database,
|
|
38
|
-
};
|
|
39
|
-
if (parsed.port)
|
|
40
|
-
env.PGPORT = parsed.port;
|
|
41
|
-
if (parsed.username)
|
|
42
|
-
env.PGUSER = decodeURIComponent(parsed.username);
|
|
43
|
-
if (parsed.password)
|
|
44
|
-
env.PGPASSWORD = decodeURIComponent(parsed.password);
|
|
45
|
-
const sslmode = parsed.searchParams.get('sslmode');
|
|
46
|
-
if (sslmode)
|
|
47
|
-
env.PGSSLMODE = sslmode;
|
|
48
|
-
return env;
|
|
49
|
-
}
|
|
50
|
-
export function resolvePgTool(tool, options = {}) {
|
|
51
|
-
const exists = options.exists ?? existsSync;
|
|
52
|
-
const executable = process.platform === 'win32' ? `${tool}.exe` : tool;
|
|
53
|
-
if (options.explicit)
|
|
54
|
-
return options.explicit;
|
|
55
|
-
if (options.binDir)
|
|
56
|
-
return path.join(options.binDir, executable);
|
|
57
|
-
const candidates = process.platform === 'darwin'
|
|
58
|
-
? ['/Applications/pgAdmin 4.app/Contents/SharedSupport', '/opt/homebrew/bin', '/usr/local/bin']
|
|
59
|
-
: process.platform === 'win32'
|
|
60
|
-
? ['C:\\Program Files\\PostgreSQL\\17\\bin', 'C:\\Program Files\\PostgreSQL\\16\\bin']
|
|
61
|
-
: ['/usr/bin', '/usr/local/bin'];
|
|
62
|
-
for (const dir of candidates) {
|
|
63
|
-
const candidate = path.join(dir, executable);
|
|
64
|
-
if (exists(candidate))
|
|
65
|
-
return candidate;
|
|
66
|
-
}
|
|
67
|
-
return executable;
|
|
68
|
-
}
|
|
69
23
|
function assertSafeBackupRoot(backupRoot) {
|
|
70
24
|
mkdirSync(backupRoot, { recursive: true, mode: 0o700 });
|
|
71
25
|
const stats = lstatSync(backupRoot, { bigint: true });
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export function resolvePgTool(tool, options = {}) {
|
|
4
|
+
const exists = options.exists ?? existsSync;
|
|
5
|
+
const executable = process.platform === 'win32' ? `${tool}.exe` : tool;
|
|
6
|
+
if (options.explicit)
|
|
7
|
+
return options.explicit;
|
|
8
|
+
if (options.binDir)
|
|
9
|
+
return path.join(options.binDir, executable);
|
|
10
|
+
const candidates = process.platform === 'darwin'
|
|
11
|
+
? ['/Applications/pgAdmin 4.app/Contents/SharedSupport', '/opt/homebrew/bin', '/usr/local/bin']
|
|
12
|
+
: process.platform === 'win32'
|
|
13
|
+
? ['C:\\Program Files\\PostgreSQL\\17\\bin', 'C:\\Program Files\\PostgreSQL\\16\\bin']
|
|
14
|
+
: ['/usr/bin', '/usr/local/bin'];
|
|
15
|
+
for (const dir of candidates) {
|
|
16
|
+
const candidate = path.join(dir, executable);
|
|
17
|
+
if (exists(candidate))
|
|
18
|
+
return candidate;
|
|
19
|
+
}
|
|
20
|
+
return executable;
|
|
21
|
+
}
|
|
22
|
+
export function locatePgDump(env = process.env, exists = existsSync) {
|
|
23
|
+
return locatePgTool('pg_dump', env, exists);
|
|
24
|
+
}
|
|
25
|
+
export function locatePgTool(tool, env = process.env, exists = existsSync) {
|
|
26
|
+
const resolved = resolvePgTool(tool, { exists });
|
|
27
|
+
if (resolved.includes(path.sep))
|
|
28
|
+
return resolved;
|
|
29
|
+
const searchPath = (env.PATH ?? '').split(path.delimiter).filter((entry) => entry.length > 0);
|
|
30
|
+
for (const entry of searchPath) {
|
|
31
|
+
const candidate = path.join(entry, resolved);
|
|
32
|
+
if (exists(candidate))
|
|
33
|
+
return candidate;
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
export function pgEnvironmentFromUrl(repoUrl) {
|
|
38
|
+
let parsed;
|
|
39
|
+
try {
|
|
40
|
+
parsed = new URL(repoUrl);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
throw new Error('community_native_backup_repo_url_invalid');
|
|
44
|
+
}
|
|
45
|
+
if (parsed.protocol !== 'postgres:' && parsed.protocol !== 'postgresql:') {
|
|
46
|
+
throw new Error('community_native_backup_repo_url_invalid');
|
|
47
|
+
}
|
|
48
|
+
const database = decodeURIComponent(parsed.pathname.replace(/^\//, ''));
|
|
49
|
+
if (!database)
|
|
50
|
+
throw new Error('community_native_backup_repo_url_invalid');
|
|
51
|
+
const env = {
|
|
52
|
+
PGHOST: parsed.hostname,
|
|
53
|
+
PGDATABASE: database,
|
|
54
|
+
};
|
|
55
|
+
if (parsed.port)
|
|
56
|
+
env.PGPORT = parsed.port;
|
|
57
|
+
if (parsed.username)
|
|
58
|
+
env.PGUSER = decodeURIComponent(parsed.username);
|
|
59
|
+
if (parsed.password)
|
|
60
|
+
env.PGPASSWORD = decodeURIComponent(parsed.password);
|
|
61
|
+
const sslmode = parsed.searchParams.get('sslmode');
|
|
62
|
+
if (sslmode)
|
|
63
|
+
env.PGSSLMODE = sslmode;
|
|
64
|
+
return env;
|
|
65
|
+
}
|
|
66
|
+
export function parsePgToolMajor(reported) {
|
|
67
|
+
const match = /(\d+)(?:\.\d+)*\s*$/.exec(reported.trim());
|
|
68
|
+
if (!match)
|
|
69
|
+
return undefined;
|
|
70
|
+
const major = Number(match[1]);
|
|
71
|
+
return Number.isInteger(major) ? major : undefined;
|
|
72
|
+
}
|
|
73
|
+
export function inspectPgToolchain(options) {
|
|
74
|
+
const requiredMajor = options.serverMajor;
|
|
75
|
+
const tools = [];
|
|
76
|
+
let cause;
|
|
77
|
+
for (const tool of ['pg_dump', 'pg_restore']) {
|
|
78
|
+
const located = locatePgTool(tool, options.env ?? process.env, options.exists ?? existsSync);
|
|
79
|
+
if (!located) {
|
|
80
|
+
tools.push({ tool });
|
|
81
|
+
cause ??= `community_pg_toolchain_missing:${tool}:required_major_${requiredMajor}`;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
let major;
|
|
85
|
+
try {
|
|
86
|
+
major = parsePgToolMajor(options.run(located, ['--version']));
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
major = undefined;
|
|
90
|
+
}
|
|
91
|
+
tools.push({ tool, path: located, major });
|
|
92
|
+
if (major === undefined) {
|
|
93
|
+
cause ??= `community_pg_toolchain_unusable:${tool}:required_major_${requiredMajor}`;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (major < requiredMajor) {
|
|
97
|
+
cause ??= `community_pg_toolchain_major_too_old:${tool}:found_${major}:required_${requiredMajor}`;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { requiredMajor, tools, ready: cause === undefined, cause };
|
|
101
|
+
}
|
|
102
|
+
export function assertPgToolchainReady(options) {
|
|
103
|
+
const readiness = inspectPgToolchain(options);
|
|
104
|
+
if (readiness.ready)
|
|
105
|
+
return readiness;
|
|
106
|
+
const detail = readiness.tools
|
|
107
|
+
.map((evidence) => `${evidence.tool}=${evidence.major ?? (evidence.path ? 'unusable' : 'missing')}`)
|
|
108
|
+
.join(' ');
|
|
109
|
+
throw new Error(`${readiness.cause}; the server host must provide PostgreSQL client tools of major ` +
|
|
110
|
+
`${readiness.requiredMajor} or newer -- the major this host's own database reports -- ` +
|
|
111
|
+
`before this server can be updated (${detail})`);
|
|
112
|
+
}
|
package/native/manifest.json
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"capabilityClass": "windows-ntfs-crash-recoverable-v1",
|
|
43
43
|
"qualification": {
|
|
44
44
|
"relativePath": "qualifications/win32-x64.json",
|
|
45
|
-
"sha256": "
|
|
45
|
+
"sha256": "e720ca34d30b63e5899f93ad9a4eda28a9c11b90c916ea8051a07d26e9a85652"
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"filesystem": "NTFS",
|
|
8
8
|
"primitiveProfile": "windows-createfile-flush-movefileex-v1",
|
|
9
9
|
"capabilityClass": "windows-ntfs-crash-recoverable-v1",
|
|
10
|
-
"evidenceSha256": "
|
|
10
|
+
"evidenceSha256": "caad48ff4b78a048304397f223163ce3504734cf8b36371d5c064b5d886aecef",
|
|
11
11
|
"crashInjectionPoints": [
|
|
12
12
|
"authority-history",
|
|
13
13
|
"authority-current",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aopslabs/aops",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.27",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AOPS CLI and terminal setup application.",
|
|
6
6
|
"aopsDockerServerVersion": "0.2.17",
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@aopslabs/aops-agent-runtime": "0.1.0",
|
|
77
|
-
"@aopslabs/aops-server": "0.2.
|
|
77
|
+
"@aopslabs/aops-server": "0.2.21",
|
|
78
78
|
"@aopslabs/artifact-trust-contracts": "0.3.1",
|
|
79
79
|
"@aopslabs/cli-kit": "0.1.0",
|
|
80
80
|
"@aopslabs/aops-host-registration": "0.2.2",
|
|
81
|
-
"@aopslabs/aops-pg-bootstrap": "0.2.
|
|
81
|
+
"@aopslabs/aops-pg-bootstrap": "0.2.6",
|
|
82
82
|
"@aopslabs/aops-runtime-config": "0.2.2",
|
|
83
83
|
"@sigstore/bundle": "4.0.0",
|
|
84
84
|
"@sigstore/protobuf-specs": "0.5.1",
|