@synopackageland/cli 0.3.1 → 0.3.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.
- package/dist/attestation/app-package.js +8 -1
- package/dist/attestation/platform-service.d.ts +70 -0
- package/dist/attestation/platform-service.js +250 -0
- package/dist/bin.js +0 -0
- package/dist/build-spk/generator.js +202 -10
- package/dist/build-spk/resource-worker.d.ts +14 -0
- package/dist/build-spk/resource-worker.js +140 -0
- package/dist/cli.js +69 -10
- package/dist/compose/analyze.d.ts +41 -1
- package/dist/compose/analyze.js +458 -18
- package/dist/contract/load.d.ts +1 -0
- package/dist/contract/load.js +1 -1
- package/dist/contract/posix-all-shares.d.ts +16 -0
- package/dist/contract/posix-all-shares.js +63 -0
- package/dist/contract/schema-validate.js +26 -1
- package/dist/contract/validate.js +57 -0
- package/dist/contract/web-launch.d.ts +6 -0
- package/dist/contract/web-launch.js +25 -0
- package/dist/deploy/deploy.d.ts +1 -0
- package/dist/deploy/deploy.js +37 -2
- package/dist/deploy/homes-values.d.ts +19 -0
- package/dist/deploy/homes-values.js +29 -0
- package/dist/deploy/param-values.d.ts +21 -0
- package/dist/deploy/param-values.js +51 -0
- package/dist/deploy/spk-version.d.ts +5 -0
- package/dist/deploy/spk-version.js +50 -18
- package/dist/doctor.d.ts +22 -0
- package/dist/doctor.js +594 -0
- package/dist/error-collector.d.ts +2 -0
- package/dist/error-collector.js +46 -0
- package/dist/error-registry.d.ts +7 -0
- package/dist/error-registry.js +827 -0
- package/dist/host/broker-upgrade-preflight.d.ts +61 -0
- package/dist/host/broker-upgrade-preflight.js +156 -0
- package/dist/host/catalog-install.d.ts +12 -0
- package/dist/host/catalog-install.js +83 -17
- package/dist/host/credentials.js +35 -5
- package/dist/host/dsm-client.d.ts +12 -0
- package/dist/host/dsm-client.js +56 -1
- package/dist/host/dsm-compound.d.ts +37 -0
- package/dist/host/dsm-compound.js +120 -0
- package/dist/host/fake-nas.d.ts +1 -0
- package/dist/host/fake-nas.js +3 -0
- package/dist/host/types.d.ts +4 -0
- package/dist/publish/curated-release.js +3 -3
- package/dist/publish/platform-service-release.d.ts +60 -0
- package/dist/publish/platform-service-release.js +333 -0
- package/dist/publish/preflight.js +14 -1
- package/dist/release-bin.js +5 -1
- package/dist/templates/hello-files/compose.yaml +2 -0
- package/dist/templates/hello-web/compose.yaml +14 -3
- package/dist/templates/hello-web/synology-app.yaml +1 -1
- package/dist/templates/hello-web-page/compose.yaml +14 -3
- package/dist/templates/hello-web-page/synology-app.yaml +1 -1
- package/dist/test-host.d.ts +2 -0
- package/dist/test-host.js +15 -2
- package/dist/types.d.ts +1 -1
- package/dist/validate.js +14 -3
- package/package.json +2 -2
- package/schema/doctor.schema.json +38 -0
- package/schema/synology-app.schema.json +1 -1
- package/skills/reference/create.md +19 -0
- package/skills/reference/diagnose.md +35 -2
- package/skills/reference/files.md +10 -0
- package/templates/hello-files/compose.yaml +2 -0
- package/templates/hello-web/compose.yaml +14 -3
- package/templates/hello-web/synology-app.yaml +1 -1
- package/templates/hello-web-page/compose.yaml +14 -3
- package/templates/hello-web-page/synology-app.yaml +1 -1
|
@@ -0,0 +1,827 @@
|
|
|
1
|
+
export const ERROR_REGISTRY = {
|
|
2
|
+
// --- Contract Validation ---
|
|
3
|
+
CONTRACT_SCHEMA_UNSUPPORTED: {
|
|
4
|
+
code: "CONTRACT_SCHEMA_UNSUPPORTED",
|
|
5
|
+
description: "synology-app.yaml 的 schema 版本不受支援。",
|
|
6
|
+
suggestion: "請將 synology-app.yaml 的 schema 欄位設為 1。",
|
|
7
|
+
},
|
|
8
|
+
CONTRACT_MISSING_FIELD: {
|
|
9
|
+
code: "CONTRACT_MISSING_FIELD",
|
|
10
|
+
description: "synology-app.yaml 缺少必填欄位。",
|
|
11
|
+
suggestion: "請在 synology-app.yaml 補上缺少的必填欄位(例如 package, version, displayname 等)。",
|
|
12
|
+
},
|
|
13
|
+
CONTRACT_SCHEMA_INVALID: {
|
|
14
|
+
code: "CONTRACT_SCHEMA_INVALID",
|
|
15
|
+
description: "synology-app.yaml 格式與 JSON Schema 規格不符。",
|
|
16
|
+
suggestion: "請修正 synology-app.yaml 的欄位格式以符合規範。",
|
|
17
|
+
},
|
|
18
|
+
CONTRACT_PACKAGE_TOO_LONG: {
|
|
19
|
+
code: "CONTRACT_PACKAGE_TOO_LONG",
|
|
20
|
+
description: "Package Identity 超過 DSM 上限 32 字元。",
|
|
21
|
+
suggestion: "請縮短 synology-app.yaml 中的 package 名稱至 32 字元以內。",
|
|
22
|
+
},
|
|
23
|
+
CONTRACT_ADMINPORT_INVALID: {
|
|
24
|
+
code: "CONTRACT_ADMINPORT_INVALID",
|
|
25
|
+
description: "adminport 必須是整數。",
|
|
26
|
+
suggestion: "請在 synology-app.yaml 提供與 Compose published port 對應的整數 adminport。",
|
|
27
|
+
},
|
|
28
|
+
CONTRACT_ADMINPORT_UNMAPPED: {
|
|
29
|
+
code: "CONTRACT_ADMINPORT_UNMAPPED",
|
|
30
|
+
description: "adminport 未在 Compose ports 宣告中對應到容器 port。",
|
|
31
|
+
suggestion: "請在 compose.yaml 的 ports 區塊宣告與 adminport 對應的連接埠映射(例如 \"8080:80\")。",
|
|
32
|
+
},
|
|
33
|
+
CONTRACT_LAUNCH_INVALID: {
|
|
34
|
+
code: "CONTRACT_LAUNCH_INVALID",
|
|
35
|
+
description: "integration.web.launch 模式無效。",
|
|
36
|
+
suggestion: "請改為 dsm-window(DSM 視窗,預設)或 new-page(新分頁),Headless App 請省略此欄位。",
|
|
37
|
+
},
|
|
38
|
+
CONTRACT_LAUNCH_REQUIRES_WEB: {
|
|
39
|
+
code: "CONTRACT_LAUNCH_REQUIRES_WEB",
|
|
40
|
+
description: "Headless App 不需要宣告 Web Launch Mode。",
|
|
41
|
+
suggestion: "請省略 integration.web.launch,或補上對應 Compose published port 的 adminport。",
|
|
42
|
+
},
|
|
43
|
+
CONTRACT_INVALID_STRING: {
|
|
44
|
+
code: "CONTRACT_INVALID_STRING",
|
|
45
|
+
description: "合約字串含有不允許的控制字元或未允許的插值語法。",
|
|
46
|
+
suggestion: "請移除控制字元與 ${ 插值語法,安裝參數請在 install 區塊宣告。",
|
|
47
|
+
},
|
|
48
|
+
CONTRACT_DSM_USER_DUPLICATE: {
|
|
49
|
+
code: "CONTRACT_DSM_USER_DUPLICATE",
|
|
50
|
+
description: "每顆 App 至多宣告一個 dsm_user 安裝參數。",
|
|
51
|
+
suggestion: "請在 synology-app.yaml 只保留一個 Container Run-as 參數。",
|
|
52
|
+
},
|
|
53
|
+
INSTALL_STRING_TOO_LONG: {
|
|
54
|
+
code: "INSTALL_STRING_TOO_LONG",
|
|
55
|
+
description: "Install Parameter 字串預設值超過 256 字元。",
|
|
56
|
+
suggestion: "請縮短 synology-app.yaml 中 install 參數的預設字串長度。",
|
|
57
|
+
},
|
|
58
|
+
INSTALL_STRING_INVALID: {
|
|
59
|
+
code: "INSTALL_STRING_INVALID",
|
|
60
|
+
description: "Install Parameter 字串值含有不合法字元或插值。",
|
|
61
|
+
suggestion: "請移除 install 參數預設值中的控制字元與 ${ 插值語法。",
|
|
62
|
+
},
|
|
63
|
+
INSTALL_PARAMETER_UNREFERENCED: {
|
|
64
|
+
code: "INSTALL_PARAMETER_UNREFERENCED",
|
|
65
|
+
description: "install 宣告的參數未在 Compose 中被引用。",
|
|
66
|
+
suggestion: "請在 compose.yaml 以 ${參數名稱} 引用該參數,或從 synology-app.yaml 移除未使用的宣告。",
|
|
67
|
+
},
|
|
68
|
+
INSTALL_DSM_USER_UNREFERENCED: {
|
|
69
|
+
code: "INSTALL_DSM_USER_UNREFERENCED",
|
|
70
|
+
description: "dsm_user 參數未在 Compose 中完整引用 UID 與 GID。",
|
|
71
|
+
suggestion: "請在 compose.yaml 將容器 user 或 PUID/PGID 設為 ${NAME_UID}:${NAME_GID}。",
|
|
72
|
+
},
|
|
73
|
+
CONTRACT_HOMES_PATH_FORBIDDEN: {
|
|
74
|
+
code: "CONTRACT_HOMES_PATH_FORBIDDEN",
|
|
75
|
+
description: "homes Install Parameter 不得在契約中寫入 NAS 實體路徑或預設值。",
|
|
76
|
+
suggestion: "請只宣告 type: homes 並在 Compose 引用該參數,由 glue/Broker 在安裝時解析這台 NAS 的 User Home 路徑。",
|
|
77
|
+
},
|
|
78
|
+
CONTRACT_POSIX_ALL_SHARES_VALUE_FORBIDDEN: {
|
|
79
|
+
code: "CONTRACT_POSIX_ALL_SHARES_VALUE_FORBIDDEN",
|
|
80
|
+
description: "POSIX all-shares 參數不得在契約中指定 default 或 NAS 實體路徑。",
|
|
81
|
+
suggestion: "請只宣告 type: posix_all_shares,讓 Broker 在安裝時用 DSM API 建立 Share snapshot。",
|
|
82
|
+
},
|
|
83
|
+
DSM_USER_REQUIRED: {
|
|
84
|
+
code: "DSM_USER_REQUIRED",
|
|
85
|
+
description: "有 Shared Folder 時必須宣告恰好一個 dsm_user 作為 Container Run-as。",
|
|
86
|
+
suggestion: "請在 synology-app.yaml 新增 install.<NAME>.type: dsm_user,並在 Compose 引用 ${NAME_UID}:${NAME_GID}。",
|
|
87
|
+
},
|
|
88
|
+
// --- Compose / Security Validation ---
|
|
89
|
+
PROJECT_RUNTIME_EXCLUSIVE: {
|
|
90
|
+
code: "PROJECT_RUNTIME_EXCLUSIVE",
|
|
91
|
+
description: "專案同時存在 compose.yaml 與 native.yaml,兩者互斥。",
|
|
92
|
+
suggestion: "請選擇使用 compose.yaml(容器 App)或 native.yaml(原生 App),並刪除另一個檔案。",
|
|
93
|
+
},
|
|
94
|
+
COMPOSE_MISSING: {
|
|
95
|
+
code: "COMPOSE_MISSING",
|
|
96
|
+
description: "找不到 compose.yaml 或 native.yaml。",
|
|
97
|
+
suggestion: "請在專案根目錄建立 compose.yaml 或 native.yaml。",
|
|
98
|
+
},
|
|
99
|
+
COMPOSE_SERVICE_NOT_FOUND: {
|
|
100
|
+
code: "COMPOSE_SERVICE_NOT_FOUND",
|
|
101
|
+
description: "depends_on 引用的服務不存在於 compose.yaml 中。",
|
|
102
|
+
suggestion: "請修正 compose.yaml 中的 depends_on,指向正確已定義的 service 名稱。",
|
|
103
|
+
},
|
|
104
|
+
COMPOSE_NUMERIC_COMMAND_ARG_FORBIDDEN: {
|
|
105
|
+
code: "COMPOSE_NUMERIC_COMMAND_ARG_FORBIDDEN",
|
|
106
|
+
description: "會走 DSM Docker Project resource worker 的 Compose command/entrypoint 陣列含純數字字串,可能在 worker YAML round-trip 後變成整數而無法 acquire。",
|
|
107
|
+
suggestion: "請把整個命令包成單一字串,例如 command: [\"sh\", \"-c\", \"httpd -f -p 8080 -h /srv\"],或與 flag 併寫成 \"-p8080\"。",
|
|
108
|
+
},
|
|
109
|
+
COMPOSE_DYNAMIC_ROUTE_UNSUPPORTED: {
|
|
110
|
+
code: "COMPOSE_DYNAMIC_ROUTE_UNSUPPORTED",
|
|
111
|
+
description: "Compose dynamic route 超出 D1/D2 白名單,或使用 DSM worker 不會載入的 secret/config 來源。",
|
|
112
|
+
suggestion: "請只使用 string/boolean wizard answer 的 ${NAME} interpolation;secret/config 因 DSM worker 不讀 docker-compose.override.yml 而拒收。",
|
|
113
|
+
},
|
|
114
|
+
COMPOSE_BUILD_FORBIDDEN: {
|
|
115
|
+
code: "COMPOSE_BUILD_FORBIDDEN",
|
|
116
|
+
description: "D0 Compose route 禁止在 NAS install-time 使用 build:;build capability 永久拒收。",
|
|
117
|
+
suggestion: "請移除 build:,改用已存在的 image(最好使用 image@sha256:... 固定 digest),再重新執行 validate。",
|
|
118
|
+
},
|
|
119
|
+
COMPOSE_SOCKET_MOUNT_FORBIDDEN: {
|
|
120
|
+
code: "COMPOSE_SOCKET_MOUNT_FORBIDDEN",
|
|
121
|
+
description: "嚴禁掛載 Docker Socket 或系統敏感 Socket。",
|
|
122
|
+
suggestion: "請從 compose.yaml 移除 docker.sock 掛載;如需存取檔案請改用 shared_folder 或 File Gateway。",
|
|
123
|
+
},
|
|
124
|
+
COMPOSE_BIND_SOURCE_FORBIDDEN: {
|
|
125
|
+
code: "COMPOSE_BIND_SOURCE_FORBIDDEN",
|
|
126
|
+
description: "掛載來源路徑不合法或屬於受保護的系統路徑。",
|
|
127
|
+
suggestion: "請使用受控的 ${SYNOPKG_PKGVAR}、${SYNO_APP_SECRETS_DIR} 或已宣告的 ${SHARED_FOLDER} 槽位。",
|
|
128
|
+
},
|
|
129
|
+
COMPOSE_BIND_SOURCE_UNDECLARED: {
|
|
130
|
+
code: "COMPOSE_BIND_SOURCE_UNDECLARED",
|
|
131
|
+
description: "Volume 掛載使用了未宣告的 Shared Folder 變數。",
|
|
132
|
+
suggestion: "請先在 synology-app.yaml 的 install 區塊宣告該 shared_folder 參數。",
|
|
133
|
+
},
|
|
134
|
+
COMPOSE_BIND_SUFFIX_INVALID: {
|
|
135
|
+
code: "COMPOSE_BIND_SUFFIX_INVALID",
|
|
136
|
+
description: "Shared Folder 子路徑格式不合法(含有 .. 或控制字元)。",
|
|
137
|
+
suggestion: "請改用合法的相對子路徑,例如 ${MEDIA_SHARE}/data:/data。",
|
|
138
|
+
},
|
|
139
|
+
COMPOSE_POSIX_ALL_SHARES_UNDECLARED: {
|
|
140
|
+
code: "COMPOSE_POSIX_ALL_SHARES_UNDECLARED",
|
|
141
|
+
description: "Compose 使用了未宣告的 POSIX all-shares marker。",
|
|
142
|
+
suggestion: "請宣告 type: posix_all_shares,讓 Broker 透過 DSM API 建立安裝當下的 Share snapshot。",
|
|
143
|
+
},
|
|
144
|
+
COMPOSE_POSIX_ALL_SHARES_SUFFIX_FORBIDDEN: {
|
|
145
|
+
code: "COMPOSE_POSIX_ALL_SHARES_SUFFIX_FORBIDDEN",
|
|
146
|
+
description: "POSIX all-shares marker 不得附加 Share 子路徑。",
|
|
147
|
+
suggestion: "請只使用完整的 ${ALL_SHARES} source;每個 Share 的 container target 由 Broker 展開。",
|
|
148
|
+
},
|
|
149
|
+
COMPOSE_HOST_BIND_FORBIDDEN: {
|
|
150
|
+
code: "COMPOSE_HOST_BIND_FORBIDDEN",
|
|
151
|
+
description: "禁止直接硬編碼本機路徑(例如 /volume1/... 或 ./)。",
|
|
152
|
+
suggestion: "請在 synology-app.yaml 宣告 shared_folder 參數,並在 Compose 改用 ${SLOT} 引用。",
|
|
153
|
+
},
|
|
154
|
+
COMPOSE_NAMED_VOLUME_UNDECLARED: {
|
|
155
|
+
code: "COMPOSE_NAMED_VOLUME_UNDECLARED",
|
|
156
|
+
description: "服務使用了未在頂層 volumes 宣告的 Named Volume。",
|
|
157
|
+
suggestion: "請在 compose.yaml 頂層 volumes 區塊補上該 Volume 宣告,或改用受控目錄。",
|
|
158
|
+
},
|
|
159
|
+
COMPOSE_USER_ROOT_FORBIDDEN: {
|
|
160
|
+
code: "COMPOSE_USER_ROOT_FORBIDDEN",
|
|
161
|
+
description: "容器以 root (0:0) 執行,違反最小權限原則。",
|
|
162
|
+
suggestion: "請在 synology-app.yaml 宣告 dsm_user 並在 Compose 使用 ${USER_UID}:${USER_GID}。",
|
|
163
|
+
},
|
|
164
|
+
COMPOSE_USER_NUMERIC_FORBIDDEN: {
|
|
165
|
+
code: "COMPOSE_USER_NUMERIC_FORBIDDEN",
|
|
166
|
+
description: "禁止在 compose.yaml 硬編碼數字 uid:gid。",
|
|
167
|
+
suggestion: "請在 synology-app.yaml 宣告 dsm_user,並在 Compose 引用 ${NAME_UID}:${NAME_GID}。",
|
|
168
|
+
},
|
|
169
|
+
COMPOSE_PRIVILEGED_FORBIDDEN: {
|
|
170
|
+
code: "COMPOSE_PRIVILEGED_FORBIDDEN",
|
|
171
|
+
description: "使用了 privileged: true 但未在合約宣告。",
|
|
172
|
+
suggestion: "請在 synology-app.yaml 加上 privilege.privileged: true,或移除 privileged: true。",
|
|
173
|
+
},
|
|
174
|
+
COMPOSE_HOST_NETWORK_FORBIDDEN: {
|
|
175
|
+
code: "COMPOSE_HOST_NETWORK_FORBIDDEN",
|
|
176
|
+
description: "使用了 host network 模式但未在合約宣告。",
|
|
177
|
+
suggestion: "請在 synology-app.yaml 加上 privilege.host_network: true,或改用受控網路模式。",
|
|
178
|
+
},
|
|
179
|
+
COMPOSE_HOST_PID_FORBIDDEN: {
|
|
180
|
+
code: "COMPOSE_HOST_PID_FORBIDDEN",
|
|
181
|
+
description: "使用了 pid: host 但未在合約宣告。",
|
|
182
|
+
suggestion: "請在 synology-app.yaml 加上 privilege.host_pid: true,或移除 pid: host。",
|
|
183
|
+
},
|
|
184
|
+
COMPOSE_HOST_IPC_FORBIDDEN: {
|
|
185
|
+
code: "COMPOSE_HOST_IPC_FORBIDDEN",
|
|
186
|
+
description: "使用了 ipc: host 但未在合約宣告。",
|
|
187
|
+
suggestion: "請在 synology-app.yaml 加上 privilege.host_ipc: true,或移除 ipc: host。",
|
|
188
|
+
},
|
|
189
|
+
COMPOSE_DEVICES_FORBIDDEN: {
|
|
190
|
+
code: "COMPOSE_DEVICES_FORBIDDEN",
|
|
191
|
+
description: "使用了 devices 裝置存取但未在合約宣告。",
|
|
192
|
+
suggestion: "請在 synology-app.yaml 加上 privilege.devices: true,或移除 devices 區塊。",
|
|
193
|
+
},
|
|
194
|
+
COMPOSE_CAP_ADD_FORBIDDEN: {
|
|
195
|
+
code: "COMPOSE_CAP_ADD_FORBIDDEN",
|
|
196
|
+
description: "使用了 cap_add 權限提升但未在合約宣告。",
|
|
197
|
+
suggestion: "請在 synology-app.yaml 加上 privilege.cap_add: true,或移除 cap_add 區塊。",
|
|
198
|
+
},
|
|
199
|
+
COMPOSE_ENV_MISSING: {
|
|
200
|
+
code: "COMPOSE_ENV_MISSING",
|
|
201
|
+
description: "專案缺少必要的環境變數目錄結構。",
|
|
202
|
+
suggestion: "請確認 SYNOPKG_PKGVAR 與 secrets 目錄已正確建立。",
|
|
203
|
+
},
|
|
204
|
+
COMPOSE_NOT_HEALTHY: {
|
|
205
|
+
code: "COMPOSE_NOT_HEALTHY",
|
|
206
|
+
description: "Compose 服務未能於時限內通過 healthcheck 達到 healthy 狀態。",
|
|
207
|
+
suggestion: "請檢查容器健康檢查設定與應用程式日誌:synopkgland log --host <nas>。",
|
|
208
|
+
},
|
|
209
|
+
COMPOSE_NOT_RUNNING: {
|
|
210
|
+
code: "COMPOSE_NOT_RUNNING",
|
|
211
|
+
description: "Compose 服務未能於時限內維持 running 狀態。",
|
|
212
|
+
suggestion: "請檢查容器啟動腳本與日誌以排除崩潰原因:synopkgland log --host <nas>。",
|
|
213
|
+
},
|
|
214
|
+
// --- Native Validation / Payload ---
|
|
215
|
+
NATIVE_LOAD_FAILED: {
|
|
216
|
+
code: "NATIVE_LOAD_FAILED",
|
|
217
|
+
description: "無法讀取或解析 native.yaml。",
|
|
218
|
+
suggestion: "請確認 native.yaml 存在且為合法 YAML 格式。",
|
|
219
|
+
},
|
|
220
|
+
NATIVE_SCHEMA_INVALID: {
|
|
221
|
+
code: "NATIVE_SCHEMA_INVALID",
|
|
222
|
+
description: "native.yaml schema 版本無效(必須為整數 1)。",
|
|
223
|
+
suggestion: "請在 native.yaml 設定 schema: 1。",
|
|
224
|
+
},
|
|
225
|
+
NATIVE_TARGETS_REQUIRED: {
|
|
226
|
+
code: "NATIVE_TARGETS_REQUIRED",
|
|
227
|
+
description: "native.yaml 缺少 targets 區塊。",
|
|
228
|
+
suggestion: "請在 native.yaml 宣告 targets 區塊並指定 x86_64 或 aarch64 目標。",
|
|
229
|
+
},
|
|
230
|
+
NATIVE_TARGETS_EMPTY: {
|
|
231
|
+
code: "NATIVE_TARGETS_EMPTY",
|
|
232
|
+
description: "native.yaml 中的 targets 區塊不可為空。",
|
|
233
|
+
suggestion: "請在 native.yaml 的 targets 內至少定義一個架構目標(x86_64 或 aarch64)。",
|
|
234
|
+
},
|
|
235
|
+
NATIVE_ARCH_UNKNOWN: {
|
|
236
|
+
code: "NATIVE_ARCH_UNKNOWN",
|
|
237
|
+
description: "native.yaml 定義了不受支援的架構目標名稱。",
|
|
238
|
+
suggestion: "目標架構名稱僅支援 x86_64 與 aarch64。",
|
|
239
|
+
},
|
|
240
|
+
NATIVE_TARGET_INVALID: {
|
|
241
|
+
code: "NATIVE_TARGET_INVALID",
|
|
242
|
+
description: "native.yaml 目標架構定義無效。",
|
|
243
|
+
suggestion: "每個目標架構必須包含 path 或 url 下載來源設定。",
|
|
244
|
+
},
|
|
245
|
+
NATIVE_TARGET_NOT_DECLARED: {
|
|
246
|
+
code: "NATIVE_TARGET_NOT_DECLARED",
|
|
247
|
+
description: "欲建置或部署的架構目標未在 native.yaml 中宣告。",
|
|
248
|
+
suggestion: "請在 native.yaml 的 targets 補上該架構目標,或透過 --arch 指定已宣告的目標。",
|
|
249
|
+
},
|
|
250
|
+
NATIVE_TARGET_SOURCE_EXCLUSIVE: {
|
|
251
|
+
code: "NATIVE_TARGET_SOURCE_EXCLUSIVE",
|
|
252
|
+
description: "目標架構不可同時包含 path 與 url,兩者互斥。",
|
|
253
|
+
suggestion: "請在該目標架構中只保留 path(本機)或 url(遠端二進位檔)。",
|
|
254
|
+
},
|
|
255
|
+
NATIVE_PATH_FORBIDDEN_IN_LISTING: {
|
|
256
|
+
code: "NATIVE_PATH_FORBIDDEN_IN_LISTING",
|
|
257
|
+
description: "公開上架審查禁止使用本機 path 來源的 native 目標。",
|
|
258
|
+
suggestion: "請將 target 改為公開可下載的 url 並附帶 sha256 校驗碼。",
|
|
259
|
+
},
|
|
260
|
+
NATIVE_SHA256_REQUIRED_IN_LISTING: {
|
|
261
|
+
code: "NATIVE_SHA256_REQUIRED_IN_LISTING",
|
|
262
|
+
description: "公開上架審查要求 url 目標必須提供 sha256 校驗碼。",
|
|
263
|
+
suggestion: "請在 native.yaml 的 url 目標補上 64 位十六進位 sha256 欄位。",
|
|
264
|
+
},
|
|
265
|
+
NATIVE_SHA256_INVALID: {
|
|
266
|
+
code: "NATIVE_SHA256_INVALID",
|
|
267
|
+
description: "sha256 校驗碼格式無效。",
|
|
268
|
+
suggestion: "請提供恰好 64 字元的十六進位 SHA-256 字串。",
|
|
269
|
+
},
|
|
270
|
+
NATIVE_STRIP_COMPONENTS_INVALID: {
|
|
271
|
+
code: "NATIVE_STRIP_COMPONENTS_INVALID",
|
|
272
|
+
description: "strip_components 必須是非負整數。",
|
|
273
|
+
suggestion: "請在 native.yaml 將 strip_components 設為大於等於 0 的整數。",
|
|
274
|
+
},
|
|
275
|
+
NATIVE_SERVICE_REQUIRED: {
|
|
276
|
+
code: "NATIVE_SERVICE_REQUIRED",
|
|
277
|
+
description: "native.yaml 缺少 service 區塊。",
|
|
278
|
+
suggestion: "請在 native.yaml 補上 service 區塊並宣告 exec 與 args/env。",
|
|
279
|
+
},
|
|
280
|
+
NATIVE_SERVICE_USER_FORBIDDEN: {
|
|
281
|
+
code: "NATIVE_SERVICE_USER_FORBIDDEN",
|
|
282
|
+
description: "native service 不允許自訂 user 欄位(固定以 package 使用者執行)。",
|
|
283
|
+
suggestion: "請從 native.yaml 的 service 區塊移除 user 欄位。",
|
|
284
|
+
},
|
|
285
|
+
NATIVE_SERVICE_SHELL_FIELD_FORBIDDEN: {
|
|
286
|
+
code: "NATIVE_SERVICE_SHELL_FIELD_FORBIDDEN",
|
|
287
|
+
description: "禁止在 native service 使用 command/shell 等字串欄位以免 shell injection。",
|
|
288
|
+
suggestion: "請改用 exec(路徑)與 args(字串陣列)方式宣告啟動指令。",
|
|
289
|
+
},
|
|
290
|
+
NATIVE_EXEC_REQUIRED: {
|
|
291
|
+
code: "NATIVE_EXEC_REQUIRED",
|
|
292
|
+
description: "native service 缺少 exec 執行檔路徑。",
|
|
293
|
+
suggestion: "請在 native.yaml 的 service 區塊指定 exec: <相對路徑>。",
|
|
294
|
+
},
|
|
295
|
+
NATIVE_EXEC_INVALID_PATH: {
|
|
296
|
+
code: "NATIVE_EXEC_INVALID_PATH",
|
|
297
|
+
description: "exec 必須是相對路徑,且不可包含 .. 或絕對路徑。",
|
|
298
|
+
suggestion: "請指定相對於安裝根目錄的合法相對路徑,例如 exec: bin/app。",
|
|
299
|
+
},
|
|
300
|
+
NATIVE_ARGS_INVALID: {
|
|
301
|
+
code: "NATIVE_ARGS_INVALID",
|
|
302
|
+
description: "service.args 必須是字串陣列。",
|
|
303
|
+
suggestion: "請在 native.yaml 將 args 宣告為字串列表格式(例如 args: [\"--port\", \"8080\"])。",
|
|
304
|
+
},
|
|
305
|
+
NATIVE_ENV_INVALID: {
|
|
306
|
+
code: "NATIVE_ENV_INVALID",
|
|
307
|
+
description: "service.env 必須是 key-value 字串映射表。",
|
|
308
|
+
suggestion: "請將 env 宣告為字典物件且每個值皆為字串。",
|
|
309
|
+
},
|
|
310
|
+
NATIVE_PKGVAR_REQUIRED: {
|
|
311
|
+
code: "NATIVE_PKGVAR_REQUIRED",
|
|
312
|
+
description: "原生二進位 App 必須在 args 或 env 中引用 ${SYNOPKG_PKGVAR} 以指定資料路徑。",
|
|
313
|
+
suggestion: "請在 native.yaml 的 service.args 或 service.env 加入 ${SYNOPKG_PKGVAR} 參數。",
|
|
314
|
+
},
|
|
315
|
+
NATIVE_ARCH_FAMILY_REQUIRED: {
|
|
316
|
+
code: "NATIVE_ARCH_FAMILY_REQUIRED",
|
|
317
|
+
description: "建置原生 SPK 時缺少目標架構家族(x86_64 或 aarch64)。",
|
|
318
|
+
suggestion: "請在指令加上 --arch x86_64 或 --arch aarch64。",
|
|
319
|
+
},
|
|
320
|
+
NATIVE_ARCH_UNDETERMINED: {
|
|
321
|
+
code: "NATIVE_ARCH_UNDETERMINED",
|
|
322
|
+
description: "無法從目標 NAS 的 CPU 資訊自動判定架構家族。",
|
|
323
|
+
suggestion: "請使用 --arch x86_64 或 --arch aarch64 明確指定目標架構。",
|
|
324
|
+
},
|
|
325
|
+
NATIVE_PAYLOAD_BUNDLE_COLLISION: {
|
|
326
|
+
code: "NATIVE_PAYLOAD_BUNDLE_COLLISION",
|
|
327
|
+
description: "原生 payload 解壓縮內容與 App Bundle 核心保留檔衝突。",
|
|
328
|
+
suggestion: "請檢查 payload 內容,避免在根目錄覆蓋 synology-app.yaml 或 native.yaml。",
|
|
329
|
+
},
|
|
330
|
+
NATIVE_PAYLOAD_DOWNLOAD_FAILED: {
|
|
331
|
+
code: "NATIVE_PAYLOAD_DOWNLOAD_FAILED",
|
|
332
|
+
description: "下載原生二進位檔 payload 失敗。",
|
|
333
|
+
suggestion: "請檢查 native.yaml 中的 url 是否有效且網路連線正常。",
|
|
334
|
+
},
|
|
335
|
+
NATIVE_PAYLOAD_DOWNLOAD_INVALID: {
|
|
336
|
+
code: "NATIVE_PAYLOAD_DOWNLOAD_INVALID",
|
|
337
|
+
description: "下載的原生 payload 回傳內容無效。",
|
|
338
|
+
suggestion: "請確認目標 URL 回傳了有效的二進位檔案內容。",
|
|
339
|
+
},
|
|
340
|
+
NATIVE_PAYLOAD_DUPLICATE_ENTRY: {
|
|
341
|
+
code: "NATIVE_PAYLOAD_DUPLICATE_ENTRY",
|
|
342
|
+
description: "原生 payload 壓縮檔內包含重複的檔案路徑。",
|
|
343
|
+
suggestion: "請重新打包原始檔案,確保壓縮檔內無重複 entry。",
|
|
344
|
+
},
|
|
345
|
+
NATIVE_PAYLOAD_ERROR: {
|
|
346
|
+
code: "NATIVE_PAYLOAD_ERROR",
|
|
347
|
+
description: "處理原生二進位 payload 時發生未預期錯誤。",
|
|
348
|
+
suggestion: "請檢查 payload 壓縮檔完整性或重新建置 SPK。",
|
|
349
|
+
},
|
|
350
|
+
NATIVE_PAYLOAD_EXTRACTION_FAILED: {
|
|
351
|
+
code: "NATIVE_PAYLOAD_EXTRACTION_FAILED",
|
|
352
|
+
description: "解壓縮原生二進位 payload 失敗。",
|
|
353
|
+
suggestion: "請確認壓縮檔格式正確無損壞,且支援 tar.gz / tar.xz / zip。",
|
|
354
|
+
},
|
|
355
|
+
NATIVE_PAYLOAD_INVALID_HARDLINK: {
|
|
356
|
+
code: "NATIVE_PAYLOAD_INVALID_HARDLINK",
|
|
357
|
+
description: "原生 payload 含有無效或循環的 hardlink。",
|
|
358
|
+
suggestion: "請移除壓縮檔中不合法的 hardlink 後重新打包。",
|
|
359
|
+
},
|
|
360
|
+
NATIVE_PAYLOAD_INVALID_STRIP_COMPONENTS: {
|
|
361
|
+
code: "NATIVE_PAYLOAD_INVALID_STRIP_COMPONENTS",
|
|
362
|
+
description: "strip_components 設定超過了壓縮檔目錄層級深度。",
|
|
363
|
+
suggestion: "請在 native.yaml 調整或減少 strip_components 數值。",
|
|
364
|
+
},
|
|
365
|
+
NATIVE_PAYLOAD_INVALID_SYMLINK: {
|
|
366
|
+
code: "NATIVE_PAYLOAD_INVALID_SYMLINK",
|
|
367
|
+
description: "原生 payload 含有無效的符號連結。",
|
|
368
|
+
suggestion: "請檢查壓縮檔內的 symlink 目標是否存在且合法。",
|
|
369
|
+
},
|
|
370
|
+
NATIVE_PAYLOAD_INVALID_ZIP: {
|
|
371
|
+
code: "NATIVE_PAYLOAD_INVALID_ZIP",
|
|
372
|
+
description: "ZIP 壓縮檔格式無效或已損壞。",
|
|
373
|
+
suggestion: "請檢查 zip 檔案完整性或重新打包。",
|
|
374
|
+
},
|
|
375
|
+
NATIVE_PAYLOAD_SHA256_MISMATCH: {
|
|
376
|
+
code: "NATIVE_PAYLOAD_SHA256_MISMATCH",
|
|
377
|
+
description: "下載的 payload SHA-256 校驗碼與 native.yaml 宣告不符。",
|
|
378
|
+
suggestion: "請更新 native.yaml 中的 sha256 欄位以符合實際檔案雜湊。",
|
|
379
|
+
},
|
|
380
|
+
NATIVE_PAYLOAD_SOURCE_AMBIGUOUS: {
|
|
381
|
+
code: "NATIVE_PAYLOAD_SOURCE_AMBIGUOUS",
|
|
382
|
+
description: "目標架構同時宣告了 path 與 url,來源衝突。",
|
|
383
|
+
suggestion: "請在該目標架構中只保留 path 或 url 其中一種來源。",
|
|
384
|
+
},
|
|
385
|
+
NATIVE_PAYLOAD_SOURCE_REQUIRED: {
|
|
386
|
+
code: "NATIVE_PAYLOAD_SOURCE_REQUIRED",
|
|
387
|
+
description: "目標架構缺少 path 或 url 來源設定。",
|
|
388
|
+
suggestion: "請在 native.yaml 的 targets 內為各架構補上 path 或 url。",
|
|
389
|
+
},
|
|
390
|
+
NATIVE_PAYLOAD_SYMLINK_CYCLE: {
|
|
391
|
+
code: "NATIVE_PAYLOAD_SYMLINK_CYCLE",
|
|
392
|
+
description: "原生 payload 包含循環符號連結 (Symlink cycle)。",
|
|
393
|
+
suggestion: "請移除壓縮檔中的循環 symlink。",
|
|
394
|
+
},
|
|
395
|
+
NATIVE_PAYLOAD_UNSAFE_HARDLINK: {
|
|
396
|
+
code: "NATIVE_PAYLOAD_UNSAFE_HARDLINK",
|
|
397
|
+
description: "原生 payload hardlink 試圖連結至目標目錄外。",
|
|
398
|
+
suggestion: "請確保 hardlink 僅指向 payload 目錄內部的有效檔案。",
|
|
399
|
+
},
|
|
400
|
+
NATIVE_PAYLOAD_UNSAFE_PATH: {
|
|
401
|
+
code: "NATIVE_PAYLOAD_UNSAFE_PATH",
|
|
402
|
+
description: "原生 payload 含有路徑穿越 (Path traversal) 等不安全路徑。",
|
|
403
|
+
suggestion: "請確保壓縮檔內無包含 .. 或絕對路徑的檔案名稱。",
|
|
404
|
+
},
|
|
405
|
+
NATIVE_PAYLOAD_UNSAFE_SYMLINK: {
|
|
406
|
+
code: "NATIVE_PAYLOAD_UNSAFE_SYMLINK",
|
|
407
|
+
description: "原生 payload symlink 指向了安裝目錄之外。",
|
|
408
|
+
suggestion: "請確保 symlink 僅指向 payload 目錄內部的相對目標。",
|
|
409
|
+
},
|
|
410
|
+
NATIVE_PAYLOAD_UNSUPPORTED_ENTRY: {
|
|
411
|
+
code: "NATIVE_PAYLOAD_UNSUPPORTED_ENTRY",
|
|
412
|
+
description: "原生 payload 包含不支援的特殊檔案類型(如 device node 或 fifo)。",
|
|
413
|
+
suggestion: "請從壓縮檔中移除特殊檔案,僅保留一般檔案、目錄與合法 symlink。",
|
|
414
|
+
},
|
|
415
|
+
NATIVE_PAYLOAD_UNSUPPORTED_ZIP: {
|
|
416
|
+
code: "NATIVE_PAYLOAD_UNSUPPORTED_ZIP",
|
|
417
|
+
description: "不支援的 ZIP 特性(例如 ZIP64、多卷分割或密碼加密)。",
|
|
418
|
+
suggestion: "請使用標準未加密的 ZIP 或改用 tar.gz 打包。",
|
|
419
|
+
},
|
|
420
|
+
NATIVE_PAYLOAD_XZ_FAILED: {
|
|
421
|
+
code: "NATIVE_PAYLOAD_XZ_FAILED",
|
|
422
|
+
description: "解壓縮 tar.xz 失敗。",
|
|
423
|
+
suggestion: "請確認本機已安裝 xz 工具且檔案未損壞。",
|
|
424
|
+
},
|
|
425
|
+
NATIVE_PAYLOAD_XZ_UNAVAILABLE: {
|
|
426
|
+
code: "NATIVE_PAYLOAD_XZ_UNAVAILABLE",
|
|
427
|
+
description: "系統中找不到 xz 指令可用於解壓縮 .tar.xz 檔案。",
|
|
428
|
+
suggestion: "請在作業系統中安裝 xz-utils 或改用 tar.gz 格式打包。",
|
|
429
|
+
},
|
|
430
|
+
// --- SPK Build & Attestation ---
|
|
431
|
+
EMBEDDED_ATTESTATION_TOKEN_EMPTY: {
|
|
432
|
+
code: "EMBEDDED_ATTESTATION_TOKEN_EMPTY",
|
|
433
|
+
description: "建置 Curated SPK 時嵌入的 Attestation Token 為空。",
|
|
434
|
+
suggestion: "請檢查 CI Attestation 簽章步驟是否正常產出 JWT。",
|
|
435
|
+
},
|
|
436
|
+
BUILD_SPK_FAILED: {
|
|
437
|
+
code: "BUILD_SPK_FAILED",
|
|
438
|
+
description: "SPK 打包流程失敗。",
|
|
439
|
+
suggestion: "請檢查 validate 錯誤與目錄檔案權限後重試。",
|
|
440
|
+
},
|
|
441
|
+
// --- Deploy & Host ---
|
|
442
|
+
VALIDATION_FAILED: {
|
|
443
|
+
code: "VALIDATION_FAILED",
|
|
444
|
+
description: "專案未通過契約或安全驗證,終止部署。",
|
|
445
|
+
suggestion: "請先執行 synopkgland validate 排除合約與 Compose 錯誤。",
|
|
446
|
+
},
|
|
447
|
+
DEPLOY_FAILED: {
|
|
448
|
+
code: "DEPLOY_FAILED",
|
|
449
|
+
description: "部署至 NAS 時發生未分類錯誤。",
|
|
450
|
+
suggestion: "請檢查 NAS 網路連線與日誌:synopkgland log --host <nas>。",
|
|
451
|
+
},
|
|
452
|
+
DEPLOY_PERSONAL_BUILD_EXHAUSTED: {
|
|
453
|
+
code: "DEPLOY_PERSONAL_BUILD_EXHAUSTED",
|
|
454
|
+
description: "Personal App 的 Package Build 已用盡 0001–9999 命名範圍。",
|
|
455
|
+
suggestion: "請改用新的 App Version,或先清理並確認不會與 Curated 版本命名空間混用。",
|
|
456
|
+
},
|
|
457
|
+
SHARE_VALUE_REQUIRED: {
|
|
458
|
+
code: "SHARE_VALUE_REQUIRED",
|
|
459
|
+
description: "部署時缺少合約中宣告的 shared_folder 實際路徑映射。",
|
|
460
|
+
suggestion: "請使用 --share <SLOT>=<邏輯名> 提供對應的 Shared Folder 名稱。",
|
|
461
|
+
},
|
|
462
|
+
SHARE_LOGICAL_NAME_REQUIRED: {
|
|
463
|
+
code: "SHARE_LOGICAL_NAME_REQUIRED",
|
|
464
|
+
description: "Share 參數必須提供邏輯名稱,禁止使用 /volume1/... 等實體路徑。",
|
|
465
|
+
suggestion: "請指定 DSM 控制台中的 Shared Folder 邏輯名稱,例如 --share MEDIA_SHARE=photos。",
|
|
466
|
+
},
|
|
467
|
+
SHARE_NOT_FOUND: {
|
|
468
|
+
code: "SHARE_NOT_FOUND",
|
|
469
|
+
description: "在目標 NAS 上找不到指定的 Shared Folder。",
|
|
470
|
+
suggestion: "請在 DSM 控制台建立該 Shared Folder,或檢查名稱拼字。",
|
|
471
|
+
},
|
|
472
|
+
HOMES_NOT_ENABLED: {
|
|
473
|
+
code: "HOMES_NOT_ENABLED",
|
|
474
|
+
description: "目標 NAS 未啟用 User Home,或無法解析 homes 的實體 bind source。",
|
|
475
|
+
suggestion: "請在這台 NAS 啟用 DSM User Home,並確認 Broker/glue 能回傳解析後的路徑,再重新部署。",
|
|
476
|
+
},
|
|
477
|
+
DSM_USER_LOGICAL_NAME_REQUIRED: {
|
|
478
|
+
code: "DSM_USER_LOGICAL_NAME_REQUIRED",
|
|
479
|
+
description: "dsm_user 參數必須提供 DSM 使用者邏輯名稱,禁止使用數字 UID。",
|
|
480
|
+
suggestion: "請在 --run-as 指定 DSM 使用者帳號名稱(例如 --run-as RUN_AS=alice)。",
|
|
481
|
+
},
|
|
482
|
+
CURATED_DEPLOY_REFUSED: {
|
|
483
|
+
code: "CURATED_DEPLOY_REFUSED",
|
|
484
|
+
description: "目標 NAS 已持有 Curated App Package Attestation,禁止隨意覆蓋部署。",
|
|
485
|
+
suggestion: "請改用 --dev 部署至開發隔離環境,或加上 --replace-curated 明確降級。",
|
|
486
|
+
},
|
|
487
|
+
CATALOG_PUBLISH_FAILED: {
|
|
488
|
+
code: "CATALOG_PUBLISH_FAILED",
|
|
489
|
+
description: "發布 SPK 至 Package Source 失敗。",
|
|
490
|
+
suggestion: "請確認 Package Source 服務運作正常且網路可達。",
|
|
491
|
+
},
|
|
492
|
+
LOCAL_SPK_INSTALL_UNSUPPORTED: {
|
|
493
|
+
code: "LOCAL_SPK_INSTALL_UNSUPPORTED",
|
|
494
|
+
description: "目標主機介面不支援直接安裝本機 SPK。",
|
|
495
|
+
suggestion: "請透過 Package Center 或支援 local-spk 安裝的 Host Adapter 進行部署。",
|
|
496
|
+
},
|
|
497
|
+
CATALOG_INSTALL_FAILED: {
|
|
498
|
+
code: "CATALOG_INSTALL_FAILED",
|
|
499
|
+
description: "NAS Package Center 安裝套件失敗。",
|
|
500
|
+
suggestion: "請至 DSM Package Center 檢查安裝日誌或手動嘗試安裝。",
|
|
501
|
+
},
|
|
502
|
+
DEPLOY_PARAM_UNDECLARED: {
|
|
503
|
+
code: "DEPLOY_PARAM_UNDECLARED",
|
|
504
|
+
description: "deploy --param 提供了契約未宣告的 Install Parameter。",
|
|
505
|
+
suggestion: "請只傳 synology-app.yaml install 中宣告的 string 或 boolean 名稱。",
|
|
506
|
+
},
|
|
507
|
+
DEPLOY_PARAM_TYPE_INVALID: {
|
|
508
|
+
code: "DEPLOY_PARAM_TYPE_INVALID",
|
|
509
|
+
description: "deploy --param 的值不符合契約宣告的 string 或 boolean 型別。",
|
|
510
|
+
suggestion: "string 請傳非空字串;boolean 請只傳 true 或 false。",
|
|
511
|
+
},
|
|
512
|
+
DSM_DEPENDENCY_CONFLICT: {
|
|
513
|
+
code: "DSM_DEPENDENCY_CONFLICT",
|
|
514
|
+
description: "DSM 複合安裝請求因執行中的依賴套件而拒絕。",
|
|
515
|
+
suggestion: "請先停止列出的依賴套件再重試升級。",
|
|
516
|
+
},
|
|
517
|
+
DSM_COMPOUND_FAILED: {
|
|
518
|
+
code: "DSM_COMPOUND_FAILED",
|
|
519
|
+
description: "DSM 複合安裝請求的子步驟失敗。",
|
|
520
|
+
suggestion: "請檢查回應中的 api、method、errorCode 與 DSM Package Center 日誌後重試。",
|
|
521
|
+
},
|
|
522
|
+
DSM_REQUEST_FAILED: {
|
|
523
|
+
code: "DSM_REQUEST_FAILED",
|
|
524
|
+
description: "DSM SYNO.Entry.Request 複合請求失敗。",
|
|
525
|
+
suggestion: "請檢查 DSM session、請求參數與 Package Center 日誌後重試。",
|
|
526
|
+
},
|
|
527
|
+
INNER_LOOP_API_MISSING: {
|
|
528
|
+
code: "INNER_LOOP_API_MISSING",
|
|
529
|
+
description: "目標 NAS 上的 SynoPkgLandService Broker inner-loop API 不可用。",
|
|
530
|
+
suggestion: "請確認已在 NAS 安裝並啟動 SynoPkgLandService (Broker >= 0.1.0-0016)。",
|
|
531
|
+
},
|
|
532
|
+
ATTESTATION_FAILED: {
|
|
533
|
+
code: "ATTESTATION_FAILED",
|
|
534
|
+
description: "向 NAS 申請或驗證 Local Attestation 失敗。",
|
|
535
|
+
suggestion: "請檢查 DSM 登入身分是否為管理者,以及 Broker 運作狀態。",
|
|
536
|
+
},
|
|
537
|
+
NOT_INSTALLED: {
|
|
538
|
+
code: "NOT_INSTALLED",
|
|
539
|
+
description: "套件尚未在目標 NAS 上安裝部署。",
|
|
540
|
+
suggestion: "請先執行 synopkgland deploy --host <nas> 安裝套件。",
|
|
541
|
+
},
|
|
542
|
+
HOST_CREDENTIALS_MISSING: {
|
|
543
|
+
code: "HOST_CREDENTIALS_MISSING",
|
|
544
|
+
description: "找不到目標 NAS 的連線憑證。",
|
|
545
|
+
suggestion: "請在 ~/.synoagentcli/setting.json 設定 profile,或設定 DSM_URL 與 DSM_PASSWORD 環境變數。",
|
|
546
|
+
},
|
|
547
|
+
HOST_UNREACHABLE: {
|
|
548
|
+
code: "HOST_UNREACHABLE",
|
|
549
|
+
description: "無法連線至目標 NAS(連線逾時或網路不可達)。",
|
|
550
|
+
suggestion: "請檢查 NAS IP/網址與網路連線;Node 網路若遇 EHOSTUNREACH 可使用 curl fallback 模式。",
|
|
551
|
+
},
|
|
552
|
+
BROKER_NOT_INSTALLED: {
|
|
553
|
+
code: "BROKER_NOT_INSTALLED",
|
|
554
|
+
description: "目標 NAS 尚未安裝 SynoPkgLandService (Broker)。",
|
|
555
|
+
suggestion: "請至 DSM Package Center 安裝 SynoPkgLandService 套件。",
|
|
556
|
+
},
|
|
557
|
+
PACKAGE_BROKEN: {
|
|
558
|
+
code: "PACKAGE_BROKEN",
|
|
559
|
+
description: "套件在 DSM Package Center 處於損毀或安裝失敗狀態 (status 150 / broken)。",
|
|
560
|
+
suggestion: "請至 DSM Package Center 嘗試修復 (Repair) 或重新安裝套件。",
|
|
561
|
+
},
|
|
562
|
+
ATTESTATION_TRUST_ROOT_MISSING: {
|
|
563
|
+
code: "ATTESTATION_TRUST_ROOT_MISSING",
|
|
564
|
+
description: "Broker 缺少生產環境 Attestation Trust Root 信任根憑證。",
|
|
565
|
+
suggestion: "請確認 SynoPkgLandService 套件完整安裝且 trust root keyring 未被移除。",
|
|
566
|
+
},
|
|
567
|
+
ATTESTATION_MISSING: {
|
|
568
|
+
code: "ATTESTATION_MISSING",
|
|
569
|
+
description: "App Bundle 缺少必要的 Attestation 簽章憑證。",
|
|
570
|
+
suggestion: "請先透過 synopkgland deploy 簽發 Local Attestation 或透過 Curated CI 簽署。",
|
|
571
|
+
},
|
|
572
|
+
ATTESTATION_INVALID: {
|
|
573
|
+
code: "ATTESTATION_INVALID",
|
|
574
|
+
description: "Attestation Token 驗證失敗或與目前 App Bundle 雜湊不符。",
|
|
575
|
+
suggestion: "檔案修改後請重新執行 synopkgland deploy 產生並安裝新 Attestation。",
|
|
576
|
+
},
|
|
577
|
+
READINESS_TIMEOUT: {
|
|
578
|
+
code: "READINESS_TIMEOUT",
|
|
579
|
+
description: "App 容器未在時限內就緒 (Readiness Deadline)。",
|
|
580
|
+
suggestion: "請使用 synopkgland log --host <nas> 檢查容器啟動日誌與健康檢查。",
|
|
581
|
+
},
|
|
582
|
+
PROJECT_BINDING_NOT_FOUND: {
|
|
583
|
+
code: "PROJECT_BINDING_NOT_FOUND",
|
|
584
|
+
description: "在 Broker 中找不到此套件的 Project Binding 紀錄。",
|
|
585
|
+
suggestion: "請執行 synopkgland deploy --host <nas> 重新建立部署。",
|
|
586
|
+
},
|
|
587
|
+
PROJECT_BINDING_DRIFTED: {
|
|
588
|
+
code: "PROJECT_BINDING_DRIFTED",
|
|
589
|
+
description: "Container Manager 中的實際專案狀態與 Broker 綁定記錄不一致。",
|
|
590
|
+
suggestion: "請執行 synopkgland deploy --host <nas> 重新同步專案。",
|
|
591
|
+
},
|
|
592
|
+
PROJECT_BINDING_REMOVED: {
|
|
593
|
+
code: "PROJECT_BINDING_REMOVED",
|
|
594
|
+
description: "此套件的 Project Binding 已被標記為移除。",
|
|
595
|
+
suggestion: "請執行 synopkgland deploy --host <nas> 重新安裝套件。",
|
|
596
|
+
},
|
|
597
|
+
PROJECT_BINDING_UNKNOWN: {
|
|
598
|
+
code: "PROJECT_BINDING_UNKNOWN",
|
|
599
|
+
description: "Container Manager 暫時無法取得 Project 狀態。",
|
|
600
|
+
suggestion: "請至 DSM 確認 Container Manager 服務正常運作。",
|
|
601
|
+
},
|
|
602
|
+
CLI_VERSION_DRIFT: {
|
|
603
|
+
code: "CLI_VERSION_DRIFT",
|
|
604
|
+
description: "本機 @synopackageland/cli 版本與 CI TOOLCHAIN_VERSION 不一致。",
|
|
605
|
+
suggestion: "請更新 package.json / package-lock.json 或執行 npm install @synopackageland/cli@latest。",
|
|
606
|
+
},
|
|
607
|
+
PROJECT_FILES_MISSING: {
|
|
608
|
+
code: "PROJECT_FILES_MISSING",
|
|
609
|
+
description: "專案根目錄缺少核心檔案(synology-app.yaml, compose.yaml/native.yaml, README.md, icon.png)。",
|
|
610
|
+
suggestion: "請補齊缺失的專案核心檔案。",
|
|
611
|
+
},
|
|
612
|
+
TRUSTED_APP_ENTRY_FAILED: {
|
|
613
|
+
code: "TRUSTED_APP_ENTRY_FAILED",
|
|
614
|
+
description: "Trusted App Entry HTTP 探測失敗(回傳非 200 或無法連線)。",
|
|
615
|
+
suggestion: "請檢查 Web Station 入口與容器 Web 服務是否正常監聽 adminport。",
|
|
616
|
+
},
|
|
617
|
+
TEST_HOST_FAILED: {
|
|
618
|
+
code: "TEST_HOST_FAILED",
|
|
619
|
+
description: "在 NAS 上執行 Open smoke 測試失敗(無法取得 DSM User Context)。",
|
|
620
|
+
suggestion: "請檢查 App 是否正確呼叫 requireLogin 或檢查 DSM Session 登入態。",
|
|
621
|
+
},
|
|
622
|
+
// --- Curated Release & Trust Root ---
|
|
623
|
+
CURATED_TRUST_ROOT_MISSING: {
|
|
624
|
+
code: "CURATED_TRUST_ROOT_MISSING",
|
|
625
|
+
description: "缺少 Curated Public Keyring 信任根設定。",
|
|
626
|
+
suggestion: "請設定 SYNOPKGLAND_CURATED_ATTESTATION_KEYRING 或 SYNOPKGLAND_CURATED_ATTESTATION_KEYRING_PATH。",
|
|
627
|
+
},
|
|
628
|
+
CURATED_TRUST_ROOT_INVALID: {
|
|
629
|
+
code: "CURATED_TRUST_ROOT_INVALID",
|
|
630
|
+
description: "Curated Public Keyring 格式或內容無效。",
|
|
631
|
+
suggestion: "請確認信任根為合法 JSON 且包含合規的 RS256 公鑰物件。",
|
|
632
|
+
},
|
|
633
|
+
CURATED_SIGNING_KEY_UNKNOWN: {
|
|
634
|
+
code: "CURATED_SIGNING_KEY_UNKNOWN",
|
|
635
|
+
description: "簽署金鑰的 kid 不存在於 Curated Public Keyring 中。",
|
|
636
|
+
suggestion: "請確認所使用的簽署金鑰已登錄於受信任的 Keyring 信任根。",
|
|
637
|
+
},
|
|
638
|
+
CURATED_SIGNING_KEY_REVOKED: {
|
|
639
|
+
code: "CURATED_SIGNING_KEY_REVOKED",
|
|
640
|
+
description: "簽署金鑰已被標記為撤銷 (revoked)。",
|
|
641
|
+
suggestion: "請更換為有效且處於 active 狀態的簽署金鑰。",
|
|
642
|
+
},
|
|
643
|
+
CURATED_SIGNING_KEY_NOT_ACTIVE: {
|
|
644
|
+
code: "CURATED_SIGNING_KEY_NOT_ACTIVE",
|
|
645
|
+
description: "簽署金鑰非 active 狀態(可能為 verify-only)。",
|
|
646
|
+
suggestion: "請使用具備簽章權限的 active 簽署金鑰。",
|
|
647
|
+
},
|
|
648
|
+
CURATED_SIGNING_KEY_MISMATCH: {
|
|
649
|
+
code: "CURATED_SIGNING_KEY_MISMATCH",
|
|
650
|
+
description: "私鑰對應的公鑰內容與 Keyring 中登錄的公鑰不符。",
|
|
651
|
+
suggestion: "請檢查簽署金鑰與 Keyring 憑證是否匹配。",
|
|
652
|
+
},
|
|
653
|
+
CURATED_SIGNING_MATERIAL_MISSING: {
|
|
654
|
+
code: "CURATED_SIGNING_MATERIAL_MISSING",
|
|
655
|
+
description: "缺少 Curated 簽署私鑰環境變數。",
|
|
656
|
+
suggestion: "請設定 SYNOPKGLAND_CURATED_ATTESTATION_PRIVATE_JWK 或 PRIVATE_PKCS8。",
|
|
657
|
+
},
|
|
658
|
+
CURATED_SIGNING_MATERIAL_AMBIGUOUS: {
|
|
659
|
+
code: "CURATED_SIGNING_MATERIAL_AMBIGUOUS",
|
|
660
|
+
description: "同時設定了 JWK 與 PKCS8 私鑰環境變數,來源衝突。",
|
|
661
|
+
suggestion: "請僅保留 SYNOPKGLAND_CURATED_ATTESTATION_PRIVATE_JWK 或 PRIVATE_PKCS8 其中之一。",
|
|
662
|
+
},
|
|
663
|
+
CURATED_SIGNING_MATERIAL_INVALID: {
|
|
664
|
+
code: "CURATED_SIGNING_MATERIAL_INVALID",
|
|
665
|
+
description: "提供的簽署私鑰格式無效或無法匯入。",
|
|
666
|
+
suggestion: "請確認私鑰為合法未加密的 RS256 RSA 私鑰。",
|
|
667
|
+
},
|
|
668
|
+
CURATED_RELEASE_SIGNER_MISSING: {
|
|
669
|
+
code: "CURATED_RELEASE_SIGNER_MISSING",
|
|
670
|
+
description: "發布流程中未提供 Attestation 簽章器。",
|
|
671
|
+
suggestion: "請確認 CI 權限與 release custody 金鑰已正確注入。",
|
|
672
|
+
},
|
|
673
|
+
CURATED_RELEASE_FAILED: {
|
|
674
|
+
code: "CURATED_RELEASE_FAILED",
|
|
675
|
+
description: "Curated Release 發布流程失敗。",
|
|
676
|
+
suggestion: "請檢查 release CI 日誌以定位失敗步驟。",
|
|
677
|
+
},
|
|
678
|
+
CURATED_APP_NOT_FOUND: {
|
|
679
|
+
code: "CURATED_APP_NOT_FOUND",
|
|
680
|
+
description: "在 Community Apps 目錄中找不到目標 App。",
|
|
681
|
+
suggestion: "請確認 synopkgland-community-apps/apps/<package> 目錄存在。",
|
|
682
|
+
},
|
|
683
|
+
CURATED_APP_VERSION_REQUIRED: {
|
|
684
|
+
code: "CURATED_APP_VERSION_REQUIRED",
|
|
685
|
+
description: "發布時合約必須宣告 version 版本號。",
|
|
686
|
+
suggestion: "請在 synology-app.yaml 設定合法的 version(例如 1.0.0)。",
|
|
687
|
+
},
|
|
688
|
+
CURATED_BUILD_INVALID: {
|
|
689
|
+
code: "CURATED_BUILD_INVALID",
|
|
690
|
+
description: "Package Build 號碼格式無效(必須為四位數字)。",
|
|
691
|
+
suggestion: "請確保 build 號碼為四位數字字串(例如 0001)。",
|
|
692
|
+
},
|
|
693
|
+
CURATED_BUILD_MUST_NOT_BE_IN_SOURCE_VERSION: {
|
|
694
|
+
code: "CURATED_BUILD_MUST_NOT_BE_IN_SOURCE_VERSION",
|
|
695
|
+
description: "合約中的 version 不得包含 -build 後綴(Build 由 CI Ledger 分配)。",
|
|
696
|
+
suggestion: "請將 synology-app.yaml 的 version 改為純語意化版本(例如 1.0.0,不含 -0001)。",
|
|
697
|
+
},
|
|
698
|
+
CURATED_PACKAGE_IDENTITY_REQUIRED: {
|
|
699
|
+
code: "CURATED_PACKAGE_IDENTITY_REQUIRED",
|
|
700
|
+
description: "合約中缺少 package 識別碼宣告。",
|
|
701
|
+
suggestion: "請在 synology-app.yaml 設定 package 欄位。",
|
|
702
|
+
},
|
|
703
|
+
CURATED_DEVELOPMENT_IDENTITY_FORBIDDEN: {
|
|
704
|
+
code: "CURATED_DEVELOPMENT_IDENTITY_FORBIDDEN",
|
|
705
|
+
description: "Curated 上架發布嚴禁使用 .dev 開發後綴識別碼。",
|
|
706
|
+
suggestion: "請移除 package 名稱末尾的 .dev 後綴。",
|
|
707
|
+
},
|
|
708
|
+
CURATED_PACKAGE_DIRECTORY_MISMATCH: {
|
|
709
|
+
code: "CURATED_PACKAGE_DIRECTORY_MISMATCH",
|
|
710
|
+
description: "Community Apps 目錄名稱與 synology-app.yaml 中的 package 名稱不一致。",
|
|
711
|
+
suggestion: "請將 app 目錄重新命名為 apps/<package>。",
|
|
712
|
+
},
|
|
713
|
+
CURATED_VALIDATION_FAILED: {
|
|
714
|
+
code: "CURATED_VALIDATION_FAILED",
|
|
715
|
+
description: "專案未通過 Curated listing profile 嚴格驗證門檻。",
|
|
716
|
+
suggestion: "請執行 synopkgland validate 排除錯誤後再進行 release。",
|
|
717
|
+
},
|
|
718
|
+
CURATED_NATIVE_MISSING: {
|
|
719
|
+
code: "CURATED_NATIVE_MISSING",
|
|
720
|
+
description: "原生 App 發布時找不到 native.yaml 定義檔。",
|
|
721
|
+
suggestion: "請在專案根目錄補上 native.yaml。",
|
|
722
|
+
},
|
|
723
|
+
CURATED_NATIVE_TARGETS_EMPTY: {
|
|
724
|
+
code: "CURATED_NATIVE_TARGETS_EMPTY",
|
|
725
|
+
description: "原生 App 發布時 targets 不可為空。",
|
|
726
|
+
suggestion: "請在 native.yaml targets 至少定義一個架構目標。",
|
|
727
|
+
},
|
|
728
|
+
CURATED_COMPOSE_MISSING: {
|
|
729
|
+
code: "CURATED_COMPOSE_MISSING",
|
|
730
|
+
description: "容器 App 發布時找不到 compose.yaml 定義檔。",
|
|
731
|
+
suggestion: "請在專案根目錄補上 compose.yaml。",
|
|
732
|
+
},
|
|
733
|
+
CURATED_COMPOSE_GATE_FAILED: {
|
|
734
|
+
code: "CURATED_COMPOSE_GATE_FAILED",
|
|
735
|
+
description: "Compose 未通過 Curated CI 嚴格門檻(如映像檔必須帶 immutable sha256 digest)。",
|
|
736
|
+
suggestion: "請在 compose.yaml 使用固定 digest 的公開 OCI 映像檔(image@sha256:...),並移除 build 區塊。",
|
|
737
|
+
},
|
|
738
|
+
CURATED_COMPOSE_BUILD_FORBIDDEN: {
|
|
739
|
+
code: "CURATED_COMPOSE_BUILD_FORBIDDEN",
|
|
740
|
+
description: "Curated 發布禁止使用 compose build: 區塊。",
|
|
741
|
+
suggestion: "請移除 compose.yaml 中的 build: 區塊,並指定已發布至公開 registry 的 image。",
|
|
742
|
+
},
|
|
743
|
+
CURATED_COMPOSE_IMAGE_REQUIRED: {
|
|
744
|
+
code: "CURATED_COMPOSE_IMAGE_REQUIRED",
|
|
745
|
+
description: "Curated 服務必須宣告 image 映像檔名稱。",
|
|
746
|
+
suggestion: "請在 compose.yaml 的 service 中宣告 image: 欄位。",
|
|
747
|
+
},
|
|
748
|
+
CURATED_COMPOSE_IMAGE_DIGEST_REQUIRED: {
|
|
749
|
+
code: "CURATED_COMPOSE_IMAGE_DIGEST_REQUIRED",
|
|
750
|
+
description: "Curated 映像檔必須使用不可變的 @sha256: 摘要鎖定。",
|
|
751
|
+
suggestion: "請在 image 加上不可變的 SHA-256 Digest(例如 image: redis@sha256:...)。",
|
|
752
|
+
},
|
|
753
|
+
CURATED_COMPOSE_SERVICES_REQUIRED: {
|
|
754
|
+
code: "CURATED_COMPOSE_SERVICES_REQUIRED",
|
|
755
|
+
description: "compose.yaml 缺少 services 區塊或服務為空。",
|
|
756
|
+
suggestion: "請在 compose.yaml 至少定義一個容器服務。",
|
|
757
|
+
},
|
|
758
|
+
CURATED_BUNDLE_FILE_MISSING: {
|
|
759
|
+
code: "CURATED_BUNDLE_FILE_MISSING",
|
|
760
|
+
description: "打包 Curated Release 時缺少必要的 Bundle 檔案。",
|
|
761
|
+
suggestion: "請確認專案根目錄包含完整的 synology-app.yaml 與 compose.yaml/native.yaml。",
|
|
762
|
+
},
|
|
763
|
+
CURATED_ATTESTATION_BINDING_FAILED: {
|
|
764
|
+
code: "CURATED_ATTESTATION_BINDING_FAILED",
|
|
765
|
+
description: "Curated Attestation Token 簽署或綁定聲明失敗。",
|
|
766
|
+
suggestion: "請檢查 signing keys 與 claims 內容。",
|
|
767
|
+
},
|
|
768
|
+
CURATED_ATTESTATION_SIGNATURE_INVALID: {
|
|
769
|
+
code: "CURATED_ATTESTATION_SIGNATURE_INVALID",
|
|
770
|
+
description: "Curated Attestation JWT 簽章無效。",
|
|
771
|
+
suggestion: "請確認簽署私鑰與公開信任根 Keyring 一致。",
|
|
772
|
+
},
|
|
773
|
+
CURATED_BUILD_FAILED: {
|
|
774
|
+
code: "CURATED_BUILD_FAILED",
|
|
775
|
+
description: "建置 Curated SPK 失敗。",
|
|
776
|
+
suggestion: "請檢查建置日誌以排除檔案或權限錯誤。",
|
|
777
|
+
},
|
|
778
|
+
CURATED_RELEASE_ATTESTATION_BINDING_FAILED: {
|
|
779
|
+
code: "CURATED_RELEASE_ATTESTATION_BINDING_FAILED",
|
|
780
|
+
description: "Detached Release Attestation 綁定 SPK 雜湊失敗。",
|
|
781
|
+
suggestion: "請確保產出的 SPK 位元組雜湊與簽署聲明一致。",
|
|
782
|
+
},
|
|
783
|
+
CURATED_EMBEDDED_ATTESTATION_MISSING: {
|
|
784
|
+
code: "CURATED_EMBEDDED_ATTESTATION_MISSING",
|
|
785
|
+
description: "已建置的 Curated SPK 內缺少嵌入的 Attestation Token。",
|
|
786
|
+
suggestion: "請檢查 build-spk 是否正確將 token 寫入 package/.synopkgland/token。",
|
|
787
|
+
},
|
|
788
|
+
CURATED_EMBEDDED_ATTESTATION_BINDING_FAILED: {
|
|
789
|
+
code: "CURATED_EMBEDDED_ATTESTATION_BINDING_FAILED",
|
|
790
|
+
description: "SPK 內嵌入的 Attestation 與 Release Claims 聲明不符。",
|
|
791
|
+
suggestion: "請確認嵌入式 Token 的 Digest 與 Claims 一致。",
|
|
792
|
+
},
|
|
793
|
+
// --- Publish & Preflight ---
|
|
794
|
+
PREFLIGHT_FAILED: {
|
|
795
|
+
code: "PREFLIGHT_FAILED",
|
|
796
|
+
description: "送審公開發布前置檢查未通過。",
|
|
797
|
+
suggestion: "請先修正 preflight 列出的錯誤後再重新送審。",
|
|
798
|
+
},
|
|
799
|
+
COMMUNITY_APPS_ROOT_MISSING: {
|
|
800
|
+
code: "COMMUNITY_APPS_ROOT_MISSING",
|
|
801
|
+
description: "找不到 synopkgland-community-apps 本機副本。",
|
|
802
|
+
suggestion: "請 clone synopkgland-community-apps 並設定 SYNOPKGLAND_COMMUNITY_APPS_ROOT 環境變數。",
|
|
803
|
+
},
|
|
804
|
+
PACKAGE_IDENTITY_MISSING: {
|
|
805
|
+
code: "PACKAGE_IDENTITY_MISSING",
|
|
806
|
+
description: "專案 synology-app.yaml 中缺少 package 欄位。",
|
|
807
|
+
suggestion: "請在 synology-app.yaml 補上 package 宣告。",
|
|
808
|
+
},
|
|
809
|
+
PACKAGE_DIRECTORY_MISMATCH: {
|
|
810
|
+
code: "PACKAGE_DIRECTORY_MISMATCH",
|
|
811
|
+
description: "專案目錄或 Community Apps 子目錄與 package 名稱不一致。",
|
|
812
|
+
suggestion: "請確保專案目錄名稱與 package 宣告一致。",
|
|
813
|
+
},
|
|
814
|
+
PUBLISH_SOURCE_IS_COMMUNITY_APP: {
|
|
815
|
+
code: "PUBLISH_SOURCE_IS_COMMUNITY_APP",
|
|
816
|
+
description: "publish 指令不可在 synopkgland-community-apps/apps 目錄內直接執行。",
|
|
817
|
+
suggestion: "請在您的獨立 App 開發專案目錄中執行 public-release-submit。",
|
|
818
|
+
},
|
|
819
|
+
PUBLISH_PR_FAILED: {
|
|
820
|
+
code: "PUBLISH_PR_FAILED",
|
|
821
|
+
description: "透過 GitHub CLI 建立 Pull Request 失敗。",
|
|
822
|
+
suggestion: "請確認 gh 已登入 (gh auth login) 或已設定 GITHUB_TOKEN。",
|
|
823
|
+
},
|
|
824
|
+
};
|
|
825
|
+
export function getErrorCode(code) {
|
|
826
|
+
return ERROR_REGISTRY[code];
|
|
827
|
+
}
|