@synopackageland/cli 0.3.10 → 0.4.1
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/LICENSE +21 -0
- package/README.md +57 -9
- package/dist/bin.js +1 -2
- package/dist/build-spk/generator.d.ts +0 -3
- package/dist/build-spk/generator.js +138 -287
- package/dist/build-spk/native-lifecycle.js +0 -3
- package/dist/build-spk/native-payload.js +0 -1
- package/dist/build-spk/notices.d.ts +5 -0
- package/dist/build-spk/notices.js +60 -0
- package/dist/cli.js +178 -151
- package/dist/compose/analyze.d.ts +1 -2
- package/dist/compose/analyze.js +5 -48
- package/dist/contract/unsupported-types.d.ts +10 -0
- package/dist/contract/unsupported-types.js +49 -0
- package/dist/contract/validate.js +25 -2
- package/dist/contract/web-launch.js +0 -2
- package/dist/deploy/deploy.d.ts +1 -4
- package/dist/deploy/deploy.js +45 -156
- package/dist/deploy/homes-values.js +1 -1
- package/dist/deploy/plan.d.ts +18 -0
- package/dist/deploy/plan.js +54 -0
- package/dist/deploy/spk-version.d.ts +2 -14
- package/dist/deploy/spk-version.js +25 -111
- package/dist/dev.d.ts +1 -3
- package/dist/dev.js +14 -28
- package/dist/error-registry.js +830 -862
- package/dist/host/dsm-client.js +12 -272
- package/dist/host/dsm-port-profile.d.ts +0 -1
- package/dist/host/dsm-port-profile.js +0 -2
- package/dist/host/types.d.ts +1 -83
- package/dist/index.d.ts +0 -9
- package/dist/index.js +0 -6
- package/dist/info.d.ts +0 -1
- package/dist/info.js +3 -10
- package/dist/init.d.ts +15 -1
- package/dist/init.js +128 -12
- package/dist/log.js +2 -3
- package/dist/native/validate.js +0 -1
- package/dist/standalone/binary.d.ts +9 -0
- package/dist/standalone/binary.js +67 -0
- package/dist/standalone/build.d.ts +25 -0
- package/dist/standalone/build.js +110 -0
- package/dist/standalone/daemon.d.ts +23 -0
- package/dist/standalone/daemon.js +114 -0
- package/dist/standalone/dsm-window.d.ts +26 -0
- package/dist/standalone/dsm-window.js +291 -0
- package/dist/standalone/helper-inventory.d.ts +16 -0
- package/dist/standalone/helper-inventory.js +2 -0
- package/dist/standalone/helper.d.ts +21 -0
- package/dist/standalone/helper.js +105 -0
- package/dist/standalone/host-adapter.d.ts +5 -0
- package/dist/standalone/host-adapter.js +148 -0
- package/dist/standalone/host-platform.d.ts +13 -0
- package/dist/standalone/host-platform.js +42 -0
- package/dist/standalone/host-types.d.ts +49 -0
- package/dist/standalone/host-types.js +1 -0
- package/dist/standalone/i18n.d.ts +28 -0
- package/dist/standalone/i18n.js +161 -0
- package/dist/standalone/inspect-helper.d.ts +6 -0
- package/dist/standalone/inspect-helper.js +88 -0
- package/dist/standalone/inspect-spk.d.ts +23 -0
- package/dist/standalone/inspect-spk.js +209 -0
- package/dist/standalone/lifecycle-helper.d.ts +2 -0
- package/dist/standalone/lifecycle-helper.js +12 -0
- package/dist/standalone/lifecycle.d.ts +3 -0
- package/dist/standalone/lifecycle.js +53 -0
- package/dist/standalone/manifest.d.ts +73 -0
- package/dist/standalone/manifest.js +279 -0
- package/dist/standalone/reopen-events.d.ts +2 -0
- package/dist/standalone/reopen-events.js +28 -0
- package/dist/standalone/root-messages.d.ts +7 -0
- package/dist/standalone/root-messages.js +259 -0
- package/dist/standalone/root-ops.d.ts +42 -0
- package/dist/standalone/root-ops.js +101 -0
- package/dist/standalone/root-window.d.ts +36 -0
- package/dist/standalone/root-window.js +302 -0
- package/dist/standalone/spk.d.ts +23 -0
- package/dist/standalone/spk.js +192 -0
- package/dist/template-paths.d.ts +2 -0
- package/dist/template-paths.js +9 -0
- package/dist/templates/_daemon/fixture_linux_test.go +15 -0
- package/dist/templates/_daemon/fixture_other_test.go +7 -0
- package/dist/templates/_daemon/go.mod +3 -0
- package/dist/templates/_daemon/main.go +608 -0
- package/dist/templates/_daemon/main_test.go +242 -0
- package/dist/templates/_daemon/process_linux.go +55 -0
- package/dist/templates/_daemon/process_linux_test.go +161 -0
- package/dist/templates/_daemon/process_other.go +14 -0
- package/dist/templates/_daemon/testdata/child.go +41 -0
- package/dist/templates/_shared/GO-LICENSE +27 -0
- package/dist/templates/_shared/GO-PATENTS +22 -0
- package/dist/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
- package/dist/templates/_shared/notice-overrides/index.json +14 -0
- package/dist/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
- package/dist/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
- package/dist/templates/_shared/third-party-notices.mjs +51 -0
- package/dist/templates/binary/synology-app.yaml +7 -0
- package/dist/templates/hello-files/compose.yaml +0 -1
- package/dist/templates/hello-web/compose.yaml +13 -10
- package/dist/templates/hello-web/html/app.js +1 -23
- package/dist/templates/hello-web/html/index.html +1 -3
- package/dist/templates/hello-web-page/compose.yaml +13 -10
- package/dist/templates/hello-web-page/html/app.js +1 -23
- package/dist/templates/hello-web-page/html/index.html +1 -3
- package/dist/templates/native-go/README.md +324 -0
- package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
- package/dist/templates/native-go/backend/cmd/app/main.go +49 -0
- package/dist/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
- package/dist/templates/native-go/backend/cmd/helper/main.go +38 -0
- package/dist/templates/native-go/backend/go.mod +7 -0
- package/dist/templates/native-go/backend/go.sum +4 -0
- package/dist/templates/native-go/backend/internal/api/binary.go +154 -0
- package/dist/templates/native-go/backend/internal/api/binary_test.go +165 -0
- package/dist/templates/native-go/backend/internal/api/errors.go +33 -0
- package/dist/templates/native-go/backend/internal/api/registry.go +104 -0
- package/dist/templates/native-go/backend/internal/api/registry_test.go +329 -0
- package/dist/templates/native-go/backend/internal/api/server.go +159 -0
- package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
- package/dist/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
- package/dist/templates/native-go/backend/internal/app/root_none.go +9 -0
- package/dist/templates/native-go/backend/internal/app/routes.go +138 -0
- package/dist/templates/native-go/backend/internal/app/routes_test.go +172 -0
- package/dist/templates/native-go/backend/internal/dsm/auth.go +118 -0
- package/dist/templates/native-go/backend/internal/dsm/auth_test.go +139 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
- package/dist/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
- package/dist/templates/native-go/backend/internal/helper/cohort.go +393 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
- package/dist/templates/native-go/backend/internal/helper/control.go +424 -0
- package/dist/templates/native-go/backend/internal/helper/control_test.go +250 -0
- package/dist/templates/native-go/backend/internal/helper/data_contract.go +242 -0
- package/dist/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/data_decode.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
- package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
- package/dist/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
- package/dist/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
- package/dist/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
- package/dist/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
- package/dist/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
- package/dist/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
- package/dist/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
- package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
- package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
- package/dist/templates/native-go/backend/internal/helper/lease.go +112 -0
- package/dist/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
- package/dist/templates/native-go/backend/internal/helper/lease_other.go +8 -0
- package/dist/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
- package/dist/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
- package/dist/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
- package/dist/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
- package/dist/templates/native-go/backend/internal/helper/native_identity.go +89 -0
- package/dist/templates/native-go/backend/internal/helper/native_provider.go +159 -0
- package/dist/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
- package/dist/templates/native-go/backend/internal/helper/observation.go +204 -0
- package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
- package/dist/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
- package/dist/templates/native-go/backend/internal/helper/observation_test.go +196 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
- package/dist/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
- package/dist/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
- package/dist/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
- package/dist/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
- package/dist/templates/native-go/backend/internal/helper/peer_linux.go +44 -0
- package/dist/templates/native-go/backend/internal/helper/peer_other.go +7 -0
- package/dist/templates/native-go/backend/internal/helper/process_linux.go +177 -0
- package/dist/templates/native-go/backend/internal/helper/process_other.go +5 -0
- package/dist/templates/native-go/backend/internal/helper/publication_test.go +178 -0
- package/dist/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
- package/dist/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
- package/dist/templates/native-go/backend/internal/helper/readonly.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
- package/dist/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
- package/dist/templates/native-go/backend/internal/helper/repair.go +132 -0
- package/dist/templates/native-go/backend/internal/helper/repair_test.go +271 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
- package/dist/templates/native-go/backend/internal/helper/server_linux.go +124 -0
- package/dist/templates/native-go/backend/internal/helper/status.go +334 -0
- package/dist/templates/native-go/backend/internal/helper/status_test.go +288 -0
- package/dist/templates/native-go/backend/internal/helper/supervision.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/supervision_test.go +124 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +363 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_linux_test.go +913 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
- package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
- package/dist/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
- package/dist/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
- package/dist/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
- package/dist/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
- package/dist/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
- package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
- package/dist/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
- package/dist/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
- package/dist/templates/native-go/backend/internal/helper/write.go +77 -0
- package/dist/templates/native-go/backend/internal/helper/write_admission.go +260 -0
- package/dist/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
- package/dist/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
- package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
- package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
- package/dist/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
- package/dist/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
- package/dist/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
- package/dist/templates/native-go/backend/internal/helper/write_test.go +53 -0
- package/dist/templates/native-go/dsm-package.yaml +58 -0
- package/dist/templates/native-go/gitignore +1 -0
- package/dist/templates/native-go/i18n/glossary.json +662 -0
- package/dist/templates/native-go/i18n/messages/de.json +28 -0
- package/dist/templates/native-go/i18n/messages/en.json +28 -0
- package/dist/templates/native-go/i18n/messages/es.json +28 -0
- package/dist/templates/native-go/i18n/messages/fr.json +28 -0
- package/dist/templates/native-go/i18n/messages/it.json +28 -0
- package/dist/templates/native-go/i18n/messages/ja.json +28 -0
- package/dist/templates/native-go/i18n/messages/ko.json +28 -0
- package/dist/templates/native-go/i18n/messages/zh-CN.json +28 -0
- package/dist/templates/native-go/i18n/messages/zh-TW.json +28 -0
- package/dist/templates/native-go/ui/app.css +35 -0
- package/dist/templates/native-go/ui/app.js +101 -0
- package/dist/templates/native-go-better-auth/backend/internal/app/identity.go +208 -0
- package/dist/templates/native-go-better-auth/backend/internal/app/identity_test.go +113 -0
- package/dist/templates/native-go-better-auth/node/app.mjs +72 -0
- package/dist/templates/native-go-better-auth/node/build.mjs +4 -0
- package/dist/templates/native-go-better-auth/node/package-lock.json +862 -0
- package/dist/templates/native-go-better-auth/node/package.json +1 -0
- package/dist/templates/native-go-better-auth/node/test/auth.test.mjs +31 -0
- package/dist/templates/native-go-integration/backend/internal/app/identity_none.go +6 -0
- package/dist/templates/native-go-integration/backend/internal/app/personal.go +203 -0
- package/dist/templates/native-go-integration/backend/internal/app/personal_test.go +119 -0
- package/dist/templates/native-go-root/backend/internal/app/root.go +107 -0
- package/dist/templates/native-go-root/backend/internal/app/root_test.go +124 -0
- package/dist/templates/native-go-root/root/whoami.sh +6 -0
- package/dist/templates/native-go-vue/README.md +224 -0
- package/dist/templates/native-go-vue/frontend/DESIGN.md +78 -0
- package/dist/templates/native-go-vue/frontend/package-lock.json +2410 -0
- package/dist/templates/native-go-vue/frontend/package.json +6 -0
- package/dist/templates/native-go-vue/frontend/src/App.vue +159 -0
- package/dist/templates/native-go-vue/frontend/src/context.ts +56 -0
- package/dist/templates/native-go-vue/frontend/src/main.ts +29 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
- package/dist/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
- package/dist/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
- package/dist/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
- package/dist/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
- package/dist/templates/native-go-vue/frontend/src/style.css +31 -0
- package/dist/templates/native-go-vue/frontend/test/apps.test.ts +190 -0
- package/dist/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
- package/dist/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
- package/dist/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
- package/dist/templates/native-go-vue/frontend/tsconfig.json +1 -0
- package/dist/templates/native-go-vue/frontend/vite.config.ts +10 -0
- package/dist/templates/native-go-vue/gitignore +2 -0
- package/dist/types.d.ts +1 -1
- package/dist/validate.js +11 -7
- package/package.json +5 -8
- package/schema/synology-app.schema.json +36 -37
- package/skills/SKILL.md +4 -48
- package/skills/reference/create.md +11 -83
- package/skills/reference/deploy.md +7 -78
- package/skills/reference/diagnose.md +4 -101
- package/skills/reference/files.md +5 -41
- package/skills/reference/identity.md +3 -29
- package/skills/reference/wrap.md +0 -2
- package/templates/_daemon/fixture_linux_test.go +15 -0
- package/templates/_daemon/fixture_other_test.go +7 -0
- package/templates/_daemon/go.mod +3 -0
- package/templates/_daemon/main.go +608 -0
- package/templates/_daemon/main_test.go +242 -0
- package/templates/_daemon/process_linux.go +55 -0
- package/templates/_daemon/process_linux_test.go +161 -0
- package/templates/_daemon/process_other.go +14 -0
- package/templates/_daemon/testdata/child.go +41 -0
- package/templates/_shared/GO-LICENSE +27 -0
- package/templates/_shared/GO-PATENTS +22 -0
- package/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
- package/templates/_shared/notice-overrides/index.json +14 -0
- package/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
- package/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
- package/templates/_shared/third-party-notices.mjs +51 -0
- package/templates/binary/synology-app.yaml +7 -0
- package/templates/hello-files/compose.yaml +0 -1
- package/templates/hello-web/compose.yaml +13 -10
- package/templates/hello-web/html/app.js +1 -23
- package/templates/hello-web/html/index.html +1 -3
- package/templates/hello-web-page/compose.yaml +13 -10
- package/templates/hello-web-page/html/app.js +1 -23
- package/templates/hello-web-page/html/index.html +1 -3
- package/templates/native-go/README.md +324 -0
- package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
- package/templates/native-go/backend/cmd/app/main.go +49 -0
- package/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
- package/templates/native-go/backend/cmd/helper/main.go +38 -0
- package/templates/native-go/backend/go.mod +7 -0
- package/templates/native-go/backend/go.sum +4 -0
- package/templates/native-go/backend/internal/api/binary.go +154 -0
- package/templates/native-go/backend/internal/api/binary_test.go +165 -0
- package/templates/native-go/backend/internal/api/errors.go +33 -0
- package/templates/native-go/backend/internal/api/registry.go +104 -0
- package/templates/native-go/backend/internal/api/registry_test.go +329 -0
- package/templates/native-go/backend/internal/api/server.go +159 -0
- package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
- package/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
- package/templates/native-go/backend/internal/app/root_none.go +9 -0
- package/templates/native-go/backend/internal/app/routes.go +138 -0
- package/templates/native-go/backend/internal/app/routes_test.go +172 -0
- package/templates/native-go/backend/internal/dsm/auth.go +118 -0
- package/templates/native-go/backend/internal/dsm/auth_test.go +139 -0
- package/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
- package/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
- package/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
- package/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
- package/templates/native-go/backend/internal/helper/cohort.go +393 -0
- package/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
- package/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
- package/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
- package/templates/native-go/backend/internal/helper/control.go +424 -0
- package/templates/native-go/backend/internal/helper/control_test.go +250 -0
- package/templates/native-go/backend/internal/helper/data_contract.go +242 -0
- package/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
- package/templates/native-go/backend/internal/helper/data_decode.go +184 -0
- package/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
- package/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
- package/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
- package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
- package/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
- package/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
- package/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
- package/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
- package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
- package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
- package/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
- package/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
- package/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
- package/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
- package/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
- package/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
- package/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
- package/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
- package/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
- package/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
- package/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
- package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
- package/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
- package/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
- package/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
- package/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
- package/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
- package/templates/native-go/backend/internal/helper/lease.go +112 -0
- package/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
- package/templates/native-go/backend/internal/helper/lease_other.go +8 -0
- package/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
- package/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
- package/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
- package/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
- package/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
- package/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
- package/templates/native-go/backend/internal/helper/native_identity.go +89 -0
- package/templates/native-go/backend/internal/helper/native_provider.go +159 -0
- package/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
- package/templates/native-go/backend/internal/helper/observation.go +204 -0
- package/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
- package/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
- package/templates/native-go/backend/internal/helper/observation_test.go +196 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
- package/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
- package/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
- package/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
- package/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
- package/templates/native-go/backend/internal/helper/peer_linux.go +44 -0
- package/templates/native-go/backend/internal/helper/peer_other.go +7 -0
- package/templates/native-go/backend/internal/helper/process_linux.go +177 -0
- package/templates/native-go/backend/internal/helper/process_other.go +5 -0
- package/templates/native-go/backend/internal/helper/publication_test.go +178 -0
- package/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
- package/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
- package/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
- package/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
- package/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
- package/templates/native-go/backend/internal/helper/readonly.go +105 -0
- package/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
- package/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
- package/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
- package/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
- package/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
- package/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
- package/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
- package/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
- package/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
- package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
- package/templates/native-go/backend/internal/helper/repair.go +132 -0
- package/templates/native-go/backend/internal/helper/repair_test.go +271 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
- package/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
- package/templates/native-go/backend/internal/helper/server_linux.go +124 -0
- package/templates/native-go/backend/internal/helper/status.go +334 -0
- package/templates/native-go/backend/internal/helper/status_test.go +288 -0
- package/templates/native-go/backend/internal/helper/supervision.go +107 -0
- package/templates/native-go/backend/internal/helper/supervision_test.go +124 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
- package/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
- package/templates/native-go/backend/internal/helper/supervisor_linux.go +363 -0
- package/templates/native-go/backend/internal/helper/supervisor_linux_test.go +913 -0
- package/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
- package/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
- package/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
- package/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
- package/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
- package/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
- package/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
- package/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
- package/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
- package/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
- package/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
- package/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
- package/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
- package/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
- package/templates/native-go/backend/internal/helper/write.go +77 -0
- package/templates/native-go/backend/internal/helper/write_admission.go +260 -0
- package/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
- package/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
- package/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
- package/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
- package/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
- package/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
- package/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
- package/templates/native-go/backend/internal/helper/write_test.go +53 -0
- package/templates/native-go/dsm-package.yaml +58 -0
- package/templates/native-go/gitignore +1 -0
- package/templates/native-go/i18n/glossary.json +662 -0
- package/templates/native-go/i18n/messages/de.json +28 -0
- package/templates/native-go/i18n/messages/en.json +28 -0
- package/templates/native-go/i18n/messages/es.json +28 -0
- package/templates/native-go/i18n/messages/fr.json +28 -0
- package/templates/native-go/i18n/messages/it.json +28 -0
- package/templates/native-go/i18n/messages/ja.json +28 -0
- package/templates/native-go/i18n/messages/ko.json +28 -0
- package/templates/native-go/i18n/messages/zh-CN.json +28 -0
- package/templates/native-go/i18n/messages/zh-TW.json +28 -0
- package/templates/native-go/ui/app.css +35 -0
- package/templates/native-go/ui/app.js +101 -0
- package/templates/native-go-better-auth/backend/internal/app/identity.go +208 -0
- package/templates/native-go-better-auth/backend/internal/app/identity_test.go +113 -0
- package/templates/native-go-better-auth/node/app.mjs +72 -0
- package/templates/native-go-better-auth/node/build.mjs +4 -0
- package/templates/native-go-better-auth/node/package-lock.json +862 -0
- package/templates/native-go-better-auth/node/package.json +1 -0
- package/templates/native-go-better-auth/node/test/auth.test.mjs +31 -0
- package/templates/native-go-integration/backend/internal/app/identity_none.go +6 -0
- package/templates/native-go-integration/backend/internal/app/personal.go +203 -0
- package/templates/native-go-integration/backend/internal/app/personal_test.go +119 -0
- package/templates/native-go-root/backend/internal/app/root.go +107 -0
- package/templates/native-go-root/backend/internal/app/root_test.go +124 -0
- package/templates/native-go-root/root/whoami.sh +6 -0
- package/templates/native-go-vue/README.md +224 -0
- package/templates/native-go-vue/frontend/DESIGN.md +78 -0
- package/templates/native-go-vue/frontend/package-lock.json +2410 -0
- package/templates/native-go-vue/frontend/package.json +6 -0
- package/templates/native-go-vue/frontend/src/App.vue +159 -0
- package/templates/native-go-vue/frontend/src/context.ts +56 -0
- package/templates/native-go-vue/frontend/src/main.ts +29 -0
- package/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
- package/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
- package/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
- package/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
- package/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
- package/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
- package/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
- package/templates/native-go-vue/frontend/src/style.css +31 -0
- package/templates/native-go-vue/frontend/test/apps.test.ts +190 -0
- package/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
- package/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
- package/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
- package/templates/native-go-vue/frontend/tsconfig.json +1 -0
- package/templates/native-go-vue/frontend/vite.config.ts +10 -0
- package/templates/native-go-vue/gitignore +2 -0
- package/dist/attestation/app-package.d.ts +0 -86
- package/dist/attestation/app-package.js +0 -206
- package/dist/attestation/install-on-host.d.ts +0 -14
- package/dist/attestation/install-on-host.js +0 -52
- package/dist/attestation/keyring.d.ts +0 -21
- package/dist/attestation/keyring.js +0 -168
- package/dist/attestation/platform-service.d.ts +0 -70
- package/dist/attestation/platform-service.js +0 -250
- package/dist/build-spk/broker-glue.d.ts +0 -16
- package/dist/build-spk/broker-glue.js +0 -40
- package/dist/deploy/catalog-publish.d.ts +0 -3
- package/dist/deploy/catalog-publish.js +0 -7
- package/dist/doctor.d.ts +0 -22
- package/dist/doctor.js +0 -822
- package/dist/error-collector.d.ts +0 -2
- package/dist/error-collector.js +0 -46
- package/dist/host/broker-paths.d.ts +0 -1
- package/dist/host/broker-paths.js +0 -1
- package/dist/host/broker-upgrade-preflight.d.ts +0 -61
- package/dist/host/broker-upgrade-preflight.js +0 -156
- package/dist/host/digests.d.ts +0 -5
- package/dist/host/digests.js +0 -63
- package/dist/host/fake-nas.d.ts +0 -49
- package/dist/host/fake-nas.js +0 -193
- package/dist/mock-broker/bootstrap.d.ts +0 -2
- package/dist/mock-broker/bootstrap.js +0 -8
- package/dist/mock-broker/files.d.ts +0 -60
- package/dist/mock-broker/files.js +0 -408
- package/dist/mock-broker/oidc.d.ts +0 -31
- package/dist/mock-broker/oidc.js +0 -161
- package/dist/mock-broker/path.d.ts +0 -9
- package/dist/mock-broker/path.js +0 -50
- package/dist/mock-broker/server.d.ts +0 -19
- package/dist/mock-broker/server.js +0 -350
- package/dist/publish/build-ledger.d.ts +0 -22
- package/dist/publish/build-ledger.js +0 -26
- package/dist/publish/community-path.d.ts +0 -6
- package/dist/publish/community-path.js +0 -41
- package/dist/publish/curated-release.d.ts +0 -78
- package/dist/publish/curated-release.js +0 -883
- package/dist/publish/file-build-ledger.d.ts +0 -18
- package/dist/publish/file-build-ledger.js +0 -268
- package/dist/publish/github-pr.d.ts +0 -25
- package/dist/publish/github-pr.js +0 -85
- package/dist/publish/github-repo.d.ts +0 -8
- package/dist/publish/github-repo.js +0 -21
- package/dist/publish/platform-service-release.d.ts +0 -60
- package/dist/publish/platform-service-release.js +0 -333
- package/dist/publish/preflight.d.ts +0 -24
- package/dist/publish/preflight.js +0 -138
- package/dist/publish/publish.d.ts +0 -27
- package/dist/publish/publish.js +0 -136
- package/dist/publish/sync-definition.d.ts +0 -4
- package/dist/publish/sync-definition.js +0 -48
- package/dist/release-bin.d.ts +0 -2
- package/dist/release-bin.js +0 -23
- package/dist/templates/hello-web/html/sdk.js +0 -68
- package/dist/templates/hello-web-page/html/sdk.js +0 -68
- package/dist/templates/native/synology-app.yaml +0 -7
- package/dist/test-host.d.ts +0 -15
- package/dist/test-host.js +0 -37
- package/templates/hello-web/html/sdk.js +0 -68
- package/templates/hello-web-page/html/sdk.js +0 -68
- package/templates/native/synology-app.yaml +0 -7
- /package/dist/templates/{native → binary}/native.yaml +0 -0
- /package/templates/{native → binary}/native.yaml +0 -0
|
@@ -12,32 +12,19 @@ import { validateProject } from "../validate.js";
|
|
|
12
12
|
import { writeDsmWindowIcons, writePackageCenterIcons } from "./dsm-icons.js";
|
|
13
13
|
import { infoArchValue } from "./dsm-arch.js";
|
|
14
14
|
import { createReproducibleTar } from "./reproducible-archive.js";
|
|
15
|
+
import { copyProjectNotices } from "./notices.js";
|
|
15
16
|
import { renderDeleteAppDataBlock } from "./delete-app-data.js";
|
|
16
|
-
import { BROKER_INSTALLER_VARS, BROKER_SOCKET_REQUIRED_SCRIPT, renderBrokerStatusProbe, } from "./broker-glue.js";
|
|
17
17
|
import { loadNative } from "../native/load.js";
|
|
18
18
|
import { materializeNativePayload } from "./native-payload.js";
|
|
19
|
-
import { renderNativePrivilege, renderNativeStartStopStatus, renderNativePostuninst, } from "./native-lifecycle.js";
|
|
19
|
+
import { renderNativePostinst, renderNativePrivilege, renderNativeStartStopStatus, renderNativePostuninst, renderNativePreuninst, } from "./native-lifecycle.js";
|
|
20
20
|
import { renderHeadlessResourceMarker, renderResourceConfig, renderResourceWorkerStartStopStatus, } from "./resource-worker.js";
|
|
21
21
|
const FILE_MODE = 0o644;
|
|
22
22
|
const SCRIPT_MODE = 0o755;
|
|
23
|
-
function hasInterpolation(value) {
|
|
24
|
-
if (typeof value === "string") {
|
|
25
|
-
return /\$\{([^}]+)\}/.test(value);
|
|
26
|
-
}
|
|
27
|
-
if (Array.isArray(value)) {
|
|
28
|
-
return value.some(hasInterpolation);
|
|
29
|
-
}
|
|
30
|
-
if (value && typeof value === "object") {
|
|
31
|
-
return Object.values(value).some(hasInterpolation);
|
|
32
|
-
}
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
23
|
const INSTALL_UIFILE = "install_uifile";
|
|
36
24
|
const UPGRADE_UIFILE = "upgrade_uifile";
|
|
37
25
|
const UNINSTALL_UIFILE = "uninstall_uifile";
|
|
38
26
|
const HEADLESS_PROBE_VOLUME = "./.synopkgland:/run/synopkgland:ro";
|
|
39
27
|
const HEADLESS_PROBE_README = "Reserved bind target for package-user headless status probing.\n";
|
|
40
|
-
export const EMBEDDED_ATTESTATION_RELATIVE_PATH = ".synopkgland/attestation.jwt";
|
|
41
28
|
const SCRIPT_NAMES = [
|
|
42
29
|
"preinst",
|
|
43
30
|
"postinst",
|
|
@@ -48,9 +35,6 @@ const SCRIPT_NAMES = [
|
|
|
48
35
|
"start-stop-status",
|
|
49
36
|
];
|
|
50
37
|
export async function buildSpk(options) {
|
|
51
|
-
if (options.embeddedAttestationToken !== undefined && options.embeddedAttestationToken.length === 0) {
|
|
52
|
-
return { ok: false, errors: ["EMBEDDED_ATTESTATION_TOKEN_EMPTY"] };
|
|
53
|
-
}
|
|
54
38
|
const validation = validateProject(options.project);
|
|
55
39
|
if (!validation.ok) {
|
|
56
40
|
return {
|
|
@@ -123,12 +107,6 @@ export async function buildSpk(options) {
|
|
|
123
107
|
}
|
|
124
108
|
copyFileSync(options.project.contractPath, join(packageDir, "synology-app.yaml"));
|
|
125
109
|
copyFileSync(nativePath, join(packageDir, "native.yaml"));
|
|
126
|
-
if (options.embeddedAttestationToken !== undefined) {
|
|
127
|
-
const attestationPath = join(packageDir, EMBEDDED_ATTESTATION_RELATIVE_PATH);
|
|
128
|
-
mkdirSync(join(packageDir, ".synopkgland"), { recursive: true });
|
|
129
|
-
writeFileSync(attestationPath, options.embeddedAttestationToken, "utf8");
|
|
130
|
-
chmodSync(attestationPath, FILE_MODE);
|
|
131
|
-
}
|
|
132
110
|
chmodSync(join(staging, "INFO"), FILE_MODE);
|
|
133
111
|
chmodSync(join(staging, "privilege"), FILE_MODE);
|
|
134
112
|
chmodSync(join(staging, "WIZARD_UIFILES", INSTALL_UIFILE), FILE_MODE);
|
|
@@ -138,6 +116,7 @@ export async function buildSpk(options) {
|
|
|
138
116
|
chmodSync(join(packageDir, "native.yaml"), FILE_MODE);
|
|
139
117
|
const outputPath = options.outputPath ??
|
|
140
118
|
join(options.project.root, `${String(contract.package)}-${options.archFamily}.spk`);
|
|
119
|
+
copyProjectNotices(options.project.root, packageDir);
|
|
141
120
|
await createDeterministicSpk(staging, outputPath);
|
|
142
121
|
return { ok: true, outputPath, errors: [] };
|
|
143
122
|
}
|
|
@@ -152,7 +131,10 @@ export async function buildSpk(options) {
|
|
|
152
131
|
if (route && route.errors.length > 0) {
|
|
153
132
|
return { ok: false, errors: route.errors.map((error) => error.code) };
|
|
154
133
|
}
|
|
155
|
-
|
|
134
|
+
if (!route || route.route === "reject") {
|
|
135
|
+
return { ok: false, errors: ["COMPOSE_ROUTE_UNSUPPORTED"] };
|
|
136
|
+
}
|
|
137
|
+
const rwEligibility = route.eligibility;
|
|
156
138
|
const isDynamicRoute = route?.route === "dynamic";
|
|
157
139
|
const isResourceWorkerRoute = route?.route === "static-zero-config" ||
|
|
158
140
|
isDynamicRoute;
|
|
@@ -186,7 +168,7 @@ export async function buildSpk(options) {
|
|
|
186
168
|
mkdirSync(resourceProjectDir, { recursive: true });
|
|
187
169
|
const dsmUserParam = collectInstallParameters(contract).find((p) => p.param.type === "dsm_user");
|
|
188
170
|
let composeContent;
|
|
189
|
-
if (dsmUserParam || rwEligibility?.headless === true
|
|
171
|
+
if (dsmUserParam || rwEligibility?.headless === true) {
|
|
190
172
|
const rawYaml = readFileSync(options.project.composePath, "utf8");
|
|
191
173
|
const doc = parseDocument(rawYaml);
|
|
192
174
|
const services = doc.get("services");
|
|
@@ -198,28 +180,6 @@ export async function buildSpk(options) {
|
|
|
198
180
|
doc.setIn(["services", sName, "user"], userVal);
|
|
199
181
|
}
|
|
200
182
|
}
|
|
201
|
-
if (hasOidcCompat(contract) && services && typeof services === "object" && typeof services.toJSON === "function") {
|
|
202
|
-
const rawServices = services.toJSON();
|
|
203
|
-
for (const [sName, sValue] of Object.entries(rawServices)) {
|
|
204
|
-
if (sValue && typeof sValue === "object" && hasInterpolation(sValue)) {
|
|
205
|
-
const str = JSON.stringify(sValue);
|
|
206
|
-
if (str.includes("SYNOPKGLAND_OIDC_ISSUER")) {
|
|
207
|
-
const serviceDoc = doc.getIn(["services", sName]);
|
|
208
|
-
const existingExtraHosts = serviceDoc?.get?.("extra_hosts");
|
|
209
|
-
const hostGatewayMapping = "${SYNOPKGLAND_OIDC_ISSUER_HOST}:host-gateway";
|
|
210
|
-
if (!existingExtraHosts) {
|
|
211
|
-
doc.setIn(["services", sName, "extra_hosts"], [hostGatewayMapping]);
|
|
212
|
-
}
|
|
213
|
-
else if (Array.isArray(existingExtraHosts.toJSON?.())) {
|
|
214
|
-
const arr = existingExtraHosts.toJSON();
|
|
215
|
-
if (!arr.includes(hostGatewayMapping)) {
|
|
216
|
-
doc.setIn(["services", sName, "extra_hosts"], [...arr, hostGatewayMapping]);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
183
|
if (rwEligibility?.headless === true) {
|
|
224
184
|
injectHeadlessProbeVolume(doc);
|
|
225
185
|
}
|
|
@@ -241,11 +201,6 @@ export async function buildSpk(options) {
|
|
|
241
201
|
writeFileSync(join(probePayloadDir, "README"), HEADLESS_PROBE_README, "utf8");
|
|
242
202
|
chmodSync(join(probePayloadDir, "README"), FILE_MODE);
|
|
243
203
|
}
|
|
244
|
-
const routeMarkerDir = join(staging, "package", ".synopkgland");
|
|
245
|
-
mkdirSync(routeMarkerDir, { recursive: true });
|
|
246
|
-
const routeMarker = join(routeMarkerDir, "route");
|
|
247
|
-
writeFileSync(routeMarker, "package-only", "utf8");
|
|
248
|
-
chmodSync(routeMarker, FILE_MODE);
|
|
249
204
|
}
|
|
250
205
|
const htmlDir = join(options.project.root, "html");
|
|
251
206
|
if (existsSync(htmlDir)) {
|
|
@@ -254,12 +209,6 @@ export async function buildSpk(options) {
|
|
|
254
209
|
cpSync(htmlDir, join(staging, "package", "compose", "html"), { recursive: true });
|
|
255
210
|
}
|
|
256
211
|
}
|
|
257
|
-
if (options.embeddedAttestationToken !== undefined) {
|
|
258
|
-
const attestationPath = join(staging, "package", EMBEDDED_ATTESTATION_RELATIVE_PATH);
|
|
259
|
-
mkdirSync(join(staging, "package", ".synopkgland"), { recursive: true });
|
|
260
|
-
writeFileSync(attestationPath, options.embeddedAttestationToken, "utf8");
|
|
261
|
-
chmodSync(attestationPath, FILE_MODE);
|
|
262
|
-
}
|
|
263
212
|
if (contract.adminport !== undefined && resolvedWebLaunch(contract) === "dsm-window") {
|
|
264
213
|
const uiDir = join(staging, "package", "ui");
|
|
265
214
|
mkdirSync(uiDir, { recursive: true });
|
|
@@ -277,6 +226,7 @@ export async function buildSpk(options) {
|
|
|
277
226
|
chmodSync(join(staging, "package", "ui", "config"), FILE_MODE);
|
|
278
227
|
}
|
|
279
228
|
const outputPath = options.outputPath ?? join(options.project.root, `${String(contract.package)}.spk`);
|
|
229
|
+
copyProjectNotices(options.project.root, join(staging, 'package'));
|
|
280
230
|
await createDeterministicSpk(staging, outputPath);
|
|
281
231
|
return { ok: true, outputPath, errors: [] };
|
|
282
232
|
}
|
|
@@ -312,12 +262,6 @@ function renderInfo(contract, archFamily, isResourceWorker = false) {
|
|
|
312
262
|
add("install_dep_packages", "WebStation");
|
|
313
263
|
}
|
|
314
264
|
}
|
|
315
|
-
else {
|
|
316
|
-
// synopkg's Container Manager dep gate reports "not ready" even when CM is
|
|
317
|
-
// running. Depend on Broker only; Broker's adapter.probe() checks CM at
|
|
318
|
-
// App install time (CM_CAPABILITY_MISSING).
|
|
319
|
-
add("install_dep_packages", "SynoPkgLandService>=0.1.0-0016");
|
|
320
|
-
}
|
|
321
265
|
add("startable", "yes");
|
|
322
266
|
const launch = resolvedWebLaunch(contract);
|
|
323
267
|
if (contract.adminprotocol) {
|
|
@@ -354,47 +298,15 @@ function renderPrivilege() {
|
|
|
354
298
|
},
|
|
355
299
|
}, null, 2)}\n`;
|
|
356
300
|
}
|
|
357
|
-
const SHARED_FOLDER_MOUNT_CONSENT = "此 App 會用你在這台 NAS 選的資料夾;整顆應用都看得到。Shared Folder Mount 是整個 App Instance 的 container access:能打開這個 App 的使用者,容器裡的程式都看得到該 Share,即使該使用者在 File Station 看不到。這不是逐使用者 DSM ACL
|
|
358
|
-
const HOMES_MOUNT_CONSENT = "此 App 會使用這台 NAS 已啟用的 User Home;整顆應用的容器都看得到,容器路徑由 Compose 決定。這不是逐使用者 DSM ACL
|
|
359
|
-
const POSIX_ALL_SHARES_MAX_WARNING = "
|
|
301
|
+
const SHARED_FOLDER_MOUNT_CONSENT = "此 App 會用你在這台 NAS 選的資料夾;整顆應用都看得到。Shared Folder Mount 是整個 App Instance 的 container access:能打開這個 App 的使用者,容器裡的程式都看得到該 Share,即使該使用者在 File Station 看不到。這不是逐使用者 DSM ACL。檔案權限取決於容器服務帳號;App 必須自行實作使用者授權。";
|
|
302
|
+
const HOMES_MOUNT_CONSENT = "此 App 會使用這台 NAS 已啟用的 User Home;整顆應用的容器都看得到,容器路徑由 Compose 決定。這不是逐使用者 DSM ACL;檔案權限取決於容器服務帳號;App 必須自行實作使用者授權。";
|
|
303
|
+
const POSIX_ALL_SHARES_MAX_WARNING = "此 App 會使用安裝當下這台 NAS 的全部 Shared Folder(App-wide,不依個別 DSM ACL);容器內可讀(或讀寫,依 Compose 模式)所有這些資料夾的檔案。安裝後新建的共用資料夾不會自動加入。Package Center 無法提供安裝當下的 Shared Folder 清單快照;要以全部 Share 安裝,請用 CLI `synopkgland deploy`,由 CLI 以管理員權限列舉全部 Share 並寫入快照。由管理員決定是否安裝。";
|
|
304
|
+
const POSIX_ALL_SHARES_UPGRADE_NOTICE = "升級會保留既有快照(安裝當下由 CLI 列舉的全部 Shared Folder);變更掛載範圍只能由 CLI 明確提供(`synopkgland deploy`)。Package Center 升級不會改動現有快照。";
|
|
360
305
|
const DSM_USER_RUN_AS_CONSENT = "寫進 Share 的新檔在 File Station 顯示為你選的那位 DSM 使用者。點開此 App 的人共用這個磁碟身分,不是逐登入 ACL。";
|
|
361
306
|
const DSM_USER_UPGRADE_CONSENT = "升級時更換 Container Run-as 不會 chown Share 上的舊檔;只有升級後寫入的新檔才會使用新的磁碟身分。";
|
|
307
|
+
const UPGRADE_VALUE_REUSE_DESC = "留空=沿用目前設定";
|
|
362
308
|
const SHARED_FOLDER_RW_UPGRADE_CONSENT = "此版本把 Share 掛載改為讀寫;容器可讀取並寫入你選的 Share,不再是唯讀。";
|
|
363
309
|
const APP_OWN_SPACE_CONSENT = "此 App 只用 App 自己的空間。";
|
|
364
|
-
const OIDC_COMPAT_CONSENT = "此 App 可用你的 DSM 帳號登入;如果這台 NAS 尚未啟用相容模式,App 會使用自己的登入。登入不等於 File Station ACL。";
|
|
365
|
-
function hasOidcCompat(contract) {
|
|
366
|
-
const integration = contract.integration;
|
|
367
|
-
if (!integration || typeof integration !== "object") {
|
|
368
|
-
return false;
|
|
369
|
-
}
|
|
370
|
-
const identity = integration.identity;
|
|
371
|
-
if (!identity || typeof identity !== "object") {
|
|
372
|
-
return false;
|
|
373
|
-
}
|
|
374
|
-
const oidcCompat = identity.oidc_compat;
|
|
375
|
-
return Boolean(oidcCompat && typeof oidcCompat === "object");
|
|
376
|
-
}
|
|
377
|
-
function renderFilesCapability(contract) {
|
|
378
|
-
const permissions = contract.permissions;
|
|
379
|
-
const files = permissions?.files;
|
|
380
|
-
if (!files) {
|
|
381
|
-
return null;
|
|
382
|
-
}
|
|
383
|
-
const parts = [];
|
|
384
|
-
if (files.read) {
|
|
385
|
-
parts.push("讀取檔案");
|
|
386
|
-
}
|
|
387
|
-
if (files.write) {
|
|
388
|
-
parts.push("寫入檔案");
|
|
389
|
-
}
|
|
390
|
-
if (files.delete) {
|
|
391
|
-
parts.push("刪除檔案");
|
|
392
|
-
}
|
|
393
|
-
if (parts.length === 0) {
|
|
394
|
-
return null;
|
|
395
|
-
}
|
|
396
|
-
return `此 App 需要以下檔案能力:${parts.join("、")}。這是每位登入者的 DSM ACL,經 File Gateway。`;
|
|
397
|
-
}
|
|
398
310
|
function volumeSources(compose) {
|
|
399
311
|
return volumeMounts(compose).map((mount) => mount.source);
|
|
400
312
|
}
|
|
@@ -484,17 +396,11 @@ function renderInstallWizard(contract, compose) {
|
|
|
484
396
|
const hasSharedFolder = params.some((item) => item.param.type === "shared_folder");
|
|
485
397
|
const hasHomes = params.some((item) => item.param.type === "homes");
|
|
486
398
|
const hasDsmUser = params.some((item) => item.param.type === "dsm_user");
|
|
487
|
-
const capabilityText = renderFilesCapability(contract);
|
|
488
399
|
if (compose && scanComposePrivilege(compose).length > 0) {
|
|
489
400
|
items.push({
|
|
490
401
|
desc: PRIVILEGE_MAX_WARNING,
|
|
491
402
|
});
|
|
492
403
|
}
|
|
493
|
-
if (hasOidcCompat(contract)) {
|
|
494
|
-
items.push({
|
|
495
|
-
desc: OIDC_COMPAT_CONSENT,
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
404
|
if (hasSharedFolder) {
|
|
499
405
|
items.push({
|
|
500
406
|
desc: SHARED_FOLDER_MOUNT_CONSENT,
|
|
@@ -510,15 +416,7 @@ function renderInstallWizard(contract, compose) {
|
|
|
510
416
|
desc: DSM_USER_RUN_AS_CONSENT,
|
|
511
417
|
});
|
|
512
418
|
}
|
|
513
|
-
if (
|
|
514
|
-
items.push({
|
|
515
|
-
desc: capabilityText,
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
// No compose at all is the native branch: the binary gets PKGVAR and nothing
|
|
519
|
-
// else, so it earns the same line. Requiring a compose left native wizards
|
|
520
|
-
// empty, which DSM rejects as an invalid package.
|
|
521
|
-
if (!hasSharedFolder && !capabilityText && (!compose || composeUsesOnlyAppSpace(compose))) {
|
|
419
|
+
if (!hasSharedFolder && (!compose || composeUsesOnlyAppSpace(compose))) {
|
|
522
420
|
items.push({
|
|
523
421
|
desc: APP_OWN_SPACE_CONSENT,
|
|
524
422
|
});
|
|
@@ -584,36 +482,19 @@ function renderInstallWizard(contract, compose) {
|
|
|
584
482
|
continue;
|
|
585
483
|
}
|
|
586
484
|
if (param.type === "posix_all_shares") {
|
|
485
|
+
// A47 (install side): DSM's declarative wizard only ever renders a
|
|
486
|
+
// single-select combo here, so the former multiSelect control silently
|
|
487
|
+
// mounted exactly one Share instead of every Share. Package Center can
|
|
488
|
+
// therefore never carry the full Share list, and there is no honest
|
|
489
|
+
// control to render -- so this branch produces only an informational
|
|
490
|
+
// textblock. The full snapshot arrives exclusively via CLI
|
|
491
|
+
// extra_values (`synopkgland deploy`), which the preinst materializer
|
|
492
|
+
// expands. No subitem key is emitted, so the install uifile contains no
|
|
493
|
+
// ALL_SHARES and no CHANGE_ALL_SHARES.
|
|
587
494
|
items.push({
|
|
588
495
|
type: "textblock",
|
|
589
496
|
desc: POSIX_ALL_SHARES_MAX_WARNING,
|
|
590
497
|
});
|
|
591
|
-
items.push({
|
|
592
|
-
type: "combobox",
|
|
593
|
-
multiSelect: true,
|
|
594
|
-
desc: `POSIX all shares: ${name}`,
|
|
595
|
-
subitems: [{
|
|
596
|
-
key: name,
|
|
597
|
-
desc: name,
|
|
598
|
-
displayField: "name",
|
|
599
|
-
valueField: "name",
|
|
600
|
-
multiSelect: true,
|
|
601
|
-
editable: false,
|
|
602
|
-
forceSelection: true,
|
|
603
|
-
autoSelect: false,
|
|
604
|
-
mode: "remote",
|
|
605
|
-
api_store: {
|
|
606
|
-
api: "SYNO.Core.Share",
|
|
607
|
-
method: "list",
|
|
608
|
-
version: 1,
|
|
609
|
-
baseParams: { limit: -1, offset: 0 },
|
|
610
|
-
root: "shares",
|
|
611
|
-
idProperty: "name",
|
|
612
|
-
fields: ["name"],
|
|
613
|
-
},
|
|
614
|
-
validator: { allowBlank: false },
|
|
615
|
-
}],
|
|
616
|
-
});
|
|
617
498
|
continue;
|
|
618
499
|
}
|
|
619
500
|
if (param.type === "dsm_user") {
|
|
@@ -651,6 +532,75 @@ function renderInstallWizard(contract, compose) {
|
|
|
651
532
|
function renderUpgradeWizard(contract, compose) {
|
|
652
533
|
const installWizard = renderInstallWizard(contract, compose);
|
|
653
534
|
const params = collectInstallParameters(contract);
|
|
535
|
+
// Every type whose value must survive an upgrade the administrator did not
|
|
536
|
+
// deliberately change. Two mechanisms are needed because DSM renders them
|
|
537
|
+
// differently: a control that can be left blank just allows blank, while one
|
|
538
|
+
// that always carries a value needs an explicit "change this" gate.
|
|
539
|
+
// - dsm_user : measurably comes up blank, so allowBlank is enough
|
|
540
|
+
// - string : blank once the new version's default is withheld (A44)
|
|
541
|
+
// - shared_folder : DSM prefills the first store row
|
|
542
|
+
// - boolean : a checkbox has no blank state at all
|
|
543
|
+
// posix_all_shares is intentionally absent: it renders as a textblock with
|
|
544
|
+
// no subitem, so there is nothing to blank or gate on the upgrade wizard.
|
|
545
|
+
// Its value can only arrive via CLI extra_values, and the preinst
|
|
546
|
+
// change-gate shell (`upgrade_change_enabled`, `CHANGE_<name>`) still
|
|
547
|
+
// governs that path, reusing the canonical snapshot on an untouched upgrade.
|
|
548
|
+
const upgradeReuseTypes = new Map(params
|
|
549
|
+
.filter(({ param }) => param.type === "shared_folder" ||
|
|
550
|
+
param.type === "dsm_user" ||
|
|
551
|
+
param.type === "string" ||
|
|
552
|
+
param.type === "boolean")
|
|
553
|
+
.map(({ name, param }) => [name, param.type]));
|
|
554
|
+
const needsChangeGate = (type) => type === "shared_folder" || type === "boolean";
|
|
555
|
+
const upgradeItems = installWizard[0].items.flatMap((item) => {
|
|
556
|
+
if (!Array.isArray(item.subitems)) {
|
|
557
|
+
return [item];
|
|
558
|
+
}
|
|
559
|
+
const reuseKeys = [];
|
|
560
|
+
const subitems = item.subitems.map((subitem) => {
|
|
561
|
+
if (!subitem || typeof subitem !== "object") {
|
|
562
|
+
return subitem;
|
|
563
|
+
}
|
|
564
|
+
const record = subitem;
|
|
565
|
+
if (typeof record.key !== "string" || !upgradeReuseTypes.has(record.key)) {
|
|
566
|
+
return subitem;
|
|
567
|
+
}
|
|
568
|
+
reuseKeys.push(record.key);
|
|
569
|
+
const reused = {
|
|
570
|
+
...record,
|
|
571
|
+
validator: { allowBlank: true },
|
|
572
|
+
};
|
|
573
|
+
// Withholding the default is what makes an untouched upgrade blank, and
|
|
574
|
+
// blank is what lets preinst fall through to the canonical .env value.
|
|
575
|
+
// Install keeps the default -- only this upgrade copy drops it.
|
|
576
|
+
delete reused.defaultValue;
|
|
577
|
+
return reused;
|
|
578
|
+
});
|
|
579
|
+
if (reuseKeys.length === 0) {
|
|
580
|
+
return [item];
|
|
581
|
+
}
|
|
582
|
+
const control = {
|
|
583
|
+
...item,
|
|
584
|
+
desc: `${String(item.desc ?? "")}(${UPGRADE_VALUE_REUSE_DESC})`,
|
|
585
|
+
subitems,
|
|
586
|
+
};
|
|
587
|
+
const changeControls = reuseKeys
|
|
588
|
+
.filter((key) => needsChangeGate(upgradeReuseTypes.get(key)))
|
|
589
|
+
.map((key) => {
|
|
590
|
+
const type = upgradeReuseTypes.get(key);
|
|
591
|
+
const label = type === "shared_folder" ? "Shared Folder" : key;
|
|
592
|
+
return {
|
|
593
|
+
type: "multiselect",
|
|
594
|
+
desc: `變更 ${label}(不勾=沿用目前設定)`,
|
|
595
|
+
subitems: [{
|
|
596
|
+
key: `CHANGE_${key}`,
|
|
597
|
+
desc: `變更 ${label}`,
|
|
598
|
+
defaultValue: false,
|
|
599
|
+
}],
|
|
600
|
+
};
|
|
601
|
+
});
|
|
602
|
+
return [...changeControls, control];
|
|
603
|
+
});
|
|
654
604
|
const sharedFolderNames = params
|
|
655
605
|
.filter((item) => item.param.type === "shared_folder")
|
|
656
606
|
.map((item) => item.name);
|
|
@@ -661,6 +611,14 @@ function renderUpgradeWizard(contract, compose) {
|
|
|
661
611
|
volumeMounts(compose).some((mount) => !mount.readOnly &&
|
|
662
612
|
sharedFolderNames.some((name) => mount.source === `\${${name}}` || mount.source.startsWith(`\${${name}}/`)));
|
|
663
613
|
const upgradeConsent = [];
|
|
614
|
+
const posixAllSharesNames = params
|
|
615
|
+
.filter((item) => item.param.type === "posix_all_shares")
|
|
616
|
+
.map((item) => item.name);
|
|
617
|
+
if (posixAllSharesNames.length > 0) {
|
|
618
|
+
upgradeConsent.push({
|
|
619
|
+
desc: POSIX_ALL_SHARES_UPGRADE_NOTICE,
|
|
620
|
+
});
|
|
621
|
+
}
|
|
664
622
|
if (hasReadWriteSharedFolder) {
|
|
665
623
|
upgradeConsent.push({
|
|
666
624
|
desc: SHARED_FOLDER_RW_UPGRADE_CONSENT,
|
|
@@ -675,11 +633,12 @@ function renderUpgradeWizard(contract, compose) {
|
|
|
675
633
|
return [{
|
|
676
634
|
...installWizard[0],
|
|
677
635
|
step_title: "升級設定",
|
|
636
|
+
items: upgradeItems,
|
|
678
637
|
}];
|
|
679
638
|
}
|
|
680
|
-
const firstControl =
|
|
681
|
-
const insertAt = firstControl === -1 ?
|
|
682
|
-
const items = [...
|
|
639
|
+
const firstControl = upgradeItems.findIndex((item) => item.subitems !== undefined);
|
|
640
|
+
const insertAt = firstControl === -1 ? upgradeItems.length : firstControl;
|
|
641
|
+
const items = [...upgradeItems];
|
|
683
642
|
items.splice(insertAt, 0, ...upgradeConsent);
|
|
684
643
|
return [{
|
|
685
644
|
...installWizard[0],
|
|
@@ -708,7 +667,6 @@ function renderUninstallWizard() {
|
|
|
708
667
|
],
|
|
709
668
|
}];
|
|
710
669
|
}
|
|
711
|
-
const LEGACY_BROKER_STATE_REGISTRY_CODE = "COMPOSE_LEGACY_BROKER_STATE_PRESENT";
|
|
712
670
|
function renderDynamicPreinstMaterializer(contract) {
|
|
713
671
|
const allParams = collectInstallParameters(contract);
|
|
714
672
|
const scalarParams = allParams.filter(({ param }) => param.type === "string" || param.type === "boolean");
|
|
@@ -721,18 +679,6 @@ function renderDynamicPreinstMaterializer(contract) {
|
|
|
721
679
|
"umask 077",
|
|
722
680
|
"# D3/D5.4 package-only carrier; values are wizard answers, canonical values, or defaults.",
|
|
723
681
|
"die() { echo \"dynamic route materialization failed: $1\" >&2; exit 1; }",
|
|
724
|
-
`# registry-code="${LEGACY_BROKER_STATE_REGISTRY_CODE}"`,
|
|
725
|
-
'APPDATA="${SYNOPKG_PKGDEST_VOL:?}/@appdata/${SYNOPKG_PKGNAME:?}"',
|
|
726
|
-
'if [ -d "$APPDATA" ]; then',
|
|
727
|
-
' broker_uid="$(id -u SynoPkgLandService 2>/dev/null || true)"',
|
|
728
|
-
' if [ -n "$broker_uid" ]; then',
|
|
729
|
-
' for item in "$APPDATA"/* "$APPDATA"/.[!.]* "$APPDATA"/..?*; do',
|
|
730
|
-
' [ -e "$item" ] || continue',
|
|
731
|
-
' item_uid="$(stat -c %u "$item" 2>/dev/null || true)"',
|
|
732
|
-
' [ "$item_uid" = "$broker_uid" ] && die "MIGRATION_UNSUPPORTED: ${SYNOPKG_PKGNAME} 曾由 Broker installer 安裝;dynamic 路線不支援就地遷移,請以新的 Package Identity 安裝或先完整卸載並清除 App Data"',
|
|
733
|
-
" done",
|
|
734
|
-
" fi",
|
|
735
|
-
"fi",
|
|
736
682
|
'T="${SYNOPKG_PKGINST_TEMP_DIR:?}"',
|
|
737
683
|
'STATUS="${SYNOPKG_PKG_STATUS:?}"',
|
|
738
684
|
'PROJECT="$T/compose"',
|
|
@@ -776,6 +722,16 @@ function renderDynamicPreinstMaterializer(contract) {
|
|
|
776
722
|
" esac",
|
|
777
723
|
"}",
|
|
778
724
|
];
|
|
725
|
+
// Emitted whenever anything reads a CHANGE_ gate. Boolean parameters (A44) use
|
|
726
|
+
// it too, and a package with only booleans has no Share resolvers -- leaving it
|
|
727
|
+
// behind that condition made `! upgrade_change_enabled ...` a missing command,
|
|
728
|
+
// which is true, so the gate silently always reused the canonical value.
|
|
729
|
+
const usesUpgradeChangeGate = sharedFolderParams.length > 0 ||
|
|
730
|
+
posixAllSharesParams.length > 0 ||
|
|
731
|
+
collectInstallParameters(contract).some(({ param }) => param.type === "boolean");
|
|
732
|
+
if (usesUpgradeChangeGate) {
|
|
733
|
+
lines.push("upgrade_change_enabled() {", " normalized=\"$(printf '%s' \"$1\" | LC_ALL=C tr '[:upper:]' '[:lower:]')\"", " case \"$normalized\" in", " true|1|yes|on) return 0 ;;", " *) return 1 ;;", " esac", "}");
|
|
734
|
+
}
|
|
779
735
|
if (sharedFolderParams.length > 0 || posixAllSharesParams.length > 0) {
|
|
780
736
|
lines.push("resolve_shared_folder() {", " share_name=\"$1\"", " case \"$share_name\" in", " */*|*..*) die \"invalid share name $share_name\" ;;", " '') die \"share name is empty\" ;;", " esac", " mounts_file=\"${D54_MOUNTS_FILE:-/proc/mounts}\"", " if [ ! -r \"$mounts_file\" ] && [ -r \"/etc/mtab\" ]; then", " mounts_file=\"/etc/mtab\"", " fi", " if [ ! -r \"$mounts_file\" ]; then", " die \"cannot read mount points from $mounts_file\"", " fi", " vols=\"$(awk '$2 ~ /^\\/volume[0-9]+$/ {print $2}' \"$mounts_file\" | sort -u)\"", ' if [ -z "$vols" ]; then', " vols=\"$(awk '{print $2}' \"$mounts_file\" | sort -u)\"", " fi", " matched=\"\"", " count=0", " for v in $vols; do", " if [ -d \"$v/$share_name\" ]; then", " matched=\"$v/$share_name\"", " count=$((count + 1))", " fi", " done", " if [ \"$count\" -eq 0 ]; then", " die \"share $share_name not found on any volume\"", " elif [ \"$count\" -gt 1 ]; then", " die \"share $share_name matched multiple volumes\"", " fi", " printf '%s' \"$matched\"", "}");
|
|
781
737
|
}
|
|
@@ -785,14 +741,6 @@ function renderDynamicPreinstMaterializer(contract) {
|
|
|
785
741
|
if (dsmUserParam) {
|
|
786
742
|
lines.push("resolve_dsm_user() {", " user_name=\"$1\"", " case \"$user_name\" in", " */*|*..*|*[[:cntrl:]]*) die \"invalid user name $user_name\" ;;", " '') die \"user name is empty\" ;;", " esac", " u_uid=\"$(id -u -- \"$user_name\" 2>/dev/null || true)\"", " case \"$u_uid\" in", " ''|*[!0-9]*) die \"resolved uid for $user_name is not a valid integer\" ;;", " 0) die \"resolved uid for $user_name cannot be 0 (root)\" ;;", " esac", " u_gid=\"$(id -g -- \"$user_name\" 2>/dev/null || true)\"", " case \"$u_gid\" in", " ''|*[!0-9]*) die \"resolved gid for $user_name is not a valid integer\" ;;", " esac", " # id -G returns all group ids including primary", " raw_groups=\"$(id -G -- \"$user_name\" 2>/dev/null || true)\"", " # filter out primary gid, deduplicate, keep numeric only", " supp_groups=\"\"", " for g in $raw_groups; do", " case \"$g\" in", " ''|*[!0-9]*) continue ;;", " esac", " if [ \"$g\" != \"$u_gid\" ]; then", " already=0", " for sg in $supp_groups; do", " if [ \"$sg\" = \"$g\" ]; then", " already=1", " break", " fi", " done", " if [ \"$already\" -eq 0 ]; then", " supp_groups=\"${supp_groups}${supp_groups:+ }$g\"", " fi", " fi", " done", " printf '%s %s %s' \"$u_uid\" \"$u_gid\" \"$supp_groups\"", "}", "rewrite_group_add() {", " p_name=\"$1\"", " g_list=\"$2\"", " compose_file=\"$3\"", " [ -f \"$compose_file\" ] || die \"compose file missing at $compose_file\"", " [ ! -L \"$compose_file\" ] || die \"compose file is a symlink\"", " tmp_compose=\"$(mktemp \"${compose_file}.tmp.XXXXXX\")\"", " awk -v param=\"$p_name\" -v g_list=\"$g_list\" '", " BEGIN {", " n = split(g_list, g_arr, \" \")", " }", " {", " regex = \"^[ \\t]*# synopkgland:group_add \" param \"$\"", " if ($0 ~ regex) {", " match($0, /^[ \\t]*/)", " indent = substr($0, RSTART, RLENGTH)", " if (n > 0) {", " print indent \"group_add:\"", " for (i = 1; i <= n; i++) {", " print indent \" - ${\" param \"_GROUP_\" i \"}\"", " }", " }", " } else {", " print $0", " }", " }", " ' \"$compose_file\" > \"$tmp_compose\" || die \"failed to rewrite group_add in $compose_file\"", " mv \"$tmp_compose\" \"$compose_file\" || die \"failed to replace $compose_file\"", "}");
|
|
787
743
|
}
|
|
788
|
-
if (hasOidcCompat(contract)) {
|
|
789
|
-
const identity = contract.integration?.identity;
|
|
790
|
-
const redirectPath = identity?.oidc_compat?.redirect_path ?? "";
|
|
791
|
-
const adminProtocol = contract.adminprotocol ?? "http";
|
|
792
|
-
const adminPort = Number(contract.adminport ?? 0);
|
|
793
|
-
const escapedRedirectPath = redirectPath.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
794
|
-
lines.push("oidc_register() {", " # DSM compose does not create missing bind sources: the secrets dir must exist even when compat is off.", " (umask 077 && mkdir -p \"$PROJECT/secrets\" && chmod 700 \"$PROJECT/secrets\") || die \"failed to create $PROJECT/secrets\"", " OIDC_ISSUER=\"\"", " OIDC_ISSUER_HOST=\"oidc.invalid\"", " OIDC_CLIENT_ID=\"\"", " OIDC_CLIENT_SECRET=\"\"", " identity_file=\"${SYNOPKGLAND_IDENTITY_FILE:-/var/packages/SynoPkgLandService/var/identity.json}\"", " if [ ! -r \"$identity_file\" ]; then", " identity_file=\"/volume1/@appdata/SynoPkgLandService/identity.json\"", " fi", " if [ ! -r \"$identity_file\" ]; then", " # Identity endpoint not found -> Broker not installed -> skip as 404", " rm -f \"$PROJECT/secrets/SYNOPKGLAND_OIDC_CLIENT_SECRET\"", " return 0", " fi", " base_url=\"$(python3 -c 'import json, sys; data=json.load(open(sys.argv[1])); print(data.get(\"baseUrl\", \"\"))' \"$identity_file\" 2>/dev/null || true)\"", " if [ -z \"$base_url\" ]; then", " rm -f \"$PROJECT/secrets/SYNOPKGLAND_OIDC_CLIENT_SECRET\"", " return 0", " fi", " attestation_file=\"$T/.synopkgland/attestation.jwt\"", " if [ ! -f \"$attestation_file\" ]; then", " rm -f \"$PROJECT/secrets/SYNOPKGLAND_OIDC_CLIENT_SECRET\"", " return 0", " fi", " attestation_token=\"$(cat \"$attestation_file\")\"", " phase=\"install\"", " case \"$STATUS\" in", " UPGRADE) phase=\"upgrade\" ;;", " *) phase=\"install\" ;;", " esac", " req_body=\"$(python3 -c 'import json, sys; print(json.dumps({\"protocolVersion\": 1, \"attestation\": sys.argv[1], \"packageIdentity\": sys.argv[2], \"packageVersion\": sys.argv[3], \"redirectPath\": sys.argv[4], \"adminProtocol\": sys.argv[5], \"adminPort\": int(sys.argv[6]), \"phase\": sys.argv[7]}))' \"$attestation_token\" \"${SYNOPKG_PKGNAME:?}\" \"${SYNOPKG_PKGVER:?}\" \"" + escapedRedirectPath + "\" \"" + String(adminProtocol) + "\" \"" + String(adminPort) + "\" \"$phase\")\"", " resp_file=\"$(mktemp \"$T/oidc_resp.XXXXXX\")\"", " http_code=\"$(curl -s -S --connect-timeout 5 --max-time 30 -o \"$resp_file\" -w '%{http_code}' -X POST -H 'Content-Type: application/json' --data-binary \"$req_body\" \"${base_url}/internal/v1/oidc/register\" 2>/dev/null || true)\"", " case \"$http_code\" in [0-9][0-9][0-9]) ;; *) http_code=\"000\" ;; esac", " if [ \"$http_code\" = \"200\" ]; then", " parsed_res=\"$(python3 -c 'import json, sys; d=json.load(open(sys.argv[1])); print(d.get(\"issuer\", \"\")); print(d.get(\"issuerHost\", \"\")); print(d.get(\"clientId\", \"\")); print(d.get(\"clientSecret\", \"\"))' \"$resp_file\" 2>/dev/null || true)\"", " rm -f \"$resp_file\"", " OIDC_ISSUER=\"$(printf '%s\\n' \"$parsed_res\" | sed -n '1p')\"", " OIDC_ISSUER_HOST=\"$(printf '%s\\n' \"$parsed_res\" | sed -n '2p')\"", " OIDC_CLIENT_ID=\"$(printf '%s\\n' \"$parsed_res\" | sed -n '3p')\"", " OIDC_CLIENT_SECRET=\"$(printf '%s\\n' \"$parsed_res\" | sed -n '4p')\"", " (umask 077 && mkdir -p \"$PROJECT/secrets\" && printf '%s' \"$OIDC_CLIENT_SECRET\" > \"$PROJECT/secrets/SYNOPKGLAND_OIDC_CLIENT_SECRET\")", " elif [ \"$http_code\" = \"404\" ] || [ \"$http_code\" = \"000\" ]; then", " rm -f \"$resp_file\"", " rm -f \"$PROJECT/secrets/SYNOPKGLAND_OIDC_CLIENT_SECRET\"", " OIDC_ISSUER=\"\"", " OIDC_ISSUER_HOST=\"oidc.invalid\"", " OIDC_CLIENT_ID=\"\"", " else", " rm -f \"$resp_file\"", " die \"OIDC_REGISTER_FAILED $http_code\"", " fi", "}", "oidc_register");
|
|
795
|
-
}
|
|
796
744
|
lines.push('tmp="$(mktemp "$PROJECT/.env.tmp.XXXXXX")"', 'chmod 600 "$tmp"', '[ "$(stat -c %a "$tmp")" = "600" ] || die "temporary env mode is not 0600"', '[ "$(stat -c %u "$tmp")" = "$(id -u)" ] || die "temporary env owner is not the package user"', "trap 'rm -f \"$tmp\"' EXIT HUP INT TERM", "{");
|
|
797
745
|
const valueVars = [];
|
|
798
746
|
for (const { name, param } of scalarParams) {
|
|
@@ -804,16 +752,27 @@ function renderDynamicPreinstMaterializer(contract) {
|
|
|
804
752
|
: type === "boolean"
|
|
805
753
|
? "false"
|
|
806
754
|
: "";
|
|
807
|
-
|
|
755
|
+
// A44: on UPGRADE the wizard always submits something for these controls, so
|
|
756
|
+
// "was it submitted" cannot mean "did the administrator choose it". A blank
|
|
757
|
+
// string, or a boolean whose CHANGE_ gate is unchecked, means "keep what is
|
|
758
|
+
// installed" -- otherwise the new version's default would silently replace a
|
|
759
|
+
// value chosen at install time. INSTALL is unaffected: STATUS is not UPGRADE,
|
|
760
|
+
// so the reuse branch is skipped and the default still applies.
|
|
761
|
+
const reuseGuard = type === "boolean"
|
|
762
|
+
? `! upgrade_change_enabled "\${CHANGE_${name}:-}"`
|
|
763
|
+
: `[ -z "\${${name}:-}" ]`;
|
|
764
|
+
lines.push(` if [ "$STATUS" = "UPGRADE" ] && ${reuseGuard} && [ -f "$CANONICAL_ENV" ] && ` +
|
|
765
|
+
`[ ! -L "$CANONICAL_ENV" ] && ${valueVar}="$(read_env_value "$CANONICAL_ENV" "${name}")"; then`, " :", ` elif [ "\${${name}+x}" = x ]; then`, ` ${valueVar}="\${${name}}"`, ' elif [ "$STATUS" = "UPGRADE" ] && [ -f "$CANONICAL_ENV" ] && [ ! -L "$CANONICAL_ENV" ] && ' +
|
|
808
766
|
`${valueVar}="$(read_env_value "$CANONICAL_ENV" "${name}")"; then`, " :", " else", " " + valueVar + "=" + shellQuote(fallback), " fi");
|
|
809
767
|
}
|
|
810
768
|
const shareVars = [];
|
|
811
769
|
for (const { name } of sharedFolderParams) {
|
|
812
770
|
const rawVar = "D54_RAW_SHARE_" + name;
|
|
813
771
|
const pathVar = "D54_RESOLVED_PATH_" + name;
|
|
772
|
+
const changeVar = "CHANGE_" + name;
|
|
814
773
|
shareVars.push({ name, pathVar });
|
|
815
|
-
lines.push(` if [ "\${${name}+x}" = x ]; then`, `
|
|
816
|
-
`${rawVar}="$(read_env_value "$CANONICAL_ENV" "${name}")"; then`, " :", " else", ` die "missing required shared folder parameter ${name}"`, " fi", ` case "$${rawVar}" in`, " /*) " + pathVar + "=\"$" + rawVar + "\" ;;", " *) " + pathVar + "=\"$(resolve_shared_folder \"$" + rawVar + "\")\" ;;", " esac");
|
|
774
|
+
lines.push(` if [ "$STATUS" = "UPGRADE" ] && upgrade_change_enabled "\${${changeVar}:-}"; then`, ` if [ "\${${name}+x}" = x ] && [ -n "\${${name}}" ]; then`, ` ${rawVar}="\${${name}}"`, " else", ` die "missing required shared folder parameter ${name}"`, " fi", ' elif [ "$STATUS" = "UPGRADE" ] && [ -f "$CANONICAL_ENV" ] && [ ! -L "$CANONICAL_ENV" ] && ' +
|
|
775
|
+
`${rawVar}="$(read_env_value "$CANONICAL_ENV" "${name}")"; then`, " :", ' elif [ "$STATUS" = "UPGRADE" ]; then', ` die "missing canonical shared folder parameter ${name}"`, ` elif [ "\${${name}+x}" = x ]; then`, ` ${rawVar}="\${${name}}"`, " else", ` die "missing required shared folder parameter ${name}"`, " fi", ` case "$${rawVar}" in`, " /*) " + pathVar + "=\"$" + rawVar + "\" ;;", " *) " + pathVar + "=\"$(resolve_shared_folder \"$" + rawVar + "\")\" ;;", " esac");
|
|
817
776
|
}
|
|
818
777
|
const posixVars = [];
|
|
819
778
|
for (const { name } of posixAllSharesParams) {
|
|
@@ -821,22 +780,18 @@ function renderDynamicPreinstMaterializer(contract) {
|
|
|
821
780
|
const namesVar = "D54_POSIX_NAMES_" + name;
|
|
822
781
|
const pathsVar = "D54_POSIX_PATHS_" + name;
|
|
823
782
|
const countVar = "D54_POSIX_COUNT_" + name;
|
|
783
|
+
const changeVar = "CHANGE_" + name;
|
|
824
784
|
posixVars.push({ name, namesVar, pathsVar, countVar });
|
|
825
|
-
lines.push(` if [ "\${${name}+x}" = x ]; then`, `
|
|
826
|
-
`${rawVar}="$(read_env_value "$CANONICAL_ENV" "${name}")"; then`, " :", " else", ` die "missing required POSIX all-shares parameter ${name}"`, " fi", ` posix_info="$(resolve_posix_all_shares "$${rawVar}")"`, ` ${namesVar}="$(printf '%s\\n' "$posix_info" | sed -n '1p')"`, ` ${pathsVar}="$(printf '%s\\n' "$posix_info" | sed -n '2p')"`, ` ${countVar}="$(printf '%s\\n' "$posix_info" | sed -n '3p')"`, ` rewrite_posix_all_shares "${name}" "$${namesVar}" "$${pathsVar}" "$PROJECT/docker-compose.yml"`);
|
|
785
|
+
lines.push(` if [ "$STATUS" = "UPGRADE" ] && upgrade_change_enabled "\${${changeVar}:-}"; then`, ` if [ "\${${name}+x}" = x ] && [ -n "\${${name}}" ]; then`, ` ${rawVar}="\${${name}}"`, " else", ` die "missing required POSIX all-shares parameter ${name}"`, " fi", ' elif [ "$STATUS" = "UPGRADE" ] && [ -f "$CANONICAL_ENV" ] && [ ! -L "$CANONICAL_ENV" ] && ' +
|
|
786
|
+
`${rawVar}="$(read_env_value "$CANONICAL_ENV" "${name}")"; then`, " :", ' elif [ "$STATUS" = "UPGRADE" ]; then', ` die "missing canonical POSIX all-shares parameter ${name}"`, ` elif [ "\${${name}+x}" = x ]; then`, ` ${rawVar}="\${${name}}"`, " else", ` die "missing required POSIX all-shares parameter ${name}"`, " fi", ` posix_info="$(resolve_posix_all_shares "$${rawVar}")"`, ` ${namesVar}="$(printf '%s\\n' "$posix_info" | sed -n '1p')"`, ` ${pathsVar}="$(printf '%s\\n' "$posix_info" | sed -n '2p')"`, ` ${countVar}="$(printf '%s\\n' "$posix_info" | sed -n '3p')"`, ` rewrite_posix_all_shares "${name}" "$${namesVar}" "$${pathsVar}" "$PROJECT/docker-compose.yml"`);
|
|
827
787
|
}
|
|
828
788
|
if (dsmUserParam) {
|
|
829
789
|
const name = dsmUserParam.name;
|
|
830
790
|
const rawUserVar = "D54_RAW_USER_" + name;
|
|
831
|
-
lines.push(` if [ "\${${name}+x}" = x ]; then`, ` ${rawUserVar}="\${${name}}"`, ' elif [ "$STATUS" = "UPGRADE" ] && [ -f "$CANONICAL_ENV" ] && [ ! -L "$CANONICAL_ENV" ] && ' +
|
|
832
|
-
`${rawUserVar}="$(read_env_value "$CANONICAL_ENV" "${name}")"; then`, " :", " else", ` die "missing required dsm user parameter ${name}"`, " fi", ` resolved_user_info="$(resolve_dsm_user "$${rawUserVar}")"`, " set -- $resolved_user_info", ` ${name}_UID="$1"`, ` ${name}_GID="$2"`, " shift 2 || true", ` ${name}_GROUPS="$*"`, ` rewrite_group_add "${name}" "$${name}_GROUPS" "$PROJECT/docker-compose.yml"`);
|
|
833
|
-
}
|
|
834
|
-
if (hasOidcCompat(contract)) {
|
|
835
|
-
lines.push(' append_env "SYNOPKG_PKGVAR" "$PLATFORM_PKGVAR"', ' append_env "SYNO_APP_SECRETS_DIR" "${SYNOPKG_PKGDEST_VOL:?}/@appstore/${SYNOPKG_PKGNAME:?}/compose/secrets"', ' append_env "SYNOPKGLAND_OIDC_ISSUER" "$OIDC_ISSUER"', ' append_env "SYNOPKGLAND_OIDC_ISSUER_HOST" "$OIDC_ISSUER_HOST"', ' append_env "SYNOPKGLAND_OIDC_CLIENT_ID" "$OIDC_CLIENT_ID"');
|
|
836
|
-
}
|
|
837
|
-
else {
|
|
838
|
-
lines.push(' append_env "SYNOPKG_PKGVAR" "$PLATFORM_PKGVAR"', ' append_env "SYNO_APP_SECRETS_DIR" "$PLATFORM_SECRETS"');
|
|
791
|
+
lines.push(` if [ "\${${name}+x}" = x ] && [ -n "\${${name}}" ]; then`, ` ${rawUserVar}="\${${name}}"`, ' elif [ "$STATUS" = "UPGRADE" ] && [ -f "$CANONICAL_ENV" ] && [ ! -L "$CANONICAL_ENV" ] && ' +
|
|
792
|
+
`${rawUserVar}="$(read_env_value "$CANONICAL_ENV" "${name}")"; then`, " :", ` elif [ "\${${name}+x}" = x ]; then`, ` ${rawUserVar}="\${${name}}"`, " else", ` die "missing required dsm user parameter ${name}"`, " fi", ` resolved_user_info="$(resolve_dsm_user "$${rawUserVar}")"`, " set -- $resolved_user_info", ` ${name}_UID="$1"`, ` ${name}_GID="$2"`, " shift 2 || true", ` ${name}_GROUPS="$*"`, ` rewrite_group_add "${name}" "$${name}_GROUPS" "$PROJECT/docker-compose.yml"`);
|
|
839
793
|
}
|
|
794
|
+
lines.push(' append_env "SYNOPKG_PKGVAR" "$PLATFORM_PKGVAR"', ' append_env "SYNO_APP_SECRETS_DIR" "$PLATFORM_SECRETS"');
|
|
840
795
|
for (const { name, valueVar, type } of valueVars) {
|
|
841
796
|
lines.push(` append_env "${name}" "$${valueVar}" "${type}"`);
|
|
842
797
|
}
|
|
@@ -910,29 +865,11 @@ function renderManagedScript(name, contract, nativeContext, isResourceWorker = f
|
|
|
910
865
|
if (name === "start-stop-status") {
|
|
911
866
|
return renderNativeStartStopStatus(lifecycleInput);
|
|
912
867
|
}
|
|
913
|
-
if (name === "preinst" || name === "preupgrade") {
|
|
914
|
-
return BROKER_SOCKET_REQUIRED_SCRIPT;
|
|
915
|
-
}
|
|
916
868
|
if (name === "postinst" || name === "postupgrade") {
|
|
917
|
-
|
|
918
|
-
// The service process needs its scratch directory before it can start,
|
|
919
|
-
// and the installer call is the script's exit status, so widen the
|
|
920
|
-
// existing mkdir rather than appending after it.
|
|
921
|
-
return installerScript.replace('mkdir -p "${SYNOPKG_PKGVAR}" "${SYNOPKG_PKGHOME}/secrets"', 'mkdir -p "${SYNOPKG_PKGVAR}" "${SYNOPKG_PKGVAR}/tmp" "${SYNOPKG_PKGHOME}/secrets"');
|
|
869
|
+
return renderNativePostinst(lifecycleInput);
|
|
922
870
|
}
|
|
923
871
|
if (name === "preuninst") {
|
|
924
|
-
|
|
925
|
-
const installerScript = renderInstallerCallScript(contract, "uninstall").replace("set -eu\n", 'set -eu\nif [ "${SYNOPKG_PKG_STATUS:-}" = "UPGRADE" ]; then\n exit 0\nfi\n');
|
|
926
|
-
// Stop the process BEFORE deregistering: `set -eu` aborts the script if
|
|
927
|
-
// the installer fails, so a stop appended after it would never run. The
|
|
928
|
-
// stop itself is best effort -- DSM already calls `start-stop-status
|
|
929
|
-
// stop` directly (N0), and a non-zero preuninst blocks uninstall.
|
|
930
|
-
const preuninstStopBlock = `CONTROL="/var/packages/\${SYNOPKG_PKGNAME:-${contract.package}}/scripts/start-stop-status"
|
|
931
|
-
if [ -x "$CONTROL" ]; then
|
|
932
|
-
"$CONTROL" stop 2>/dev/null || true
|
|
933
|
-
fi
|
|
934
|
-
`;
|
|
935
|
-
return installerScript.replace('"$INSTALLER"', `${preuninstStopBlock}"$INSTALLER"`);
|
|
872
|
+
return renderNativePreuninst(lifecycleInput);
|
|
936
873
|
}
|
|
937
874
|
if (name === "postuninst") {
|
|
938
875
|
return renderNativePostuninst(lifecycleInput);
|
|
@@ -967,93 +904,7 @@ ${projectRoot}${renderDeleteAppDataBlock(deleteRoots)}exit 0
|
|
|
967
904
|
}
|
|
968
905
|
return `#!/bin/sh\nexit 0\n`;
|
|
969
906
|
}
|
|
970
|
-
|
|
971
|
-
return `#!/bin/sh
|
|
972
|
-
${BROKER_INSTALLER_VARS}
|
|
973
|
-
case "$1" in
|
|
974
|
-
start) exit 0 ;;
|
|
975
|
-
stop) exit 0 ;;
|
|
976
|
-
status)
|
|
977
|
-
${renderBrokerStatusProbe(String(contract.package))}
|
|
978
|
-
exit 0
|
|
979
|
-
;;
|
|
980
|
-
*) exit 1 ;;
|
|
981
|
-
esac
|
|
982
|
-
`;
|
|
983
|
-
}
|
|
984
|
-
if (name === "preinst" || name === "preupgrade") {
|
|
985
|
-
return BROKER_SOCKET_REQUIRED_SCRIPT;
|
|
986
|
-
}
|
|
987
|
-
if (name === "postinst" || name === "postupgrade") {
|
|
988
|
-
return renderInstallerCallScript(contract, name === "postupgrade" ? "update" : "install");
|
|
989
|
-
}
|
|
990
|
-
if (name === "preuninst") {
|
|
991
|
-
return renderInstallerCallScript(contract, "uninstall").replace("set -eu\n", 'set -eu\nif [ "${SYNOPKG_PKG_STATUS:-}" = "UPGRADE" ]; then\n exit 0\nfi\n');
|
|
992
|
-
}
|
|
993
|
-
if (name === "postuninst") {
|
|
994
|
-
return `#!/bin/sh
|
|
995
|
-
set -eu
|
|
996
|
-
PKGVAR="\${SYNOPKG_PKGVAR}"
|
|
997
|
-
PKGHOME="\${SYNOPKG_PKGHOME}"
|
|
998
|
-
SECRETS="\${PKGHOME}/secrets"
|
|
999
|
-
${renderDeleteAppDataBlock(["PKGVAR", "SECRETS"])}exit 0
|
|
1000
|
-
`;
|
|
1001
|
-
}
|
|
1002
|
-
return `#!/bin/sh
|
|
1003
|
-
exit 0
|
|
1004
|
-
`;
|
|
1005
|
-
}
|
|
1006
|
-
function renderInstallerCallScript(contract, phase) {
|
|
1007
|
-
const params = collectInstallParameters(contract);
|
|
1008
|
-
const secrets = params.filter((item) => item.param.type === "secret");
|
|
1009
|
-
const nonSecrets = params.filter((item) => item.param.type !== "secret");
|
|
1010
|
-
const lines = [
|
|
1011
|
-
"#!/bin/sh",
|
|
1012
|
-
"set -eu",
|
|
1013
|
-
'INSTALLER="${BROKER_INSTALLER:-/var/packages/SynoPkgLandService/target/bin/synopkgland-installer}"',
|
|
1014
|
-
'SOCKET="${BROKER_SOCKET:-/var/packages/SynoPkgLandService/var/installer.sock}"',
|
|
1015
|
-
`PACKAGE_ROOT="/var/packages/${contract.package}"`,
|
|
1016
|
-
'ATTEMPT_ID="${SYNOPKG_PKGNAME}-${SYNOPKG_PKGVER}-$$"',
|
|
1017
|
-
'WORK="$(mktemp -d /tmp/synopkgland-install.XXXXXX)"',
|
|
1018
|
-
'chmod 700 "$WORK"',
|
|
1019
|
-
"cleanup() { rm -rf \"$WORK\"; }",
|
|
1020
|
-
"trap cleanup EXIT",
|
|
1021
|
-
'mkdir -p "${SYNOPKG_PKGVAR}" "${SYNOPKG_PKGHOME}/secrets"',
|
|
1022
|
-
'chmod 770 "${SYNOPKG_PKGVAR}" "${SYNOPKG_PKGHOME}" "${SYNOPKG_PKGHOME}/secrets" 2>/dev/null || true',
|
|
1023
|
-
'chgrp synopkgs "${SYNOPKG_PKGVAR}" "${SYNOPKG_PKGHOME}" "${SYNOPKG_PKGHOME}/secrets" 2>/dev/null || true',
|
|
1024
|
-
'VARS=""',
|
|
1025
|
-
'SECRET_FILES=""',
|
|
1026
|
-
];
|
|
1027
|
-
for (const { name, param } of secrets) {
|
|
1028
|
-
if (param.generate === true) {
|
|
1029
|
-
continue;
|
|
1030
|
-
}
|
|
1031
|
-
lines.push(`if [ -n "\${${name}+x}" ]; then`);
|
|
1032
|
-
lines.push(" umask 077");
|
|
1033
|
-
lines.push(` printf '%s' "\$${name}" > "$WORK/${name}"`);
|
|
1034
|
-
lines.push(` unset ${name}`);
|
|
1035
|
-
lines.push(` SECRET_FILES="$SECRET_FILES --secret-file ${name}=$WORK/${name}"`);
|
|
1036
|
-
lines.push("fi");
|
|
1037
|
-
}
|
|
1038
|
-
for (const { name } of nonSecrets) {
|
|
1039
|
-
lines.push(`if [ -n "\${${name}+x}" ]; then`);
|
|
1040
|
-
lines.push(` VARS="$VARS --var ${name}=\$${name}"`);
|
|
1041
|
-
lines.push("fi");
|
|
1042
|
-
}
|
|
1043
|
-
const generateFlags = secrets
|
|
1044
|
-
.filter((item) => item.param.generate === true)
|
|
1045
|
-
.map((item) => `--generate-secret ${item.name}`)
|
|
1046
|
-
.join(" ");
|
|
1047
|
-
lines.push(`"$INSTALLER" --socket "$SOCKET" --phase ${phase} --attempt-id "$ATTEMPT_ID" \\`);
|
|
1048
|
-
lines.push(` --package-identity "${contract.package}" --package-version "\${SYNOPKG_PKGVER}" \\`);
|
|
1049
|
-
lines.push(' --package-path "$PACKAGE_ROOT/target" --bundle-path "$PACKAGE_ROOT/target" \\');
|
|
1050
|
-
lines.push(' --pkg-var "$PACKAGE_ROOT/var" --pkg-home "$PACKAGE_ROOT/home" \\');
|
|
1051
|
-
if (generateFlags) {
|
|
1052
|
-
lines.push(` ${generateFlags} \\`);
|
|
1053
|
-
}
|
|
1054
|
-
lines.push(' $VARS $SECRET_FILES');
|
|
1055
|
-
lines.push("exit $?");
|
|
1056
|
-
return `${lines.join("\n")}\n`;
|
|
907
|
+
throw new Error("Unsupported container route");
|
|
1057
908
|
}
|
|
1058
909
|
async function createDeterministicSpk(stagingDir, outputPath) {
|
|
1059
910
|
const payloadDir = join(stagingDir, "package");
|