Compare commits

..
Author SHA1 Message Date
Naeel 4dc0c5637f docs: add custom fork header to README (multi-tenant by Naeel/ngcloud) 2026-05-04 16:59:09 +03:00
Naeel 0cae275dbd executor: update gpm.podLister in AddNamespace to fix IsValid nil panic 2026-04-27 14:43:10 +03:00
Naeel 775845b55c executor: preserve generation in untap metadata 2026-04-27 13:37:30 +03:00
Naeel c9036f716f layer2: add single-file chat handoff 2026-04-26 16:38:37 +03:00
Naeel 4349d0b239 layer2: add chat handoff note 2026-04-26 16:34:49 +03:00
Naeel 63ce6ea135 layer1: close namespace manager step1 2026-04-26 16:27:53 +03:00
Naeel 7b6ff84188 layer1: harden namespace watcher logging path 2026-04-26 16:27:20 +03:00
Naeel 55d0b5a9e7 layer1: log namespace watcher startup summary 2026-04-26 16:24:29 +03:00
Naeel 813617ffd1 layer1: log watcher namespace transitions 2026-04-26 11:52:06 +03:00
Naeel 7d7fe561a8 layer1: log namespace summary active flag 2026-04-26 11:51:03 +03:00
Naeel fed69da335 layer1: add namespace summary active helper 2026-04-26 11:46:47 +03:00
Naeel 9f0e911b9d layer1: stabilize namespace summary contract 2026-04-26 11:46:15 +03:00
Naeel f4a3bffc6b layer1: test namespace manager summary logging 2026-04-26 11:45:13 +03:00
Naeel 90924cdec7 layer1: checkpoint namespace manager runtime series 2026-04-26 11:44:36 +03:00
Naeel 6e037a506d layer1: add default watcher config helper 2026-04-26 11:03:39 +03:00
Naeel d24605a8b8 layer1: fix managed watcher config wiring 2026-04-26 11:02:54 +03:00
Naeel d2ff55f9e0 layer1: add managed watcher config 2026-04-26 11:02:09 +03:00
Naeel b9236698f3 layer1: run managed namespace watchers 2026-04-26 11:01:05 +03:00
Naeel 073f2c1504 layer1: add live namespace counts 2026-04-26 10:59:39 +03:00
Naeel b93e720e12 layer1: add namespace source counts 2026-04-26 10:59:01 +03:00
Naeel f16aa030db layer1: log namespace manager summary 2026-04-26 10:57:29 +03:00
Naeel 5c481b7293 layer1: add namespace manager summary 2026-04-26 10:55:56 +03:00
Naeel 67db8d71f1 layer1: fix watcher preparation imports 2026-04-26 10:54:51 +03:00
Naeel 2bbed95c2a layer1: prepare managed namespace watchers 2026-04-26 10:54:24 +03:00
Naeel a1517ba4b2 layer1: share managed namespace watcher startup 2026-04-26 10:51:31 +03:00
Naeel 49be1db3a0 layer1: share namespace watcher event handlers 2026-04-26 10:50:28 +03:00
Naeel c3b161da83 layer1: share update removal policy 2026-04-26 10:49:26 +03:00
Naeel 0755319fac layer1: formalize namespace removal strategy 2026-04-26 10:48:42 +03:00
Naeel 340b9cae84 layer1: centralize namespace watcher handlers 2026-04-26 10:47:12 +03:00
Naeel 4cd4bc9507 layer1: share namespace watcher lifecycle helpers 2026-04-26 10:45:03 +03:00
Naeel 0e08664ef6 layer1: share watcher namespace manager bootstrap 2026-04-26 10:41:14 +03:00
Naeel d7497dcd34 layer1: remove old namespace watcher helpers 2026-04-26 10:40:36 +03:00
Naeel 447133d5b2 layer1: track namespace removals in manager 2026-04-26 10:39:59 +03:00
Naeel b6f3640bbe layer1: add namespace tombstone helper step 34 2026-04-26 10:39:11 +03:00
Naeel d09bee3431 layer1: add namespace remove dispatch step 33 2026-04-26 10:36:48 +03:00
Naeel 488157963a layer1: bootstrap executor namespace manager 2026-04-26 10:35:50 +03:00
Naeel 804bc533db layer1: bootstrap router namespace manager 2026-04-26 10:35:29 +03:00
Naeel 65837610a1 layer1: bootstrap builder namespace manager 2026-04-26 10:35:09 +03:00
Naeel dd7470922c layer1: hook executor watcher to namespace manager 2026-04-26 10:34:34 +03:00
Naeel 0135a93a30 layer1: hook router watcher to namespace manager 2026-04-26 10:34:04 +03:00
Naeel b12a8e5e75 layer1: hook builder watcher to namespace manager 2026-04-26 10:33:36 +03:00
Naeel ad0f83fd4b layer1: add namespace bootstrap dispatch step 26 2026-04-26 10:32:43 +03:00
Naeel 6f77fa5a9a layer1: add executor namespace subscriber step 25 2026-04-26 10:31:54 +03:00
Naeel 331f531962 layer1: factor executor namespace registration step 24 2026-04-26 10:30:59 +03:00
Naeel 346399d35f layer1: align router watcher flow step 23 2026-04-26 10:29:43 +03:00
Naeel 33a08f00b3 layer1: fix router namespace subscriber syntax 2026-04-26 10:29:19 +03:00
Naeel 2971029c42 layer1: add router namespace subscriber step 22 2026-04-26 10:28:57 +03:00
Naeel 3159fba65b layer1: align builder watcher flow step 21 2026-04-26 10:27:09 +03:00
Naeel b200b8bb5b layer1: fix builder namespace subscriber syntax 2026-04-26 10:26:40 +03:00
Naeel 126f7cc51c layer1: add builder namespace subscriber step 20 2026-04-26 10:26:13 +03:00
Naeel bcf34d6b1a layer1: add namespace subscriber adapter step 19 2026-04-26 10:24:01 +03:00
Naeel 022960ade7 layer1: add namespace event bridge step 18 2026-04-26 10:23:21 +03:00
Naeel b1e2e6462d layer1: add namespace dispatch step 17 2026-04-26 10:22:35 +03:00
Naeel ae8275d0a7 layer1: add namespace lifecycle subscribers step 16 2026-04-26 10:21:26 +03:00
Naeel 2857398e11 layer1: checkpoint pending utils changes 2026-04-26 10:20:56 +03:00
Naeel 834c0de941 layer1: add namespace event helpers step 15 2026-04-26 10:05:51 +03:00
Naeel db4499d8c7 layer1: add namespace part helpers step 14 2026-04-26 10:05:12 +03:00
Naeel b3f99b2b6c layer1: centralize managed namespace labels step 13 2026-04-26 10:04:18 +03:00
Naeel 5e5058ba0e layer1: add namespace manager bridge step 12 2026-04-26 10:03:09 +03:00
Naeel 42acce308f layer1: add namespace bootstrap step 11 2026-04-26 10:02:37 +03:00
Naeel 66a3dc2a3c layer1: derive namespace phases step 10 2026-04-26 10:02:03 +03:00
Naeel 910f65b6d4 layer1: add namespace manager subscribers step 9 2026-04-26 10:01:21 +03:00
Naeel 114d5b99af layer1: add namespace manager skeleton step 8 2026-04-26 10:00:45 +03:00
Naeel ac2638f17d layer1: add namespace manager model step 7 2026-04-26 09:54:23 +03:00
Naeel 97b13a13c2 doc: add namespace manager target design 2026-04-26 09:53:06 +03:00
Naeel 1f53bc1fb7 doc: add detailed namespace rewrite logic 2026-04-26 09:50:06 +03:00
Naeel 87477d4529 layer1: guard router informer maps step 6 2026-04-26 09:37:09 +03:00
Naeel 94f26b69ee layer1: fix newdeploy namespace parity step 5 2026-04-26 09:35:39 +03:00
Naeel 56a499a59f layer1: fix buildermgr namespace dedup step 4 2026-04-26 09:34:46 +03:00
Naeel 6102b277c8 layer1: migrate runtime loops to snapshots step 3 2026-04-26 09:33:36 +03:00
Naeel 9ce9829f3b layer1: fix sa namespace routing step 2 2026-04-26 09:32:08 +03:00
Naeel c987fa07e8 layer1: add namespace snapshot api step 1 2026-04-26 09:30:51 +03:00
Naeel 27a280bc03 doc: record debugging comparison notes 2026-04-26 09:11:18 +03:00
Naeel e2dff8db09 doc: add detailed layer1 multi-tenant fix report 2026-04-26 09:06:44 +03:00
Naeel 7faaa9dc1f rbac: allow router namespace watch in multi-tenant mode 2026-04-26 09:03:15 +03:00
Naeel f617913ad9 rbac: allow full fetcher role provisioning in dynamic namespaces 2026-04-26 08:59:02 +03:00
Naeel 8ccc9fb342 rbac: add fission-executor-sa-provisioner for SA/Role/RoleBinding creation in user NS
Fixes EnsureNamespaceSA getting 403 Forbidden when provisioning fission-fetcher
SA in dynamically registered namespaces. Adds ClusterRole + ClusterRoleBinding
with create/update/patch for serviceaccounts, roles, rolebindings.

Also adds doc/progress.md and doc/thinking/2026-04-26-rbac-fix.md.
2026-04-26 07:46:33 +03:00
Naeel 161de70576 multi-tenant: EnsureNamespaceSA + ns_watcher SA provisioning (v8) 2026-04-26 07:41:46 +03:00
82e1ff76a5 Add npm dependabot rules (#3293)
* Add npm dependabot rules

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* Update .github/dependabot.yml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by:  Sanket Sudake <sanketsudake@gmail.com>

---------

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-16 10:33:52 +05:30
Sanket SudakeandGitHub e7cfb06afa Update dependabot.yml for formatting and ignore rules (#3292)
* Update dependabot.yml for formatting and ignore rules

Adjusted formatting and added ignore rules for dependencies in test directories.

Signed-off-by:  Sanket Sudake <sanketsudake@gmail.com>

* Fix dependabot file

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* code cleanup

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* All paths under test ignore

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* more fix

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

---------

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>
2025-12-15 13:30:10 +05:30
Sanket SudakeandGitHub d9d9d226d3 Chart version update (#3291)
* Helm K8s minimum version to 1.28

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* Workflow image changes

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* Update tools version

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

---------

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>
2025-12-15 12:04:14 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Sanket Sudake
bcd1872ffa Bump github.com/opencontainers/runc (#3275)
Bumps the go_modules group with 1 update in the / directory: [github.com/opencontainers/runc](https://github.com/opencontainers/runc).


Updates `github.com/opencontainers/runc` from 1.2.3 to 1.2.8
- [Release notes](https://github.com/opencontainers/runc/releases)
- [Changelog](https://github.com/opencontainers/runc/blob/v1.2.8/CHANGELOG.md)
- [Commits](https://github.com/opencontainers/runc/compare/v1.2.3...v1.2.8)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/runc
  dependency-version: 1.2.8
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sanket Sudake <sanketsudake@gmail.com>
2025-12-15 10:22:27 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0bd3a5957b Bump k8s.io/apiextensions-apiserver in the go-dependencies group (#3288)
Bumps the go-dependencies group with 1 update: [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver).


Updates `k8s.io/apiextensions-apiserver` from 0.34.2 to 0.34.3
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.34.2...v0.34.3)

---
updated-dependencies:
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 09:51:10 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
a450dfebc7 Bump the docker-images group across 5 directories with 1 update (#3289)
Bumps the docker-images group with 1 update in the /cmd/builder directory: [chainguard/static](https://github.com/chainguard-images/images).
Bumps the docker-images group with 1 update in the /cmd/fetcher directory: [chainguard/static](https://github.com/chainguard-images/images).
Bumps the docker-images group with 1 update in the /cmd/fission-bundle directory: [chainguard/static](https://github.com/chainguard-images/images).
Bumps the docker-images group with 1 update in the /cmd/preupgradechecks directory: [chainguard/static](https://github.com/chainguard-images/images).
Bumps the docker-images group with 1 update in the /cmd/reporter directory: [chainguard/static](https://github.com/chainguard-images/images).


Updates `chainguard/static` from `d44809c` to `a301031`
- [Commits](https://github.com/chainguard-images/images/commits)

Updates `chainguard/static` from `d44809c` to `a301031`
- [Commits](https://github.com/chainguard-images/images/commits)

Updates `chainguard/static` from `d44809c` to `a301031`
- [Commits](https://github.com/chainguard-images/images/commits)

Updates `chainguard/static` from `d44809c` to `a301031`
- [Commits](https://github.com/chainguard-images/images/commits)

Updates `chainguard/static` from `d44809c` to `a301031`
- [Commits](https://github.com/chainguard-images/images/commits)

---
updated-dependencies:
- dependency-name: chainguard/static
  dependency-version: latest
  dependency-type: direct:production
  dependency-group: docker-images
- dependency-name: chainguard/static
  dependency-version: latest
  dependency-type: direct:production
  dependency-group: docker-images
- dependency-name: chainguard/static
  dependency-version: latest
  dependency-type: direct:production
  dependency-group: docker-images
- dependency-name: chainguard/static
  dependency-version: latest
  dependency-type: direct:production
  dependency-group: docker-images
- dependency-name: chainguard/static
  dependency-version: latest
  dependency-type: direct:production
  dependency-group: docker-images
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 09:50:13 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5f90095470 Bump the github-actions group with 7 updates (#3290)
Bumps the github-actions group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.13.2` | `2.14.0` |
| [actions/checkout](https://github.com/actions/checkout) | `6.0.0` | `6.0.1` |
| [github/codeql-action](https://github.com/github/codeql-action) | `4.31.5` | `4.31.8` |
| [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) | `9.1.0` | `9.2.0` |
| [codecov/codecov-action](https://github.com/codecov/codecov-action) | `5.5.1` | `5.5.2` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `5.0.0` | `6.0.0` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.20.10` | `0.20.11` |


Updates `step-security/harden-runner` from 2.13.2 to 2.14.0
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/95d9a5deda9de15063e7595e9719c11c38c90ae2...20cf305ff2072d973412fa9b1e3a4f227bda3c76)

Updates `actions/checkout` from 6.0.0 to 6.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/1af3b93b6815bc44a9784bd300feb67ff0d1eeb3...8e8c483db84b4bee98b60c0593521ed34d9990e8)

Updates `github/codeql-action` from 4.31.5 to 4.31.8
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/fdbfb4d2750291e159f0156def62b853c2798ca2...1b168cd39490f61582a9beae412bb7057a6b2c4e)

Updates `golangci/golangci-lint-action` from 9.1.0 to 9.2.0
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/e7fa5ac41e1cf5b7d48e45e42232ce7ada589601...1e7e51e771db61008b38414a730f564565cf7c20)

Updates `codecov/codecov-action` from 5.5.1 to 5.5.2
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/5a1091511ad55cbe89839c7260b706298ca349f7...671740ac38dd9b0130fbe1cec585b89eea48d3de)

Updates `actions/upload-artifact` from 5.0.0 to 6.0.0
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/330a01c490aca151604b8cf639adc76d48f6c5d4...b7c566a772e6b6bfb58ed0dc250532a479d7789f)

Updates `anchore/sbom-action` from 0.20.10 to 0.20.11
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/fbfd9c6c189226748411491745178e0c2017392d...43a17d6e7add2b5535efe4dcae9952337c479a93)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: actions/checkout
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action
  dependency-version: 4.31.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: golangci/golangci-lint-action
  dependency-version: 9.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: codecov/codecov-action
  dependency-version: 5.5.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: actions/upload-artifact
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 09:49:37 +05:30
Sanket SudakeandGitHub eb865e137f Changes in goreleaser (#3274)
* Changes in goreleaser

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* few more fixes

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* Test release

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* use setup-buildx action

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* Project name

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* changes in cosign

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* Fix image digest

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* Verify provenance

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* temp commit

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* few more changes

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* fix attestations write permission

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* Try pushing provenance to registry

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* Simplify provenance and sbom for images

* Sign all artifacts

* Change repo to fission

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* fix docker builds for skaffold

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

* Fix sed commands

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

---------

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>
2025-12-14 17:43:22 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b7819fda76 Bump the docker-images group across 5 directories with 1 update (#3277)
Bumps the docker-images group with 1 update in the /cmd/builder directory: [chainguard/static](https://github.com/chainguard-images/images).
Bumps the docker-images group with 1 update in the /cmd/fetcher directory: [chainguard/static](https://github.com/chainguard-images/images).
Bumps the docker-images group with 1 update in the /cmd/fission-bundle directory: [chainguard/static](https://github.com/chainguard-images/images).
Bumps the docker-images group with 1 update in the /cmd/preupgradechecks directory: [chainguard/static](https://github.com/chainguard-images/images).
Bumps the docker-images group with 1 update in the /cmd/reporter directory: [chainguard/static](https://github.com/chainguard-images/images).


Updates `chainguard/static` from `939a132` to `d4c20db`
- [Commits](https://github.com/chainguard-images/images/commits)

Updates `chainguard/static` from `939a132` to `d4c20db`
- [Commits](https://github.com/chainguard-images/images/commits)

Updates `chainguard/static` from `939a132` to `d4c20db`
- [Commits](https://github.com/chainguard-images/images/commits)

Updates `chainguard/static` from `939a132` to `d4c20db`
- [Commits](https://github.com/chainguard-images/images/commits)

Updates `chainguard/static` from `939a132` to `d4c20db`
- [Commits](https://github.com/chainguard-images/images/commits)

---
updated-dependencies:
- dependency-name: chainguard/static
  dependency-version: latest
  dependency-type: direct:production
  dependency-group: docker-images
- dependency-name: chainguard/static
  dependency-version: latest
  dependency-type: direct:production
  dependency-group: docker-images
- dependency-name: chainguard/static
  dependency-version: latest
  dependency-type: direct:production
  dependency-group: docker-images
- dependency-name: chainguard/static
  dependency-version: latest
  dependency-type: direct:production
  dependency-group: docker-images
- dependency-name: chainguard/static
  dependency-version: latest
  dependency-type: direct:production
  dependency-group: docker-images
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-14 16:46:15 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0e2883d0c6 Bump the github-actions group across 1 directory with 9 updates (#3282)
Bumps the github-actions group with 9 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.13.1` | `2.13.2` |
| [actions/checkout](https://github.com/actions/checkout) | `5.0.0` | `6.0.0` |
| [actions/setup-go](https://github.com/actions/setup-go) | `6.0.0` | `6.1.0` |
| [github/codeql-action](https://github.com/github/codeql-action) | `4.31.2` | `4.31.4` |
| [actions/dependency-review-action](https://github.com/actions/dependency-review-action) | `4.8.1` | `4.8.2` |
| [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) | `8.0.0` | `9.1.0` |
| [helm/kind-action](https://github.com/helm/kind-action) | `1.12.0` | `1.13.0` |
| [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `3.6.0` | `3.7.0` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.20.9` | `0.20.10` |



Updates `step-security/harden-runner` from 2.13.1 to 2.13.2
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a...95d9a5deda9de15063e7595e9719c11c38c90ae2)

Updates `actions/checkout` from 5.0.0 to 6.0.0
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/08c6903cd8c0fde910a37f88322edcfb5dd907a8...1af3b93b6815bc44a9784bd300feb67ff0d1eeb3)

Updates `actions/setup-go` from 6.0.0 to 6.1.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/44694675825211faa026b3c33043df3e48a5fa00...4dc6199c7b1a012772edbd06daecab0f50c9053c)

Updates `github/codeql-action` from 4.31.2 to 4.31.4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/0499de31b99561a6d14a36a5f662c2a54f91beee...e12f0178983d466f2f6028f5cc7a6d786fd97f4b)

Updates `actions/dependency-review-action` from 4.8.1 to 4.8.2
- [Release notes](https://github.com/actions/dependency-review-action/releases)
- [Commits](https://github.com/actions/dependency-review-action/compare/40c09b7dc99638e5ddb0bfd91c1673effc064d8a...3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261)

Updates `golangci/golangci-lint-action` from 8.0.0 to 9.1.0
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/4afd733a84b1f43292c63897423277bb7f4313a9...e7fa5ac41e1cf5b7d48e45e42232ce7ada589601)

Updates `helm/kind-action` from 1.12.0 to 1.13.0
- [Release notes](https://github.com/helm/kind-action/releases)
- [Commits](https://github.com/helm/kind-action/compare/a1b0e391336a6ee6713a0583f8c6240d70863de3...92086f6be054225fa813e0a4b13787fc9088faab)

Updates `docker/setup-qemu-action` from 3.6.0 to 3.7.0
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/29109295f81e9208d7d86ff1c6c12d2833863392...c7c53464625b32c7a7e944ae62b3e17d2b600130)

Updates `anchore/sbom-action` from 0.20.9 to 0.20.10
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/8e94d75ddd33f69f691467e42275782e4bfefe84...fbfd9c6c189226748411491745178e0c2017392d)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: actions/checkout
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-go
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/codeql-action
  dependency-version: 4.31.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: actions/dependency-review-action
  dependency-version: 4.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: golangci/golangci-lint-action
  dependency-version: 9.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: helm/kind-action
  dependency-version: 1.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/setup-qemu-action
  dependency-version: 3.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-11 15:35:12 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Sanket Sudake
a8322b5ed2 Bump the go-dependencies group across 1 directory with 22 updates (#3286)
* Bump the go-dependencies group across 1 directory with 22 updates

Bumps the go-dependencies group with 13 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) | `5.16.3` | `5.16.4` |
| [github.com/kedacore/keda/v2](https://github.com/kedacore/keda) | `2.18.0` | `2.18.2` |
| [github.com/minio/minio-go/v7](https://github.com/minio/minio-go) | `7.0.95` | `7.0.97` |
| [github.com/prometheus/common](https://github.com/prometheus/common) | `0.67.2` | `0.67.4` |
| [github.com/spf13/cobra](https://github.com/spf13/cobra) | `1.10.1` | `1.10.2` |
| [go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp](https://github.com/open-telemetry/opentelemetry-go-contrib) | `0.63.0` | `0.64.0` |
| [go.opentelemetry.io/contrib/propagators/autoprop](https://github.com/open-telemetry/opentelemetry-go-contrib) | `0.63.0` | `0.64.0` |
| [go.opentelemetry.io/otel/exporters/otlp/otlptrace](https://github.com/open-telemetry/opentelemetry-go) | `1.38.0` | `1.39.0` |
| [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc](https://github.com/open-telemetry/opentelemetry-go) | `1.38.0` | `1.39.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.47.0` | `0.48.0` |
| [k8s.io/metrics](https://github.com/kubernetes/metrics) | `0.34.1` | `0.34.3` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.22.3` | `0.22.4` |
| [sigs.k8s.io/structured-merge-diff/v6](https://github.com/kubernetes-sigs/structured-merge-diff) | `6.3.0` | `6.3.1` |



Updates `github.com/go-git/go-git/v5` from 5.16.3 to 5.16.4
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.16.3...v5.16.4)

Updates `github.com/kedacore/keda/v2` from 2.18.0 to 2.18.2
- [Release notes](https://github.com/kedacore/keda/releases)
- [Changelog](https://github.com/kedacore/keda/blob/main/CHANGELOG.md)
- [Commits](https://github.com/kedacore/keda/compare/v2.18.0...v2.18.2)

Updates `github.com/minio/minio-go/v7` from 7.0.95 to 7.0.97
- [Release notes](https://github.com/minio/minio-go/releases)
- [Commits](https://github.com/minio/minio-go/compare/v7.0.95...v7.0.97)

Updates `github.com/prometheus/common` from 0.67.2 to 0.67.4
- [Release notes](https://github.com/prometheus/common/releases)
- [Changelog](https://github.com/prometheus/common/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/common/compare/v0.67.2...v0.67.4)

Updates `github.com/spf13/cobra` from 1.10.1 to 1.10.2
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.10.1...v1.10.2)

Updates `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` from 0.63.0 to 0.64.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.63.0...zpages/v0.64.0)

Updates `go.opentelemetry.io/contrib/propagators/autoprop` from 0.63.0 to 0.64.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.63.0...zpages/v0.64.0)

Updates `go.opentelemetry.io/otel` from 1.38.0 to 1.39.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.38.0...v1.39.0)

Updates `go.opentelemetry.io/otel/exporters/otlp/otlptrace` from 1.38.0 to 1.39.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.38.0...v1.39.0)

Updates `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` from 1.38.0 to 1.39.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.38.0...v1.39.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.38.0 to 1.39.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.38.0...v1.39.0)

Updates `go.opentelemetry.io/otel/trace` from 1.38.0 to 1.39.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.38.0...v1.39.0)

Updates `go.uber.org/zap` from 1.27.0 to 1.27.1
- [Release notes](https://github.com/uber-go/zap/releases)
- [Changelog](https://github.com/uber-go/zap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uber-go/zap/compare/v1.27.0...v1.27.1)

Updates `golang.org/x/net` from 0.47.0 to 0.48.0
- [Commits](https://github.com/golang/net/compare/v0.47.0...v0.48.0)

Updates `google.golang.org/grpc` from 1.76.0 to 1.77.0
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.76.0...v1.77.0)

Updates `k8s.io/api` from 0.34.1 to 0.34.2
- [Commits](https://github.com/kubernetes/api/compare/v0.34.1...v0.34.2)

Updates `k8s.io/apiextensions-apiserver` from 0.34.1 to 0.34.2
- [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases)
- [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.34.1...v0.34.2)

Updates `k8s.io/apimachinery` from 0.34.1 to 0.34.2
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.34.1...v0.34.2)

Updates `k8s.io/client-go` from 0.34.1 to 0.34.2
- [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes/client-go/compare/v0.34.1...v0.34.2)

Updates `k8s.io/metrics` from 0.34.1 to 0.34.3
- [Commits](https://github.com/kubernetes/metrics/compare/v0.34.1...v0.34.3)

Updates `sigs.k8s.io/controller-runtime` from 0.22.3 to 0.22.4
- [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases)
- [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.22.3...v0.22.4)

Updates `sigs.k8s.io/structured-merge-diff/v6` from 6.3.0 to 6.3.1
- [Release notes](https://github.com/kubernetes-sigs/structured-merge-diff/releases)
- [Changelog](https://github.com/kubernetes-sigs/structured-merge-diff/blob/master/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/structured-merge-diff/compare/v6.3.0...v6.3.1)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-git/v5
  dependency-version: 5.16.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: github.com/kedacore/keda/v2
  dependency-version: 2.18.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: github.com/minio/minio-go/v7
  dependency-version: 7.0.97
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: github.com/prometheus/common
  dependency-version: 0.67.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: github.com/spf13/cobra
  dependency-version: 1.10.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
  dependency-version: 0.64.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-dependencies
- dependency-name: go.opentelemetry.io/contrib/propagators/autoprop
  dependency-version: 0.64.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-dependencies
- dependency-name: go.opentelemetry.io/otel
  dependency-version: 1.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-dependencies
- dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace
  dependency-version: 1.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-dependencies
- dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
  dependency-version: 1.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-dependencies
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-version: 1.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-dependencies
- dependency-name: go.opentelemetry.io/otel/trace
  dependency-version: 1.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-dependencies
- dependency-name: go.uber.org/zap
  dependency-version: 1.27.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: golang.org/x/net
  dependency-version: 0.48.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-dependencies
- dependency-name: google.golang.org/grpc
  dependency-version: 1.77.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-dependencies
- dependency-name: k8s.io/api
  dependency-version: 0.34.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: k8s.io/apiextensions-apiserver
  dependency-version: 0.34.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.34.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: k8s.io/client-go
  dependency-version: 0.34.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: k8s.io/metrics
  dependency-version: 0.34.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: sigs.k8s.io/controller-runtime
  dependency-version: 0.22.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
- dependency-name: sigs.k8s.io/structured-merge-diff/v6
  dependency-version: 6.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix webhook publisher lint issue

Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sanket Sudake <sanketsudake@gmail.com>
2025-12-11 15:34:01 +05:30
Sanket SudakeandGitHub 43dc34ee8f Remove dashboard linter from tool dependency (#3285)
Signed-off-by: Sanket Sudake <sanketsudake@gmail.com>
2025-12-11 11:27:19 +05:30
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0300051e7c Bump golang.org/x/crypto from 0.43.0 to 0.45.0 (#3280)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.43.0 to 0.45.0.
- [Commits](https://github.com/golang/crypto/compare/v0.43.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 12:57:21 +05:30
125 changed files with 6818 additions and 1046 deletions
+26
View File
@@ -20,6 +20,8 @@ updates:
schedule:
interval: weekly
open-pull-requests-limit: 5
exclude-paths:
- "test/**"
groups:
docker-images:
patterns:
@@ -30,7 +32,31 @@ updates:
schedule:
interval: weekly
open-pull-requests-limit: 5
exclude-paths:
- "test/**"
groups:
go-dependencies:
patterns:
- "*"
- package-ecosystem: helm
directory: /charts/fission-all
schedule:
interval: weekly
open-pull-requests-limit: 5
groups:
helm-charts:
patterns:
- "*"
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
exclude-paths:
- "test/**"
groups:
npm-dependencies:
patterns:
- "*"
+5 -5
View File
@@ -28,23 +28,23 @@ jobs:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-ci') }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- name: Check out code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: setup go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version-file: "go.mod"
cache: true
- name: Initialize CodeQL
uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
uses: github/codeql-action/init@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
with:
languages: go
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
uses: github/codeql-action/analyze@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
+3 -3
View File
@@ -21,11 +21,11 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- name: 'Checkout Repository'
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: 'Dependency Review'
uses: actions/dependency-review-action@40c09b7dc99638e5ddb0bfd91c1673effc064d8a # v4.8.1
uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2
+3 -3
View File
@@ -21,15 +21,15 @@ jobs:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-ci') }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- name: Check out code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version-file: "go.mod"
+6 -6
View File
@@ -17,7 +17,7 @@ on:
- go.sum
env:
GOLANGCI_LINT_VERSION: v2.6.0
GOLANGCI_LINT_VERSION: v2.6.2
GOLANGCI_LINT_TIMEOUT: 5m
permissions:
@@ -36,15 +36,15 @@ jobs:
# if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-ci') }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- name: Check out code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version-file: "go.mod"
cache: true
@@ -55,7 +55,7 @@ jobs:
go mod download
- name: Run golangci-lint
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
with:
skip-cache: true
version: ${{ env.GOLANGCI_LINT_VERSION }}
@@ -76,7 +76,7 @@ jobs:
run: ./hack/runtests.sh
- name: Upload Coverage report to CodeCov
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: unittests
+22 -21
View File
@@ -22,9 +22,10 @@ on:
- go.sum
env:
HELM_VERSION: v3.19.0
HELM_VERSION: v4.0.1
KIND_VERSION: v0.30.0
KIND_CLUSTER_NAME: kind
SKAFFOLD_VERSION: v2.17.0
permissions:
contents: read
@@ -41,25 +42,25 @@ jobs:
strategy:
fail-fast: false
matrix:
kindversion: ["v1.28.15", "v1.30.8", "v1.32.0"]
kindversion: ["v1.28.15", "v1.32.8", "v1.34.0"]
os: [ubuntu-24.04]
steps:
- name: Harden Runner
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- name: Checkout sources
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: setup go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version-file: "go.mod"
cache: true
- name: Checkout sources
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
repository: fission/examples
path: examples
@@ -70,7 +71,7 @@ jobs:
version: ${{ env.HELM_VERSION }}
- name: Kind Cluster
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
with:
node_image: kindest/node:${{ matrix.kindversion }}
version: ${{ env.KIND_VERSION }}
@@ -91,7 +92,7 @@ jobs:
- name: Install Skaffold
run: |
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/v2.14.0/skaffold-linux-amd64
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/${{ env.SKAFFOLD_VERSION }}/skaffold-linux-amd64
sudo install skaffold /usr/local/bin/
skaffold version
@@ -157,7 +158,7 @@ jobs:
- name: Archive fission dump
timeout-minutes: 10
if: ${{ failure() || cancelled() }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: fission-dump-${{ github.run_id }}-${{ matrix.kindversion }}
path: fission-dump/*.zip
@@ -166,7 +167,7 @@ jobs:
- name: Archive prometheus dump
timeout-minutes: 10
if: ${{ always() }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: prom-dump-${{ github.run_id }}-${{ matrix.kindversion }}
path: /tmp/prometheus/*
@@ -175,7 +176,7 @@ jobs:
- name: Archive kind logs
timeout-minutes: 10
if: ${{ always() }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: kind-logs-${{ github.run_id }}-${{ matrix.kindversion }}
path: kind-logs/*
@@ -189,25 +190,25 @@ jobs:
strategy:
fail-fast: false
matrix:
kindversion: ["v1.19.16"]
kindversion: ["v1.31.12"]
os: [ubuntu-24.04]
steps:
- name: Harden Runner
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- name: Checkout sources
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: setup go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version-file: "go.mod"
cache: true
- name: Checkout sources
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
repository: fission/examples
path: examples
@@ -218,7 +219,7 @@ jobs:
version: ${{ env.HELM_VERSION }}
- name: Kind Cluster
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
with:
node_image: kindest/node:${{ matrix.kindversion }}
version: ${{ env.KIND_VERSION }}
@@ -239,7 +240,7 @@ jobs:
- name: Install Skaffold
run: |
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/v2.14.0/skaffold-linux-amd64
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/${{ env.SKAFFOLD_VERSION }}/skaffold-linux-amd64
sudo install skaffold /usr/local/bin/
skaffold version
@@ -308,7 +309,7 @@ jobs:
- name: Archive fission dump
timeout-minutes: 10
if: ${{ failure() || cancelled() }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: fission-dump-${{ github.run_id }}-${{ matrix.kindversion }}
path: fission-dump/*.zip
@@ -317,7 +318,7 @@ jobs:
- name: Archive prometheus dump
timeout-minutes: 10
if: ${{ always() }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: prom-dump-${{ github.run_id }}-${{ matrix.kindversion }}
path: /tmp/prometheus/*
@@ -326,7 +327,7 @@ jobs:
- name: Archive kind logs
timeout-minutes: 10
if: ${{ always() }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: kind-logs-${{ github.run_id }}-${{ matrix.kindversion }}
path: kind-logs/*
+39 -112
View File
@@ -9,33 +9,33 @@ env:
KIND_VERSION: v0.30.0
KIND_NODE_IMAGE_TAG: v1.28.15
KIND_CLUSTER_NAME: kind
COSIGN_VERSION: v3.0.2
COSIGN_VERSION: v3.0.3
jobs:
create-draft-release:
name: Create Draft Release with Goreleaser
outputs:
hashes: ${{ steps.binary.outputs.hashes }}
ghcr_images: ${{ steps.image.outputs.ghcr_images }}
version: ${{ steps.get_version.outputs.VERSION }}
permissions:
contents: write # for goreleaser/goreleaser-action to create a GitHub release
packages: write # for goreleaser/goreleaser-action to upload artifacts to GitHub Packages
id-token: write # for cosign to sign the image and binary
attestations: write # for goreleaser/goreleaser-action to upload attestations
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- name: Check out code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Setup go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version-file: "go.mod"
cache: true
@@ -51,7 +51,7 @@ jobs:
version: "~> v2"
- name: Kind Cluster
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
with:
node_image: kindest/node:${{ env.KIND_NODE_IMAGE_TAG }}
version: ${{ env.KIND_VERSION }}
@@ -59,7 +59,10 @@ jobs:
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Login to ghcr.io
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
@@ -76,7 +79,7 @@ jobs:
- name: Check cosign install!
run: cosign version
- uses: anchore/sbom-action/download-syft@8e94d75ddd33f69f691467e42275782e4bfefe84 #v0.20.9
- uses: anchore/sbom-action/download-syft@43a17d6e7add2b5535efe4dcae9952337c479a93 #v0.20.11
- name: Generate yaml for manifest, Minikube and Openshift installation
run: ${GITHUB_WORKSPACE}/hack/build-yaml.sh $VERSION
@@ -95,15 +98,12 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKER_CLI_EXPERIMENTAL: "enabled"
- name: Generate binary hashes
id: binary
env:
ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}"
run: |
set -euo pipefail
checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path')
echo "hashes=$(cat $checksum_file | base64 -w0)" >> "$GITHUB_OUTPUT"
# Attest binary artifacts
# https://goreleaser.com/customization/attestations/
- name: Attest binary artifacts
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
with:
subject-checksums: ./dist/checksums.txt
- name: Image digest
id: image
@@ -111,7 +111,7 @@ jobs:
ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}"
run: |
set -euo pipefail
image_and_digest=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Docker Manifest") | {name, "digest": (.extra.Digest // .extra.Checksum)} | select(.digest) | {name} + {digest} | join("@") | sub("^sha256:";"")' | grep -v latest)
image_and_digest=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Docker Image") | {name, "digest": (.extra.Digest // .extra.Checksum)} | select(.digest) | {name} + {digest} | join("@") | sub("^sha256:";"")' | grep -v latest)
ghcr_images=$(echo "${image_and_digest}" | grep ghcr.io | jq -R -s -c '
split("\n")
| map(select(. != ""))
@@ -124,40 +124,8 @@ jobs:
)')
echo "ghcr_images=$ghcr_images" >> "$GITHUB_OUTPUT"
binary-provenance:
name: Create Binary Provenance
needs: [create-draft-release]
permissions:
actions: read # To read the workflow path.
id-token: write # To sign the provenance.
contents: write # To add assets to a release.
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 # Do not use commit hash
with:
base64-subjects: "${{ needs.create-draft-release.outputs.hashes }}"
provenance-name: "fission_${{ needs.create-draft-release.outputs.version }}.intoto.jsonl"
upload-assets: true # upload to a new release
draft-release: true # create a draft release
image-provenance-ghcr:
name: Create Image Provenance
needs: [create-draft-release]
strategy:
matrix:
include: ${{ fromJson(needs.create-draft-release.outputs.ghcr_images) }}
permissions:
actions: read
id-token: write
packages: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0 # Do not use commit hash
with:
image: ${{ fromJson(toJson(matrix)).image }}
digest: ${{ fromJson(toJson(matrix)).checksum }}
registry-username: ${{ github.actor }}
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}
image-sbom-ghcr:
name: Create SBOM for container images
image-sbom-provenance-ghcr:
name: Create SBOM & Provenance for container images
# Goreleaser does not support generating SBOM for container images.
needs: [create-draft-release]
runs-on: ubuntu-24.04
@@ -168,9 +136,10 @@ jobs:
actions: write
id-token: write
packages: write
attestations: write
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
- name: Login to GitHub Container Registry
@@ -184,66 +153,24 @@ jobs:
with:
scan-type: "fs"
format: "spdx-json"
output: "spdx.sbom.json"
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
output: "sbom.spdx.json"
- name: Attest SBOM for image
uses: actions/attest-sbom@4651f806c01d8637787e274ac3bdf724ef169f34 # v3.0.0
with:
cosign-release: ${{ env.COSIGN_VERSION }}
- name: Sign image and sbom
env:
IMAGE: ${{ fromJson(toJson(matrix)).image }}
DIGEST: ${{ fromJson(toJson(matrix)).checksum }}
run: |
#!/usr/bin/env bash
set -euo pipefail
cosign attach sbom --sbom spdx.sbom.json $IMAGE@$DIGEST
cosign sign -a git_sha=$GITHUB_SHA --attachment sbom $IMAGE@$DIGEST --yes
binary-provenance-verification-with-slsa-verifier:
name : Verify Binary Provenance
needs: [create-draft-release, binary-provenance]
runs-on: ubuntu-24.04
permissions:
contents: write # To download the assets from draft release.
steps:
- name: Install the verifier
uses: slsa-framework/slsa-verifier/actions/installer@ea584f4502babc6f60d9bc799dbbb13c1caa9ee6 # v2.7.1
- name: Download assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PROVENANCE: ${{ needs.binary-provenance.outputs.provenance-name }}
VERSION: ${{ needs.create-draft-release.outputs.version }}
run: |
set -euo pipefail
echo "repo=$GITHUB_REPOSITORY"
echo "ref=$VERSION"
gh -R "$GITHUB_REPOSITORY" release download "$VERSION" -p "$PROVENANCE"
- name: Verify assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CHECKSUMS: ${{ needs.create-draft-release.outputs.hashes }}
PROVENANCE: ${{ needs.binary-provenance.outputs.provenance-name }}
VERSION: ${{ needs.create-draft-release.outputs.version }}
run: |
set -euo pipefail
echo "CHECKSUMS=$CHECKSUMS"
echo "PROVENANCE=$PROVENANCE"
checksums=$(echo "$CHECKSUMS" | base64 -d)
while read -r line; do
fn=$(echo $line | cut -d ' ' -f2)
echo "Verifying $fn"
gh -R "$GITHUB_REPOSITORY" release download "$VERSION" -p "$fn"
slsa-verifier verify-artifact --provenance-path "$PROVENANCE" \
--source-uri "github.com/$GITHUB_REPOSITORY" \
--source-tag "$VERSION" \
"$fn"
done <<<"$checksums"
sbom-path: sbom.spdx.json
subject-name: ${{ fromJson(toJson(matrix)).image }}
subject-digest: ${{ fromJson(toJson(matrix)).checksum }}
push-to-registry: true
- name: Attest provenance for image
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
with:
subject-name: ${{ fromJson(toJson(matrix)).image }}
subject-digest: ${{ fromJson(toJson(matrix)).checksum }}
push-to-registry: true
image-provenance-verification-with-cosign:
name: Verify Image Provenance
needs: [create-draft-release, image-provenance-ghcr]
needs: [create-draft-release, image-sbom-provenance-ghcr]
strategy:
matrix:
include: ${{ fromJson(needs.create-draft-release.outputs.ghcr_images) }}
@@ -269,7 +196,7 @@ jobs:
run: |
echo "Verifying $IMAGE@$DIGEST"
cosign verify-attestation \
--type slsaprovenance \
--type https://slsa.dev/provenance/v1 \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@refs/tags/v[0-9]+.[0-9]+.[0-9]+$' \
$IMAGE@$DIGEST
--certificate-identity-regexp '^https://github.com/fission/fission/.github/workflows/release.yaml@refs/tags/v[0-9]+\.[0-9]+\.[0-9]+(?:-rc[0-9]+)?$' \
$IMAGE@$DIGEST
+4 -4
View File
@@ -32,12 +32,12 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- name: "Checkout code"
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false
@@ -64,7 +64,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v3.pre.node20
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v3.pre.node20
with:
name: SARIF file
path: results.sarif
@@ -73,6 +73,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
uses: github/codeql-action/upload-sarif@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
with:
sarif_file: results.sarif
+8 -8
View File
@@ -23,7 +23,7 @@ on:
env:
HELM_VERSION: v3.19.0
KIND_VERSION: v0.26.0
KIND_VERSION: v0.30.0
KIND_CLUSTER_NAME: kind
permissions:
@@ -40,19 +40,19 @@ jobs:
strategy:
fail-fast: false
matrix:
kindversion: ["v1.28.15"]
kindversion: ["v1.31.12"]
os: [ubuntu-24.04]
steps:
- name: Harden Runner
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- name: Checkout action sources
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version-file: "go.mod"
cache: true
@@ -63,7 +63,7 @@ jobs:
version: ${{ env.HELM_VERSION }}
- name: Setup Kind Cluster
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
with:
node_image: kindest/node:${{ matrix.kindversion }}
version: ${{ env.KIND_VERSION }}
@@ -118,7 +118,7 @@ jobs:
- name: Archive fission dump
if: ${{ failure() || cancelled() }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: fission-dump-${{ github.run_id }}-${{ matrix.kindversion }}
path: fission-dump/*.zip
@@ -126,7 +126,7 @@ jobs:
- name: Archive kind logs
if: ${{ always() }}
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: kind-logs-${{ github.run_id }}-${{ matrix.kindversion }}
path: kind-logs/*
+81 -218
View File
@@ -70,224 +70,87 @@ builds:
id: reporter
binary: reporter
dir: ./cmd/reporter
dockers:
- &docker-amd64
use: buildx
goos: linux
goarch: amd64
ids:
- builder
image_templates:
- "{{ .Env.GHCR_REPO }}/builder:latest-amd64"
- "{{ .Env.GHCR_REPO }}/builder:{{ .Tag }}-amd64"
dockers_v2:
- id: builder
tags:
- latest
- "{{ .Tag }}"
images:
- "{{ .Env.GHCR_REPO }}/builder"
labels:
org.opencontainers.image.description: "The builder assists in building the fission function source code for deployment."
org.opencontainers.image.source: "{{.GitURL}}"
org.opencontainers.image.created: "{{.Date}}"
org.opencontainers.image.revision: "{{.FullCommit}}"
org.opencontainers.image.version: "{{.Tag}}"
org.opencontainers.image.authors: "The Fission Authors https://fission.io/"
org.opencontainers.image.vendor: "Fission"
org.opencontainers.image.url: "https://fission.io/"
dockerfile: cmd/builder/Dockerfile
build_flag_templates:
- "--label=org.opencontainers.image.description=The builder assists in building the fission function source code for deployment."
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--platform=linux/amd64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Tag}}"
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
- "--label=org.opencontainers.image.vendor=Fission"
- "--label=org.opencontainers.image.url=https://fission.io/"
- <<: *docker-amd64
ids:
- fetcher
image_templates:
- "{{ .Env.GHCR_REPO }}/fetcher:latest-amd64"
- "{{ .Env.GHCR_REPO }}/fetcher:{{ .Tag }}-amd64"
- id: fetcher
tags:
- latest
- "{{ .Tag }}"
images:
- "{{ .Env.GHCR_REPO }}/fetcher"
labels:
org.opencontainers.image.description: "Fetcher is a lightweight component used by environment and builder pods. Fetcher helps in fetch and upload of source/deployment packages and specializing environments."
org.opencontainers.image.source: "{{.GitURL}}"
org.opencontainers.image.created: "{{.Date}}"
org.opencontainers.image.revision: "{{.FullCommit}}"
org.opencontainers.image.version: "{{.Tag}}"
org.opencontainers.image.authors: "The Fission Authors https://fission.io/"
org.opencontainers.image.vendor: "Fission"
org.opencontainers.image.url: "https://fission.io/"
dockerfile: cmd/fetcher/Dockerfile
build_flag_templates:
- "--label=org.opencontainers.image.description=Fetcher is a lightweight component used by environment and builder pods. Fetcher helps in fetch and upload of source/deployment packages and specializing environments."
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--platform=linux/amd64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Tag}}"
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
- "--label=org.opencontainers.image.vendor=Fission"
- "--label=org.opencontainers.image.url=https://fission.io/"
- <<: *docker-amd64
ids:
- fission-bundle
image_templates:
- "{{ .Env.GHCR_REPO }}/fission-bundle:latest-amd64"
- "{{ .Env.GHCR_REPO }}/fission-bundle:{{ .Tag }}-amd64"
- id: fission-bundle
tags:
- latest
- "{{ .Tag }}"
images:
- "{{ .Env.GHCR_REPO }}/fission-bundle"
labels:
org.opencontainers.image.description: "fission-bundle is a component which is a single binary for all components. Most server side components running on server side are fission-bundle binary wrapped in container and used with different arguments."
org.opencontainers.image.source: "{{.GitURL}}"
org.opencontainers.image.created: "{{.Date}}"
org.opencontainers.image.revision: "{{.FullCommit}}"
org.opencontainers.image.version: "{{.Tag}}"
org.opencontainers.image.authors: "The Fission Authors https://fission.io/"
org.opencontainers.image.vendor: "Fission"
org.opencontainers.image.url: "https://fission.io/"
dockerfile: cmd/fission-bundle/Dockerfile
build_flag_templates:
- "--label=org.opencontainers.image.description=fission-bundle is a component which is a single binary for all components. Most server side components running on server side are fission-bundle binary wrapped in container and used with different arguments."
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--platform=linux/amd64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Tag}}"
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
- "--label=org.opencontainers.image.vendor=Fission"
- "--label=org.opencontainers.image.url=https://fission.io/"
- <<: *docker-amd64
ids:
- pre-upgrade-checks
image_templates:
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:latest-amd64"
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:{{ .Tag }}-amd64"
- id: pre-upgrade-checks
tags:
- latest
- "{{ .Tag }}"
images:
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks"
labels:
org.opencontainers.image.description: "Preupgradechecks ensures that Fission is ready for the targeted version upgrade by performing checks beforehand."
org.opencontainers.image.source: "{{.GitURL}}"
org.opencontainers.image.created: "{{.Date}}"
org.opencontainers.image.revision: "{{.FullCommit}}"
org.opencontainers.image.version: "{{.Tag}}"
org.opencontainers.image.authors: "The Fission Authors https://fission.io/"
org.opencontainers.image.vendor: "Fission"
org.opencontainers.image.url: "https://fission.io/"
dockerfile: cmd/preupgradechecks/Dockerfile
build_flag_templates:
- "--label=org.opencontainers.image.description=Preupgradechecks ensures that Fission is ready for the targeted version upgrade by performing checks beforehand."
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--platform=linux/amd64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Tag}}"
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
- "--label=org.opencontainers.image.vendor=Fission"
- "--label=org.opencontainers.image.url=https://fission.io/"
- <<: *docker-amd64
ids:
- reporter
image_templates:
- "{{ .Env.GHCR_REPO }}/reporter:latest-amd64"
- "{{ .Env.GHCR_REPO }}/reporter:{{ .Tag }}-amd64"
- id: reporter
tags:
- latest
- "{{ .Tag }}"
images:
- "{{ .Env.GHCR_REPO }}/reporter"
labels:
org.opencontainers.image.description: "The reporter gathers information that assists in improving fission."
org.opencontainers.image.source: "{{.GitURL}}"
org.opencontainers.image.created: "{{.Date}}"
org.opencontainers.image.revision: "{{.FullCommit}}"
org.opencontainers.image.version: "{{.Tag}}"
org.opencontainers.image.authors: "The Fission Authors https://fission.io/"
org.opencontainers.image.vendor: "Fission"
org.opencontainers.image.url: "https://fission.io/"
dockerfile: cmd/reporter/Dockerfile
build_flag_templates:
- "--label=org.opencontainers.image.description=The reporter gathers information that assists in improving fission."
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--platform=linux/amd64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Tag}}"
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
- "--label=org.opencontainers.image.vendor=Fission"
- "--label=org.opencontainers.image.url=https://fission.io/"
- &docker-arm64
use: buildx
goos: linux
goarch: arm64
ids:
- builder
image_templates:
- "{{ .Env.GHCR_REPO }}/builder:latest-arm64"
- "{{ .Env.GHCR_REPO }}/builder:{{ .Tag }}-arm64"
dockerfile: cmd/builder/Dockerfile
build_flag_templates:
- "--label=org.opencontainers.image.description=The builder assists in building the fission function source code for deployment."
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--platform=linux/arm64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Tag}}"
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
- "--label=org.opencontainers.image.vendor=Fission"
- "--label=org.opencontainers.image.url=https://fission.io/"
- <<: *docker-arm64
ids:
- fetcher
image_templates:
- "{{ .Env.GHCR_REPO }}/fetcher:latest-arm64"
- "{{ .Env.GHCR_REPO }}/fetcher:{{ .Tag }}-arm64"
dockerfile: cmd/fetcher/Dockerfile
build_flag_templates:
- "--label=org.opencontainers.image.description=Fetcher is a lightweight component used by environment and builder pods. Fetcher helps in fetch and upload of source/deployment packages and specializing environments."
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--platform=linux/arm64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Tag}}"
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
- "--label=org.opencontainers.image.vendor=Fission"
- "--label=org.opencontainers.image.url=https://fission.io/"
- <<: *docker-arm64
ids:
- fission-bundle
image_templates:
- "{{ .Env.GHCR_REPO }}/fission-bundle:latest-arm64"
- "{{ .Env.GHCR_REPO }}/fission-bundle:{{ .Tag }}-arm64"
dockerfile: cmd/fission-bundle/Dockerfile
build_flag_templates:
- "--label=org.opencontainers.image.description=fission-bundle is a component which is a single binary for all components. Most server side components running on server side are fission-bundle binary wrapped in container and used with different arguments."
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--platform=linux/arm64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Tag}}"
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
- "--label=org.opencontainers.image.vendor=Fission"
- "--label=org.opencontainers.image.url=https://fission.io/"
- <<: *docker-arm64
ids:
- pre-upgrade-checks
image_templates:
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:latest-arm64"
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:{{ .Tag }}-arm64"
dockerfile: cmd/preupgradechecks/Dockerfile
build_flag_templates:
- "--label=org.opencontainers.image.description=Preupgradechecks ensures that Fission is ready for the targeted version upgrade by performing checks beforehand."
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--platform=linux/arm64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Tag}}"
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
- "--label=org.opencontainers.image.vendor=Fission"
- "--label=org.opencontainers.image.url=https://fission.io/"
- <<: *docker-arm64
ids:
- reporter
image_templates:
- "{{ .Env.GHCR_REPO }}/reporter:latest-arm64"
- "{{ .Env.GHCR_REPO }}/reporter:{{ .Tag }}-arm64"
dockerfile: cmd/reporter/Dockerfile
build_flag_templates:
- "--label=org.opencontainers.image.description=The reporter gathers information that assists in improving fission."
- "--label=org.opencontainers.image.source={{.GitURL}}"
- "--platform=linux/arm64"
- "--label=org.opencontainers.image.created={{.Date}}"
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Tag}}"
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
- "--label=org.opencontainers.image.vendor=Fission"
- "--label=org.opencontainers.image.url=https://fission.io/"
docker_manifests:
- name_template: "{{ .Env.GHCR_REPO }}/builder:{{ .Tag }}"
image_templates:
- "{{ .Env.GHCR_REPO }}/builder:{{ .Tag }}-amd64"
- "{{ .Env.GHCR_REPO }}/builder:{{ .Tag }}-arm64"
- name_template: "{{ .Env.GHCR_REPO }}/fetcher:{{ .Tag }}"
image_templates:
- "{{ .Env.GHCR_REPO }}/fetcher:{{ .Tag }}-amd64"
- "{{ .Env.GHCR_REPO }}/fetcher:{{ .Tag }}-arm64"
- name_template: "{{ .Env.GHCR_REPO }}/fission-bundle:{{ .Tag }}"
image_templates:
- "{{ .Env.GHCR_REPO }}/fission-bundle:{{ .Tag }}-amd64"
- "{{ .Env.GHCR_REPO }}/fission-bundle:{{ .Tag }}-arm64"
- name_template: "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:{{ .Tag }}"
image_templates:
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:{{ .Tag }}-amd64"
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:{{ .Tag }}-arm64"
- name_template: "{{ .Env.GHCR_REPO }}/reporter:{{ .Tag }}"
image_templates:
- "{{ .Env.GHCR_REPO }}/reporter:{{ .Tag }}-amd64"
- "{{ .Env.GHCR_REPO }}/reporter:{{ .Tag }}-arm64"
- name_template: "{{ .Env.GHCR_REPO }}/builder:latest"
image_templates:
- "{{ .Env.GHCR_REPO }}/builder:latest-amd64"
- "{{ .Env.GHCR_REPO }}/builder:latest-arm64"
- name_template: "{{ .Env.GHCR_REPO }}/fetcher:latest"
image_templates:
- "{{ .Env.GHCR_REPO }}/fetcher:latest-amd64"
- "{{ .Env.GHCR_REPO }}/fetcher:latest-arm64"
- name_template: "{{ .Env.GHCR_REPO }}/fission-bundle:latest"
image_templates:
- "{{ .Env.GHCR_REPO }}/fission-bundle:latest-amd64"
- "{{ .Env.GHCR_REPO }}/fission-bundle:latest-arm64"
- name_template: "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:latest"
image_templates:
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:latest-amd64"
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:latest-arm64"
- name_template: "{{ .Env.GHCR_REPO }}/reporter:latest"
image_templates:
- "{{ .Env.GHCR_REPO }}/reporter:latest-amd64"
- "{{ .Env.GHCR_REPO }}/reporter:latest-arm64"
changelog:
disable: true
archives:
@@ -299,7 +162,8 @@ archives:
- binary
checksum:
name_template: "checksums.txt"
algorithm: sha256
docker_digest:
name_template: "docker-digests.txt"
# signs the checksum file
# https://goreleaser.com/customization/sign
@@ -307,13 +171,12 @@ signs:
- id: cosign-binary
env:
- COSIGN_EXPERIMENTAL=1
certificate: "${artifact}.pem"
signature: "${artifact}.sig.bundle"
cmd: cosign
artifacts: binary
artifacts: all
args:
- sign-blob
- "--output-signature=${signature}"
- "--output-certificate=${certificate}"
- "--bundle=${signature}"
- "${artifact}"
- "--yes" # needed for cosign 2.0.0+
+1
View File
@@ -112,6 +112,7 @@ skaffold-prebuild:
@cp -v cmd/fission-bundle/Dockerfile dist/fission-bundle_linux_amd64_v1/Dockerfile
@cp -v cmd/reporter/Dockerfile dist/reporter_linux_amd64_v1/Dockerfile
@cp -v cmd/preupgradechecks/Dockerfile dist/pre-upgrade-checks_linux_amd64_v1/Dockerfile
@find dist/ -name 'Dockerfile' -exec sed -i.bak 's|$$TARGETPLATFORM/||g' {} +; find dist/ -name 'Dockerfile.bak' -delete
skaffold-deploy: skaffold-prebuild
skaffold run -p $(SKAFFOLD_PROFILE)
+79
View File
@@ -0,0 +1,79 @@
# NEXT CHAT: LAYER2 START HERE
Если ты новый агент в новом чате, сначала прочитай этот файл целиком.
## Где работать
Репозиторий: `fission-src`
Ветка:
`rewrite/layer2-namespace-manager-api-step1`
## Что уже готово
Layer1 завершён.
Это значит:
1. Внутренний `NamespaceManager` layer уже реализован.
2. Buildermgr, router и executor/multitenant уже переведены на общий watcher/helper layer.
3. Summary/debug contract стабилизирован.
4. Logging path усилен.
5. Layer1 закрыт commit-ом:
`63ce6ea`
`layer1: close namespace manager step1`
## Что уже было проверено
Целевой прогон для layer1 уже был зелёным:
`go test ./pkg/utils/... ./pkg/buildermgr/... ./pkg/router/... ./pkg/executor/multitenant`
## Что нужно делать теперь
Нужен layer2.
Layer2 = не переписывать watcher-ы заново, а дать внешний read-only status/debug/API surface поверх уже готового `NamespaceManager` слоя.
Цель:
1. Найти лучший существующий read-only endpoint/status/debug surface.
2. Начать аккуратно выносить наружу `NamespaceManagerSummary`.
3. Не менять runtime semantics watcher-ов.
4. Не плодить второй источник правды о namespace state.
## Как работать
1. Работай маленькими шагами.
2. Перед кодом сначала найди правильную точку интеграции.
3. Все новые заметки пиши только в новые файлы в `doc/thinking/`.
4. Не трогай старые doc-файлы.
5. Не запускай background-команды.
6. Все команды запускай только через SSH на VM и всегда с timeout.
## Важные файлы
- `pkg/utils/namespace_manager.go`
- `pkg/utils/namespace_manager_model.go`
- `pkg/utils/namespace_manager_test.go`
- `pkg/buildermgr/ns_watcher.go`
- `pkg/router/ns_watcher.go`
- `pkg/executor/multitenant/ns_watcher.go`
## Первый шаг в новом чате
Сначала не писать код.
Сначала:
1. проверить текущую ветку и чистоту дерева;
2. найти существующий service-level status/debug/API contour;
3. выбрать один безопасный read-only entrypoint для первого шага layer2.
## Текст первого сообщения нового чата
Можно просто вставить это:
"Прочитай файл NEXT_CHAT_LAYER2.md и продолжай работу строго по нему. Нужен layer2: safe read-only API/status/debug surface поверх NamespaceManager без изменения runtime semantics watcher-ов. Сначала найди правильную точку интеграции, потом делай маленькие шаги с документированием в новых файлах doc/thinking/."
+15
View File
@@ -1,3 +1,18 @@
> [!IMPORTANT]
> ## Это форк Fission с поддержкой мультитенантности (multi-tenant)
>
> **Автор доработок:** Naeel / ngcloud
> **Базовая версия:** Fission v1.22.0 (официальный)
> **Репозиторий:** https://gitea.services.ngcloud.ru/Nail/fission-src
>
> ### Что добавлено по сравнению с официальным Fission:
> - **Динамический multi-tenant:** namespace с меткой `fission.io/managed=true` подхватываются без рестарта Fission
> - **Автоматический SA provisioning:** при появлении нового namespace автоматически создаются ServiceAccount, Role, RoleBinding для fetcher/builder
> - **Namespace Manager:** новый компонент в `pkg/utils/` для отслеживания namespace в реальном времени
> - **Обратная совместимость:** полная, поведение идентично официальному если меток нет
---
<p align="center">
<img src="https://fission.io/images/logo-gh.svg" width="300" />
<br>
+3
View File
@@ -0,0 +1,3 @@
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
COPY fission-bundle /
ENTRYPOINT ["/fission-bundle"]
BIN
View File
Binary file not shown.
+2 -3
View File
@@ -1,9 +1,9 @@
apiVersion: v2
name: fission-all
version: v1.22.0
version: 1.22.0
appVersion: v1.22.0
description: Fission is a fast serverless framework for Kubernetes.
kubeVersion: ">=1.27.0-0"
kubeVersion: ">=1.28.0-0"
home: https://fission.io/
icon: https://fission.io/images/fission-logo-white.svg
sources:
@@ -21,7 +21,6 @@ maintainers:
email: vishal@infracloud.io
- name: Sanket Sudake
email: sanket@infracloud.io
engine: gotpl
type: application
annotations:
artifacthub.io/signKey: |
+1 -1
View File
@@ -4,7 +4,7 @@
## Prerequisites
- Kubernetes 1.23+
- Kubernetes 1.28+
- Helm 3+
## Get Repo Info
+3 -2
View File
@@ -1,3 +1,4 @@
FROM cgr.dev/chainguard/static:latest@sha256:939a132511fcbc2702e0e251b6f3ea368c0ad4f114678ae5973903352357d01a
COPY builder /builder
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
ARG TARGETPLATFORM
COPY $TARGETPLATFORM/builder /builder
ENTRYPOINT ["/builder"]
+3 -2
View File
@@ -1,3 +1,4 @@
FROM cgr.dev/chainguard/static:latest@sha256:939a132511fcbc2702e0e251b6f3ea368c0ad4f114678ae5973903352357d01a
COPY fetcher /
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
ARG TARGETPLATFORM
COPY $TARGETPLATFORM/fetcher /
ENTRYPOINT ["/fetcher"]
+3 -2
View File
@@ -1,3 +1,4 @@
FROM cgr.dev/chainguard/static:latest@sha256:939a132511fcbc2702e0e251b6f3ea368c0ad4f114678ae5973903352357d01a
COPY fission-bundle /
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
ARG TARGETPLATFORM
COPY $TARGETPLATFORM/fission-bundle /
ENTRYPOINT ["/fission-bundle"]
+3
View File
@@ -0,0 +1,3 @@
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
COPY fission-bundle /
ENTRYPOINT ["/fission-bundle"]
Binary file not shown.
+3 -2
View File
@@ -1,3 +1,4 @@
FROM cgr.dev/chainguard/static:latest@sha256:939a132511fcbc2702e0e251b6f3ea368c0ad4f114678ae5973903352357d01a
COPY pre-upgrade-checks /
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
ARG TARGETPLATFORM
COPY $TARGETPLATFORM/pre-upgrade-checks /
ENTRYPOINT ["/pre-upgrade-checks"]
+3 -2
View File
@@ -1,3 +1,4 @@
FROM cgr.dev/chainguard/static:latest@sha256:939a132511fcbc2702e0e251b6f3ea368c0ad4f114678ae5973903352357d01a
COPY reporter /
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
ARG TARGETPLATFORM
COPY $TARGETPLATFORM/reporter /
ENTRYPOINT ["/reporter"]
+26
View File
@@ -0,0 +1,26 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fission-executor-ns-watcher
labels:
app: fission-executor
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fission-executor-ns-watcher
labels:
app: fission-executor
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: fission-executor-ns-watcher
subjects:
- kind: ServiceAccount
name: fission-executor
namespace: fission
+122
View File
@@ -0,0 +1,122 @@
# deploy/multitenant/rbac.yaml
#
# RBAC required for the Fission multi-tenant NSWatcher components.
#
# Both fission-executor and fission-router must be allowed to list and watch
# Namespaces at the cluster scope so that their NSWatchers can detect newly-
# labeled Namespaces.
#
# The executor also needs additional write permissions to provision the
# fission-fetcher ServiceAccount/Role/RoleBinding in new namespaces.
# Apply once per cluster after installing Fission:
#
# kubectl apply -f deploy/multitenant/rbac.yaml
#
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fission-executor-ns-watcher
labels:
app.kubernetes.io/name: fission
app.kubernetes.io/component: executor
app.kubernetes.io/part-of: fission-multitenant
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fission-executor-ns-watcher
labels:
app.kubernetes.io/name: fission
app.kubernetes.io/component: executor
app.kubernetes.io/part-of: fission-multitenant
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: fission-executor-ns-watcher
subjects:
- kind: ServiceAccount
name: fission-executor
namespace: fission
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fission-router-ns-watcher
labels:
app.kubernetes.io/name: fission
app.kubernetes.io/component: router
app.kubernetes.io/part-of: fission-multitenant
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fission-router-ns-watcher
labels:
app.kubernetes.io/name: fission
app.kubernetes.io/component: router
app.kubernetes.io/part-of: fission-multitenant
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: fission-router-ns-watcher
subjects:
- kind: ServiceAccount
name: fission-router
namespace: fission
---
# ClusterRole: allows fission-executor to create/update fission-fetcher SA,
# Role and RoleBinding in any user namespace managed by NSWatcher.
#
# It also needs two less-obvious permissions:
# 1. localsubjectaccessreviews.create — setupSAAndRoleBindings checks whether
# the target SA already has each permission before creating missing rules.
# 2. events.create — Kubernetes forbids creating a Role that grants permissions
# the caller does not currently hold. Since fission-fetcher gets events.create,
# fission-executor must hold it too in order to create that Role.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fission-executor-sa-provisioner
labels:
app.kubernetes.io/name: fission
app.kubernetes.io/component: executor
app.kubernetes.io/part-of: fission-multitenant
rules:
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create"]
- apiGroups: ["authorization.k8s.io"]
resources: ["localsubjectaccessreviews"]
verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fission-executor-sa-provisioner
labels:
app.kubernetes.io/name: fission
app.kubernetes.io/component: executor
app.kubernetes.io/part-of: fission-multitenant
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: fission-executor-sa-provisioner
subjects:
- kind: ServiceAccount
name: fission-executor
namespace: fission
+52
View File
@@ -0,0 +1,52 @@
# Fission Multi-Tenant — Progress
## Задача
Добиться 5/5 PASS в `test_layer1.sh`: динамически добавленный NS с меткой `fission.io/managed=true` должен работать без рестарта Fission.
---
## Статус задач
| # | Задача | Статус |
|---|--------|--------|
| 1 | Добавить `EnsureNamespaceSA` в `pkg/utils/serviceaccount.go` | ✅ DONE |
| 2 | Вызов `EnsureNamespaceSA` из `ns_watcher.go` при регистрации NS | ✅ DONE |
| 3 | Сборка образа `naeel/fission-bundle:v1.22.0-multi-ns-8` | ✅ DONE |
| 4 | Деплой образа v8 в кластер (executor/router/buildermgr) | ✅ DONE |
| 5 | Коммит `161de70` "multi-tenant: EnsureNamespaceSA + ns_watcher SA provisioning (v8)" | ✅ DONE |
| 6 | Исправить RBAC: добавить полный набор прав для SA provisioning в `deploy/multitenant/rbac.yaml` | ✅ DONE |
| 7 | Применить RBAC через `kubectl apply`, верифицировать SA/Role/RoleBinding | ✅ DONE |
| 8 | Коммит RBAC fix | 🔄 IN PROGRESS |
| 9 | Запустить `test_layer1.sh`, добиться 5/5 PASS | ⏳ TODO |
---
## Текущий результат теста
`test_layer1.sh` — 4/5:
- Шаг 5 падает: `serviceaccount "fission-fetcher" not found` в NS `l1-test-77773`
## Диагностика (2026-04-26)
- Код `EnsureNamespaceSA` присутствует в `serviceaccount.go`
- `ns_watcher.go` строка 168 вызывает `EnsureNamespaceSA`
- RBAC: `kubectl auth can-i create serviceaccounts --as=...fission-executor -n l1-test-77773`**`no`** ❌
- ClusterRole `fission-executor-multi-ns` не имеет `create` для `serviceaccounts`, и нет rules для `roles`/`rolebindings`
- Вывод: `setupSAAndRoleBindings` вызывается, но получает 403 Forbidden и тихо фейлится → SA не создаётся → pod не стартует
## Решение
Добавить в `deploy/multitenant/rbac.yaml` новый ClusterRole + ClusterRoleBinding с правами:
- `serviceaccounts`: `get/list/watch/create/update/patch`
- `roles`, `rolebindings`: `get/list/watch/create/update/patch`
- `events`: `create`
- `localsubjectaccessreviews.authorization.k8s.io`: `create`
Применить через `kubectl apply`.
**Пересборка образа НЕ нужна** — логика правильная, проблема только в RBAC.
## Последняя верификация
- `kubectl auth can-i create events --as=system:serviceaccount:fission:fission-executor``yes`
- `kubectl auth can-i create localsubjectaccessreviews.authorization.k8s.io --as=system:serviceaccount:fission:fission-executor``yes`
- В новом NS `rbac-verify-83117` автоматически созданы:
- `ServiceAccount/fission-fetcher`
- `Role/fission-fetcher-role-*`
- `RoleBinding/fission-fetcher-rolebinding-*`
@@ -0,0 +1,248 @@
# 2026-04-26 - Layer1 multi-tenant NSWatcher: полный разбор до 5/5 PASS
## Цель
Довести `test_layer1.sh` до `PASS=5 FAIL=0` для сценария:
1. создаётся новый namespace
2. namespace получает label `fission.io/managed=true`
3. Fission без рестарта подхватывает namespace
4. в namespace создаются `Environment`, `Function`, `HTTPTrigger`
5. функция успешно вызывается через router
Ключевое требование: всё должно происходить без rolling restart Fission-компонентов.
## Исходный симптом
Первый устойчивый симптом был таким:
- `test_layer1.sh` стабильно доходил до `4/5`
- шаг вызова функции падал
- в user namespace наблюдалось:
- `FailedCreate`
- `serviceaccount "fission-fetcher" not found`
Это означало, что poolmgr deployment для environment уже создаётся, но pod не может стартовать без `fission-fetcher` ServiceAccount.
## Что уже было исправлено до RBAC-этапа
Кодовая часть hot-registration была уже внедрена ранее:
- `pkg/utils/serviceaccount.go`
- добавлена `EnsureNamespaceSA(...)`
- `pkg/executor/multitenant/ns_watcher.go`
- при регистрации нового namespace вызывается `EnsureNamespaceSA(...)`
- образ `naeel/fission-bundle:v1.22.0-multi-ns-8` уже был собран и задеплоен
То есть логика в коде уже существовала; сбой был не в отсутствии вызова, а в невозможности выполнить его успешно в кластере.
## Диагностика 1: executor не может создать ServiceAccount/Role/RoleBinding
Была проведена проверка прав service account `fission-executor`.
Подтверждено:
- код `EnsureNamespaceSA` вызывается
- `ns_watcher` регистрирует namespace
- executor не имеет достаточных RBAC-прав для provisioning ресурсов в новом namespace
Первый явный пробел:
- отсутствовали права на:
- `serviceaccounts`
- `roles`
- `rolebindings`
После начального RBAC fix было видно, что `ServiceAccount/fission-fetcher` уже создаётся, но этого оказалось недостаточно.
## Диагностика 2: initial RBAC fix оказался неполным
После расширения прав на `serviceaccounts/roles/rolebindings` тест перестал падать на отсутствии SA, но при детальной диагностике выяснилось, что `EnsureNamespaceSA` всё ещё не может полностью создать `Role` для fetcher.
Ключевой лог executor:
```text
error while creating role for sa fission-fetcher in namespace diag-ns-82702
... is attempting to grant RBAC permissions not currently held:
{APIGroups:[""], Resources:["events"], Verbs:["create"]}
```
И дополнительный лог перед этим:
```text
localsubjectaccessreviews.authorization.k8s.io is forbidden
```
### Что это означает
Функция `setupSAAndRoleBindings()` делает две важные вещи:
1. пытается проверить уже существующие права через `LocalSubjectAccessReview`
2. если прав нет, создаёт `Role` с нужными permission-ами
Следовательно executor должен иметь не только право создавать `Role/RoleBinding`, но и:
- `authorization.k8s.io/localsubjectaccessreviews:create`
- все permission-ы, которые он пытается делегировать через создаваемую `Role`
В нашем случае fetcher получает право:
- `events:create`
По правилам Kubernetes нельзя создать `Role`, выдающую право, которого нет у самого вызывающего субъекта. Поэтому executor должен был сам иметь `events:create`.
### Реальный root cause на этом этапе
`fission-executor` не имел:
- `events.create`
- `localsubjectaccessreviews.create`
Из-за этого:
- `ServiceAccount` создавался
- но `Role` и `RoleBinding` создавались не полностью или не создавались вовсе
- downstream specialization ломалась
## Исправление 1: полный executor RBAC для dynamic SA provisioning
В `deploy/multitenant/rbac.yaml` был добавлен и затем расширен `ClusterRole`:
- `fission-executor-sa-provisioner`
Итоговый набор прав для него:
- core:
- `serviceaccounts`: `get`, `list`, `watch`, `create`, `update`, `patch`
- `events`: `create`
- `authorization.k8s.io`:
- `localsubjectaccessreviews`: `create`
- `rbac.authorization.k8s.io`:
- `roles`: `get`, `list`, `watch`, `create`, `update`, `patch`
- `rolebindings`: `get`, `list`, `watch`, `create`, `update`, `patch`
После применения этого манифеста было подтверждено:
- `kubectl auth can-i create events --as=system:serviceaccount:fission:fission-executor` -> `yes`
- `kubectl auth can-i create localsubjectaccessreviews.authorization.k8s.io --as=system:serviceaccount:fission:fission-executor` -> `yes`
И в новом test namespace автоматически появлялись:
- `ServiceAccount/fission-fetcher`
- `Role/fission-fetcher-role-*`
- `RoleBinding/fission-fetcher-rolebinding-*`
## Изменение симптома после executor-fix
После полного executor RBAC fix шаг 5 перестал падать с `500` timeout от executor.
Новый симптом:
- постоянный `HTTP 404`
- router не видел route/function в новом namespace
Это был важный индикатор того, что executor-path уже работает лучше, а оставшаяся проблема находится в router-path.
## Диагностика 3: router NSWatcher не мог watch/list namespaces
Лог router показал прямую ошибку:
```text
failed to list *v1.Namespace: namespaces is forbidden:
User "system:serviceaccount:fission:fission-router" cannot list resource
"namespaces" at the cluster scope
```
При этом код router уже содержал dynamic namespace watcher:
- `pkg/router/ns_watcher.go`
То есть логика была, но RBAC для `fission-router` отсутствовал.
### Реальный root cause на этом этапе
`fission-router` не имел cluster-scope прав:
- `namespaces:list`
- `namespaces:watch`
Из-за этого:
- router не подхватывал новые labeled namespaces
- `HTTPTriggerSet.AddNamespace(...)` не вызывался
- HTTP trigger не попадал в router runtime map
- вызов функции возвращал `404`
## Исправление 2: router RBAC для NSWatcher
В тот же `deploy/multitenant/rbac.yaml` добавлены:
- `ClusterRole/fission-router-ns-watcher`
- `ClusterRoleBinding/fission-router-ns-watcher`
С правами:
- core `namespaces`: `list`, `watch`
После применения подтверждено:
- `kubectl auth can-i list namespaces --as=system:serviceaccount:fission:fission-router` -> `yes`
- `kubectl auth can-i watch namespaces --as=system:serviceaccount:fission:fission-router` -> `yes`
## Финальная проверка
После обоих RBAC fixes повторный запуск `test_layer1.sh` дал:
```text
ИТОГ: PASS=5 FAIL=0
```
На шаге 5 функция успешно ответила:
```text
HTTP 200 - hello from layer1
```
## Что именно оказалось правдой по итогу
Итоговая проблема состояла из двух последовательных RBAC-дырок:
1. executor не мог полностью provision-ить `fission-fetcher` в динамическом namespace
2. router не мог подхватить новый namespace из-за отсутствия namespace watch/list
То есть код hot-registration в целом был правильный, но runtime contract в Kubernetes RBAC был реализован не полностью.
## Итоговые изменения
### Код и манифесты
- `deploy/multitenant/rbac.yaml`
- executor namespace watch
- executor SA provisioning RBAC
- router namespace watch RBAC
### Документация
- `doc/progress.md`
- `doc/thinking/2026-04-26-rbac-fix.md`
- `doc/thinking/2026-04-26-layer1-pass-detailed.md`
### Коммиты по ходу исправления
- `161de70` - `multi-tenant: EnsureNamespaceSA + ns_watcher SA provisioning (v8)`
- `8ccc9fb` - первый RBAC commit
- `f617913` - полный executor RBAC fix для fetcher role provisioning
- `7faaa9d` - router namespace watch RBAC
## Практический вывод
Для hot namespace onboarding в Fission недостаточно просто добавить informer-ы в коде.
Нужно обеспечить весь runtime contract:
- executor видит namespace
- executor может provision-ить service accounts и RBAC в tenant namespace
- executor может делегировать все требуемые permission-ы
- router видит namespace и подписывается на triggers/functions в нём
Если хотя бы одно из этих звеньев отсутствует, поведение выглядит как "код вроде есть, но dynamic namespace не работает".
@@ -0,0 +1,94 @@
# 2026-04-26 — Layer2 chat handoff
## Что уже сделано
Layer1 завершён в ветке rewrite/layer1-namespace-manager-step1 и перенесён в новую рабочую ветку:
`rewrite/layer2-namespace-manager-api-step1`
Layer1 означает, что внутренняя адаптация Fission под multi-tenant namespace onboarding уже готова:
1. Вынесен общий `NamespaceManager`.
2. Buildermgr, router и executor/multitenant переведены на общий watcher/helper layer.
3. Summary/debug contract стабилизирован.
4. Logging path усилен и покрыт тестами.
Последняя точка закрытия layer1:
- commit `63ce6ea``layer1: close namespace manager step1`
## Какие тесты уже были прогнаны
Финальный целевой прогон для layer1:
`go test ./pkg/utils/... ./pkg/buildermgr/... ./pkg/router/... ./pkg/executor/multitenant`
Он прошёл зелёным.
## На какой ветке продолжать
Продолжать работу нужно на ветке:
`rewrite/layer2-namespace-manager-api-step1`
## Что является целью layer2
Layer2 — это уже не перепись watcher-ов, а внешний read-only consumption поверх готового `NamespaceManager` слоя.
Практическая цель:
1. Дать безопасный read-only status/debug/API surface для состояния multi-tenant namespace onboarding.
2. Не менять runtime behavior watcher-ов.
3. Не дублировать логику manager-а в service-level коде.
4. Использовать уже существующий `NamespaceManagerSummary`, а не придумывать вторую модель состояния.
## Что делать в новом чате
Новый чат должен стартовать не с переписывания layer1 заново, а с аккуратного поиска лучшей точки интеграции для layer2.
Предпочтительный порядок:
1. Проверить текущую ветку и чистоту дерева.
2. Найти существующий service-level debug/status/API contour в buildermgr, router или executor.
3. Выбрать один самый безопасный read-only endpoint или status surface.
4. Протащить наружу `NamespaceManagerSummary` без изменения watcher semantics.
5. Добавить unit/integration tests именно на внешний consumer-side path.
6. Документировать каждый шаг в новых файлах в `doc/thinking/`.
## Чего НЕ надо делать
1. Не продолжать внутреннюю консолидацию watcher layer ради самой консолидации.
2. Не ломать существующий runtime flow add/resync/remove.
3. Не вводить второй независимый источник правды о namespace state.
4. Не менять старые doc-файлы — только новые файлы с новыми шагами.
## Важные файлы для продолжения
- `pkg/utils/namespace_manager.go`
- `pkg/utils/namespace_manager_model.go`
- `pkg/utils/namespace_manager_test.go`
- `pkg/buildermgr/ns_watcher.go`
- `pkg/router/ns_watcher.go`
- `pkg/executor/multitenant/ns_watcher.go`
## Как начать с другого компьютера
Если работа продолжается в том же репозитории на той же VM, достаточно открыть репозиторий и проверить ветку:
`cd ~/terra/fission-src && git branch --show-current && git log --oneline -8`
Если ветка не выбрана, переключиться на неё:
`git checkout rewrite/layer2-namespace-manager-api-step1`
Если новый чат работает через VS Code tools над sshfs mount, локальный путь будет соответствовать смонтированной папке, а команды всё равно нужно запускать через SSH на VM.
## Готовый текст для первого сообщения в новом чате
Ниже текст, который можно вставить почти без изменений:
"Продолжаем в repo `fission-src` на ветке `rewrite/layer2-namespace-manager-api-step1`. Layer1 завершён и закрыт commit-ом `63ce6ea`. Внутренний `NamespaceManager` layer готов, buildermgr/router/executor уже сидят на общих watcher helper-ах, summary/debug contract стабилизирован и целевой прогон `go test ./pkg/utils/... ./pkg/buildermgr/... ./pkg/router/... ./pkg/executor/multitenant` уже был зелёным. Теперь нужен layer2: аккуратно найти лучший существующий read-only status/debug/API surface и начать вынос наружу `NamespaceManagerSummary` без изменения runtime semantics watcher-ов. Работай маленькими шагами, с новыми doc-файлами в `doc/thinking/`, без background команд, все команды только через SSH на VM и всегда с timeout."
## Ожидаемый первый технический шаг в новом чате
Не писать код сразу. Сначала найти реальный существующий endpoint или status surface, куда summary можно встроить безопасно и без архитектурного мусора.
@@ -0,0 +1,589 @@
# 2026-04-26 — Layer 1 namespace rewrite: подробная логика правок
## Зачем этот документ
Нужен не просто список коммитов, а объяснение инженерной логики:
- что именно было не так в коде;
- почему исправление выбрано именно таким;
- почему изменения разбиты на маленькие шаги;
- какие инварианты я старался сохранить;
- что уже исправлено, а что еще нет.
Этот документ описывает серию маленьких безопасных шагов в ветке
`rewrite/layer1-namespace-manager-step1`.
Основной принцип серии:
1. Не делать большой взрывной rewrite.
2. Сначала сузить race-surface и разъединить старую статическую модель от новой динамической.
3. Исправлять реальные дефекты отдельно от mechanical refactor.
4. После каждого шага отдельно проверять соответствующий пакет тестами.
---
## Исходная архитектурная проблема
Переделанный Layer 1 жил в гибридном состоянии.
Старая модель Fission:
- список resource namespaces задается один раз на старте;
- компоненты считают этот список immutable;
- informer factories строятся из startup configuration.
Новая multi-tenant модель:
- namespace появляется позже, уже после старта процесса;
- watcher видит label `fission.io/managed=true`;
- компоненты должны подключить новый namespace на лету.
Из-за этого в коде образовался разрыв между двумя мирами:
1. Часть кода уже работает как dynamic system.
2. Часть кода все еще читает глобальную map namespace-ов напрямую, как будто она immutable.
3. В некоторых компонентах startup-path и dynamic-path оказались несимметричными.
4. В некоторых местах общий global dedup конфликтует с локальной логикой конкретного компонента.
Это и есть корневой дефект всей подсистемы: не один конкретный баг, а отсутствие единого namespace lifecycle contract.
---
## Что было решено не делать сразу
Я сознательно не пошел в большой rewrite в один коммит.
Почему:
1. Слишком много точек входа: executor, router, buildermgr, storagesvc, utils.
2. Если переписать все сразу, невозможно будет локализовать регрессию.
3. Уже были реальные functional дефекты в нескольких местах, их удобнее чинить изолированно.
4. Пользователь отдельно попросил идти последовательно и проверять после каждого изменения.
Поэтому выбран bounded rewrite: сначала вычищать старые опасные предположения, затем исправлять функциональные несовпадения, и только потом идти к более крупному NamespaceManager.
---
## Инварианты серии
Во всех шагах я старался держать одинаковые правила.
### 1. Не ломать действующий onboarding contract
Если namespace приходит через label watcher, компоненты должны продолжать подключать его без рестарта. Нельзя было ради рефактора возвращаться к статической модели.
### 2. Не менять лишние контракты одновременно
Если шаг про snapshot API, он не должен заодно переписывать cleanup semantics.
### 3. Сначала механические и безопасные сдвиги, потом functional fixes
Это нужно, чтобы понимать, баг возник из-за новой логики или уже существовал ранее.
### 4. Каждый шаг должен быть проверяем локально
После каждого шага запускались тесты по затронутому пакету, а не абстрактное «кажется, всё нормально».
---
## Step 1 — Snapshot API для namespace resolver
Коммит: `c987fa0`
### Что было не так
`NamespaceResolver` уже имел mutex для записи через `AddNamespace`, но многие потребители читали `FissionResourceNS` напрямую.
Это означало следующее:
1. Запись в map уже динамическая.
2. Чтение в части мест по-прежнему не thread-safe.
3. Код внешне выглядел как безопасный, потому что mutex в структуре есть, но контракт чтения не был централизован.
То есть защита существовала только наполовину.
### Что я сделал
В `pkg/utils/namespace.go` добавлены:
- `Snapshot()`
- `SnapshotWithOptions()`
Их логика:
1. Под read lock взять текущее состояние.
2. Скопировать его в detached slice.
3. Отсортировать, чтобы получить стабильный детерминированный порядок.
Почему именно slice snapshot, а не снова map:
1. Читателям в основном нужен именно проход по namespace-ам.
2. Slice удобнее для безопасной итерации.
3. Сортировка убирает дрожание порядка и делает поведение более предсказуемым в тестах и логике startup factory generation.
### Почему это был правильный первый шаг
Этот шаг почти не меняет бизнес-логику. Он не трогает watchers, RBAC, cleanup, lifecycle events. Он вводит базовый безопасный API, на который потом можно переводить потребителей.
### Что было переведено сразу
Чтобы snapshot API не оставался мертвым кодом, на него были переведены:
- `pkg/utils/informer.go`
- startup factory creation в `pkg/executor/executor.go`
Логика этого выбора:
1. Это общие helper path.
2. Они касаются большого числа компонентов.
3. Но при этом change поверхностный: вместо прямой итерации по map берется snapshot.
### Отдельный мелкий дефект, найденный на шаге 1
Новые тесты создали локальный `NamespaceResolver` без logger. Выяснилось, что часть методов предполагает ненулевой logger. Это нехорошо само по себе: utility object не должен падать только потому, что его используют вне global singleton.
Поэтому были добавлены nil checks вокруг debug/info логов в resolver.
### Проверка шага
Проверялось:
- `go test ./pkg/utils/...`
- `go test ./pkg/executor/...`
Смысл проверки:
1. Убедиться, что snapshot API корректен как utility layer.
2. Убедиться, что startup path executor не поменял поведение.
---
## Step 2 — Исправление namespace routing в serviceaccount checker
Коммит: `9ce9829`
### Что было не так
В `pkg/utils/serviceaccount.go` был более тонкий дефект, чем просто прямое чтение map.
В `runSACheck()` одна и та же переменная `ns` переиспользовалась внутри цикла по permission groups.
Смысл проблемы:
1. Есть исходный base namespace.
2. Для fetcher нужен путь через `GetFunctionNS(baseNS)`.
3. Для builder нужен путь через `GetBuilderNS(baseNS)`.
4. Но код мутировал саму переменную `ns` по мере обхода permission sets.
Это опасно, потому что builder resolution начинает зависеть от предыдущего шага цикла, а не от исходного namespace.
Если `FunctionNamespace` и `BuilderNamespace` различаются, route builder SA может поехать.
### Что я сделал
Изменение было разбито на две части:
1. Итерироваться не по `FissionResourceNS` напрямую, а по `Snapshot()`.
2. Явно вычислять `targetNS` из `baseNS` через отдельный метод `resolveSANamespace(baseNS, saName)`.
Почему выделен отдельный метод:
1. Логика namespace routing становится читаемой как отдельный контракт.
2. Её можно тестировать отдельно.
3. В коде исчезает скрытая мутация переменной цикла.
### Почему я не переписывал весь serviceaccount.go сразу
В файле еще остаются спорные места:
- глобальные `fetcherCheck` / `builderCheck`;
- мутация `permission.exists`;
- runtime provisioning через `LocalSubjectAccessReview`.
Но если решать всё сразу, шаг становится слишком широким. На этом этапе была цель исправить именно namespace routing bug и убрать прямую итерацию по общей map.
### Какой тест был добавлен
Добавлен unit test на `resolveSANamespace()`:
- fetcher на default namespace должен идти в function namespace;
- builder на default namespace должен идти в builder namespace;
- tenant namespace должен сохраняться как tenant namespace.
Тест важен не из-за синтаксиса, а потому что он фиксирует смысловую развязку между двумя namespace path.
### Проверка шага
Проверялось:
- `go test ./pkg/utils/...`
- `go test ./pkg/executor/...`
---
## Step 3 — Перевод runtime loops на snapshot API
Коммит: `6102b27`
### Что было не так
Даже после появления snapshot API ещё оставались runtime loops, которые напрямую читали общую map namespace-ов в горячих путях:
- adopt existing resources;
- idle object reaper;
- orphan archive pruning.
Это плохо не только из-за race. Это также концептуально закрепляет старую модель «список namespace-ов — это просто глобальная map, в которую можно смотреть отовсюду».
### Что я сделал
Перевёл на `Snapshot()` следующие места:
- `pkg/executor/executortype/container/containermgr.go`
- `pkg/executor/executortype/newdeploy/newdeploymgr.go`
- `pkg/executor/executortype/poolmgr/gpm.go`
- `pkg/storagesvc/archivePruner.go`
### Почему именно эти места были хорошим кандидатом
Потому что это mechanical refactor:
1. Логика списков не меняется.
2. Namespace source меняется с raw map на stable snapshot.
3. Поведение должно оставаться тем же, кроме устранения unsafe read.
### Что это дало
1. Уменьшило площадь прямого доступа к глобальному mutable состоянию.
2. Подготовило код к следующему этапу, когда namespace registry станет ещё более централизованным.
3. Сделало background loops более предсказуемыми при одновременном dynamic onboarding.
### Проверка шага
Проверялось:
- `go test ./pkg/executor/... ./pkg/storagesvc/...`
---
## Step 4 — Исправление buildermgr dedup bug
Коммит: `56a499a`
### Это уже не mechanical refactor, а реальный functional fix
### Что было не так
`buildermgr.StartNSWatcher()` при появлении нового namespace делал:
1. `envw.AddNamespace()`
2. `pkgw.AddNamespace()`
Но оба watcher-а использовали один и тот же глобальный dedup через `nsResolver.AddNamespace()`.
Фактический эффект:
1. Первый вызов успешно добавляет namespace в global resolver.
2. Второй вызов видит, что namespace уже «есть».
3. И просто выходит.
То есть в buildermgr динамический namespace мог получить только часть подписок.
Это уже не theoretical risk, а реальный дефект логики.
### Почему проблема архитектурная
Здесь смешались два уровня ответственности:
1. Global registry должен знать, что namespace существует.
2. Конкретный компонент должен знать, подписался ли он уже на этот namespace.
Это разные виды dedup.
Один глобальный dedup не может корректно заменить локальный dedup для двух разных subcomponents.
### Что я сделал
Логику развёл по уровням:
1. В `pkg/buildermgr/ns_watcher.go` global resolver обновляется один раз.
2. `environmentWatcher` dedup делает по своей map `envWatchInformer`.
3. `packageWatcher` dedup делает по своей map `pkgInformer`.
### Почему это правильнее
Теперь структура похожа на executor path:
1. Глобальный реестр говорит: namespace известен системе.
2. Каждый компонент сам решает: свои informers он уже поднял или нет.
Именно так должен выглядеть multi-component dynamic onboarding.
### Что я сознательно не делал
Не добавлял remove/cleanup и не переделывал buildermgr lifecycle целиком. На шаге требовалось только убрать ошибку дедупликации.
### Проверка шага
Проверялось:
- `go test ./pkg/buildermgr/...`
Тестов в пакете немного, но для этого шага важно было хотя бы подтвердить, что wiring собирается и не поломан compile-time.
---
## Step 5 — Исправление parity gap в newdeploy
Коммит: `94f26b6`
### Что было не так
`MakeNewDeploy()` на старте процесса регистрировал оба типа handler-ов:
- `FunctionEventHandlers()`
- `EnvEventHandlers()`
Но `AddNamespace()` для динамически появившегося namespace регистрировал только `FunctionEventHandlers()`.
Это значит, что два namespace-а с одинаковым содержимым вели себя по-разному только из-за времени появления:
1. startup namespace обслуживается полным code path;
2. dynamic namespace обслуживается урезанным code path.
Это очень плохое свойство для Layer 1, потому что поведение перестаёт зависеть только от данных и начинает зависеть от истории запуска процесса.
### Что я сделал
В `newdeploy.AddNamespace()` добавил регистрацию `EnvEventHandlers()` рядом с `FunctionEventHandlers()`.
### Почему fix именно такой
Потому что это минимальное исправление семантической несимметрии.
Я не придумывал новую абстракцию, а привёл dynamic path к уже существующему startup contract.
### Инженерный смысл шага
Это важный принцип всей серии: если startup-path и late onboarding-path делают похожую работу, они должны проходить через один и тот же контракт, а не через два слегка разных набора side effects.
### Проверка шага
Проверялось:
- `go test ./pkg/executor/executortype/newdeploy`
---
## Step 6 — Защита router informer maps от гонок
Коммит: `87477d4`
### Что было не так
В router динамический namespace добавляет новые informer-ы в две map:
- `triggerInformer`
- `funcInformer`
Параллельно `updateRouter()` итерируется по тем же map, собирая триггеры и функции для rebuild router-а.
Плюс `functionReferenceResolver` получает `funcInformer` и тоже читает его напрямую.
Это создаёт классическую проблему:
1. одна goroutine пишет в map;
2. другая одновременно по ней итерируется;
3. третья читает её через resolver.
Результат может быть от паники `concurrent map iteration and map write` до тихого чтения неполного состояния.
### Почему шаг стал чуть шире
Простой mutex только вокруг `HTTPTriggerSet.AddNamespace()` не решал бы проблему полностью, потому что `functionReferenceResolver` держал свою ссылку на ту же mutable структуру.
Поэтому понадобилось сделать две вещи одновременно:
1. Защитить maps в `HTTPTriggerSet` через `RWMutex` и snapshot helpers.
2. Дать `functionReferenceResolver` собственный thread-safe путь доступа к informer registry.
### Что я сделал
В `HTTPTriggerSet`:
- добавлен `RWMutex`;
- добавлены `snapshotTriggerInformers()`;
- добавлены `snapshotFuncInformers()`;
- `updateRouter()` и setup handlers теперь работают по snapshot-спискам.
В `functionReferenceResolver`:
- добавлен `RWMutex`;
- чтение informer-а по namespace теперь под read lock;
- добавлен `addInformer()` для безопасного добавления нового namespace.
В `router.AddNamespace()`:
- запись в `triggerInformer` и `funcInformer` идёт под lock;
- resolver получает новый informer через собственный безопасный метод.
### Почему именно snapshot-helpers, а не держать lock во время всей итерации
Потому что rebuild router-а и чтение store-ов могут быть относительно дорогими. Держать глобальный lock на всё это время было бы лишним. Нам нужен был не coarse lock на длинный процесс, а короткий lock на получение стабильного снимка ссылок на informer-ы.
То есть стратегия такая:
1. Быстро снять snapshot ссылок.
2. Отпустить lock.
3. Работать со snapshot уже без блокировки записи.
Это лучше и по безопасности, и по latency.
### Проверка шага
Проверялось:
- `go test ./pkg/router/...`
---
## Почему шаги документировались отдельно
Я сохранял отдельный thinking-файл на каждый шаг не ради бюрократии, а ради трассируемости.
Когда изменения маленькие, отдельные документы позволяют понять:
1. какой дефект исправлял именно этот коммит;
2. что было осознанно оставлено за рамками;
3. какой тест подтверждал именно этот шаг;
4. где functional fix, а где только mechanical safety refactor.
Именно это позволяет потом анализировать regressions не по памяти, а по истории.
---
## Что осталось нерешённым после step 6
Несмотря на шесть шагов, это ещё не финальный NamespaceManager rewrite.
Остаются важные вопросы.
### 1. Нет remove/cleanup semantics
Система умеет add, но почти не умеет delete/relabel cleanup.
Что это значит practically:
- informer-ы и локальные registry entries живут вечно;
- once onboarded, always onboarded;
- короткоживущие tenant namespace-ы будут оставлять мусор.
### 2. `serviceaccount.go` всё ещё не идеален
Текущий `serviceaccount.go` уже лучше, чем до step 2, но файл всё ещё сложный:
- глобальные `fetcherCheck` / `builderCheck` живут как process-wide mutable objects;
- `permission.exists` мутируется в runtime;
- provisioning и permission-check тесно сцеплены.
Это отдельный кандидат на следующий bounded refactor, но уже не маленький mechanical шаг.
### 3. Глобальный resolver всё ещё остаётся transitional abstraction
`NamespaceResolver` теперь безопаснее для чтения, но это пока ещё не полноценный NamespaceManager с событиями, remove lifecycle и подписками.
Он всё ещё ближе к thread-safe registry, чем к полной orchestration layer.
### 4. Cleanup/restart/backfill lifecycle ещё не централизован
Часть компонентов уже ближе к единообразию, но по-прежнему нет одного центрального orchestration contract вида:
- add existing namespaces on startup;
- reconcile on relabel;
- remove on delete;
- rebuild after restart;
- re-register late component safely.
---
## Почему я не стал сразу делать remove/cleanup
Потому что это уже следующая категория сложности.
До step 6 изменения укладывались в схему:
- локальный и понятный дефект;
- ограниченный blast radius;
- тестируемый пакет;
- отдельный маленький commit.
Remove/cleanup меняет уже жизненный цикл системы и затрагивает много мест одновременно:
- watcher behavior;
- manager lifecycle;
- informer shutdown semantics;
- cache invalidation;
- resolver state.
Это не тот шаг, который разумно смешивать с небольшими safety fixes.
---
## Почему такая стратегия лучше, чем «переписать всё сразу»
Потому что сейчас уже есть видимый результат с низким риском:
1. Уменьшено число прямых доступов к общей mutable map.
2. Исправлен реальный functional bug в buildermgr.
3. Исправлена реальная логическая ошибка в serviceaccount namespace routing.
4. Исправлена несимметрия в newdeploy dynamic path.
5. Закрыта явная router race-surface.
И всё это не одним большим коммитом, а серией шагов с локальной верификацией.
Для инфраструктурного кода это важнее, чем «красивый большой rewrite», который сложно раскладывать при регрессиях.
---
## Какие проверки были прогнаны по ходу серии
После шагов запускались:
- `go test ./pkg/utils/...`
- `go test ./pkg/executor/...`
- `go test ./pkg/storagesvc/...`
- `go test ./pkg/buildermgr/...`
- `go test ./pkg/router/...`
Логика была такая:
1. Не гонять каждый раз всю репу, если шаг локальный.
2. Но обязательно проверять затронутый пакет и соседний пакет, если change касается shared utility layer.
---
## Текущее состояние после серии
Серия шагов 1-6 не завершает rewrite, но заметно улучшает базу для следующего этапа.
Что теперь стало лучше:
1. Namespace reads стали заметно более дисциплинированными.
2. Dynamic namespace onboarding стал логически ровнее между компонентами.
3. В router исчезла наиболее явная race-surface на informer maps.
4. Buildermgr больше не теряет часть подписок на новый namespace из-за неправильного dedup.
Что остаётся следующим осмысленным этапом:
1. Вынесение уже полноценного NamespaceManager как orchestration layer.
2. Remove/cleanup lifecycle.
3. Разделение discovery, registry и provisioning.
4. Дополнительные тесты на restart/relabel/delete/burst onboarding.
---
## Отдельная заметка про `serviceaccount.go`
На момент написания этого документа файл `pkg/utils/serviceaccount.go` был заново перечитан по текущему содержимому. Документ описывает актуальную логику файла в его текущем состоянии, а не только то состояние, которое было в момент коммита step 2.
Это важно, потому что именно в этом файле пользовательский контекст отдельно предупредил о возможных дополнительных изменениях между сообщениями.
@@ -0,0 +1,44 @@
# 2026-04-26 — NamespaceManager rewrite, step 1
## Цель шага
Начать bounded rewrite Layer 1 без большого взрыва по коду.
Первый шаг deliberately узкий:
- не менять lifecycle namespace onboarding;
- не трогать watcher-ы executor/router/buildermgr;
- не менять контракты `AddNamespace`;
- убрать первые прямые проходы по общей mutable map `FissionResourceNS`.
## Почему именно так
Сейчас multi-tenant логика уже динамическая, но многие старые code path все еще читают
`DefaultNSResolver().FissionResourceNS` напрямую. Это опасно по двум причинам:
1. map общая и mutable, а dynamic onboarding меняет ее во время работы процесса;
2. часть helper-ов и startup path продолжают жить как будто список namespace-ов immutable.
Полный rewrite в один шаг дал бы слишком большой blast radius. Поэтому сначала вводится
thread-safe snapshot API в namespace layer, а затем существующие потребители переводятся
на него по одному.
## План шага 1
1. Добавить в `pkg/utils/namespace.go` методы snapshot для plain namespaces и namespaces with options.
2. Перевести `pkg/utils/informer.go` на snapshot API.
3. Перевести startup factory path в `pkg/executor/executor.go` на snapshot API.
4. Добавить unit tests для snapshot behavior.
5. Прогнать `go test ./pkg/utils/... ./pkg/executor/...`.
## Ожидаемый эффект
- меньше прямых чтений общей map;
- появление базового API, через который дальше можно выносить единый NamespaceManager;
- нулевое изменение внешнего поведения на этом шаге.
## Что НЕ делаем на этом шаге
- не исправляем watcher lifecycle;
- не добавляем remove/delete semantics;
- не трогаем router race и buildermgr dedup bug;
- не меняем RBAC.
@@ -0,0 +1,22 @@
# 2026-04-26 — NamespaceManager rewrite, step 10
## Цель шага
Научить skeleton manager выводить общую phase namespace-а из part states.
## Что меняем
1. Добавляем константы состояний частей:
- `registering`
- `active`
- `failed`
2. После `MarkPartState()` manager пересчитывает общую phase namespace-а.
3. Добавляем unit tests на переходы:
- registering -> active
- failed -> NamespacePhaseFailed
## Что НЕ меняем
- не запускаем реальный reconcile loop;
- не вызываем subscriber-ов автоматически;
- не подключаем manager к runtime.
@@ -0,0 +1,18 @@
# 2026-04-26 — NamespaceManager rewrite, step 11
## Цель шага
Добавить bootstrap helper для массовой загрузки initial namespace set в manager.
## Что меняем
1. Добавляем `Bootstrap()` в manager interface и реализацию.
2. Метод принимает список namespace-ов и `NamespaceSource`.
3. Метод прогоняет namespaces через `Upsert()` как initial discovered set.
4. Добавляем unit tests на bootstrap.
## Что НЕ меняем
- не подключаем bootstrap к runtime startup path;
- не меняем watcher-ы;
- не трогаем resolver/SA/runtime.
@@ -0,0 +1,17 @@
# 2026-04-26 — NamespaceManager rewrite, step 12
## Цель шага
Добавить bridge helper между legacy `NamespaceResolver` и новым `NamespaceManager`.
## Что меняем
1. Добавляем helper `NewBootstrappedNamespaceManager()`.
2. Helper берёт snapshot из resolver и bootstraps manager.
3. Добавляем unit test на bootstrap from resolver.
## Что НЕ меняем
- не подключаем helper к production startup path;
- не меняем watcher-ы;
- не меняем runtime components.
@@ -0,0 +1,20 @@
# 2026-04-26 — NamespaceManager rewrite, step 13
## Цель шага
Централизовать managed namespace label contract в `utils`.
## Что меняем
1. Добавляем в `utils`:
- `ManagedNamespaceLabelKey`
- `ManagedNamespaceLabelValue`
- `ManagedNamespaceLabelSelector()`
- `IsManagedNamespace()`
2. Переводим watcher-ы executor/router/buildermgr на единый helper.
## Что НЕ меняем
- не подключаем новый manager к watcher-ам;
- не меняем поведение onboarding;
- не трогаем runtime reconcile.
@@ -0,0 +1,19 @@
# 2026-04-26 — NamespaceManager rewrite, step 14
## Цель шага
Добавить удобные helper-методы для part-state transitions.
## Что меняем
1. В manager interface добавляем:
- `MarkPartRegistering()`
- `MarkPartActive()`
- `MarkPartFailed()`
2. Реализуем их поверх `MarkPartState()`.
3. Добавляем unit tests.
## Что НЕ меняем
- не подключаем helpers к runtime reconcile;
- не трогаем watcher-ы и runtime components.
@@ -0,0 +1,16 @@
# 2026-04-26 — NamespaceManager rewrite, step 15
## Цель шага
Добавить utility helper-методы для построения `NamespaceEvent`.
## Что меняем
1. Добавляем `NewNamespaceEvent()`.
2. Добавляем `ManagedNamespaceEvent()`.
3. Добавляем unit tests.
## Что НЕ меняем
- не подключаем event helpers к watcher-ам;
- не меняем runtime behavior.
@@ -0,0 +1,18 @@
# 2026-04-26 — NamespaceManager rewrite, step 16
## Цель шага
Подготовить lifecycle subscriber contract для будущего reconcile path.
## Что меняем
1. Расширяем `NamespaceSubscriber` методами:
- `OnNamespaceAdd()`
- `OnNamespaceRemove()`
- `OnNamespaceResync()`
2. Обновляем тестовую заглушку subscriber-а.
## Что НЕ меняем
- не вызываем subscriber-ов из manager;
- не подключаем contract к runtime components.
@@ -0,0 +1,22 @@
# 2026-04-26 — NamespaceManager rewrite, step 17
## Цель шага
Добавить dispatch helper для прогона namespace через subscriber-ов в add/resync path.
## Что меняем
1. В manager interface добавляем:
- `DispatchAdd()`
- `DispatchResync()`
2. Manager вызывает subscriber-ов последовательно.
3. Для каждого subscriber-а manager проставляет part state:
- `registering`
- `active` или `failed`
4. Добавляем unit tests на success и failure path.
## Что НЕ меняем
- не подключаем dispatch к production watcher-ам;
- не добавляем remove dispatch;
- не меняем runtime components.
@@ -0,0 +1,15 @@
# 2026-04-26 — NamespaceManager rewrite, step 18
## Цель шага
Подготовить watcher-friendly helper для преобразования Kubernetes Namespace в `NamespaceEvent`.
## Что меняем
1. Добавляем `NamespaceEventFromNamespace()`.
2. Добавляем unit tests на перенос имени и labels.
## Что НЕ меняем
- не подключаем helper к watcher-ам;
- не меняем runtime behavior.
@@ -0,0 +1,16 @@
# 2026-04-26 — NamespaceManager rewrite, step 19
## Цель шага
Добавить functional adapter для `NamespaceSubscriber`.
## Что меняем
1. Добавляем `NamespaceSubscriberFuncs`.
2. Добавляем `Name()/OnNamespaceAdd()/OnNamespaceRemove()/OnNamespaceResync()`.
3. Добавляем unit tests.
## Что НЕ меняем
- не подключаем adapter к runtime;
- не меняем production watcher-ы.
@@ -0,0 +1,33 @@
# 2026-04-26 — NamespaceManager rewrite, step 2
## Цель шага
Убрать еще один прямой проход по `FissionResourceNS` и закрыть конкретный баг в
`pkg/utils/serviceaccount.go`.
## Проблема
`runSACheck()` сейчас:
1. итерируется по `sa.nsResolver.FissionResourceNS` напрямую;
2. переиспользует переменную `ns` внутри внутреннего цикла по permissions.
Из-за этого код выглядит безобидно, но фактически смешивает два разных namespace path:
- fetcher path через `GetFunctionNS()`;
- builder path через `GetBuilderNS()`.
Если `FunctionNamespace` и `BuilderNamespace` различаются, builder SA может начать
резолвиться уже не от исходного namespace, а от результата предыдущего шага цикла.
## Что меняем
1. Берем base namespaces через thread-safe `Snapshot()`.
2. Для каждого permission вычисляем `targetNS` из исходного `baseNS`, а не из мутированной переменной.
3. Добавляем unit test на routing function/builder namespace.
## Что НЕ меняем на этом шаге
- не трогаем глобальные `fetcherCheck` / `builderCheck` структуры;
- не меняем `LocalSubjectAccessReview` path;
- не делаем большой refactor всего SA provisioning.
@@ -0,0 +1,21 @@
# 2026-04-26 — NamespaceManager rewrite, step 20
## Цель шага
Сделать первый реальный runtime adapter для `NamespaceManager` в `buildermgr`.
## Что меняем
1. Добавляем buildermgr namespace subscriber.
2. Adapter переиспользует существующие `envWatcher.AddNamespace()` и `packageWatcher.AddNamespace()`.
3. `add/resync` path повторяет текущую логику watcher-а:
- добавить namespace в resolver;
- вызвать env watcher;
- вызвать package watcher.
4. Добавляем unit test на вызов обоих watcher-ов.
## Что НЕ меняем
- не подключаем subscriber к `StartNSWatcher()`;
- не меняем remove behavior;
- не ломаем текущий production flow.
@@ -0,0 +1,15 @@
# 2026-04-26 — NamespaceManager rewrite, step 21
## Цель шага
Свести текущий watcher flow и новый subscriber flow `buildermgr` к одному helper.
## Что меняем
1. `buildermgr/ns_watcher.go` больше не дублирует логику add/resync.
2. Watcher вызывает `registerBuilderNamespace()`.
## Что НЕ меняем
- не меняем внешний API watcher-а;
- не переключаем `StartNSWatcher()` на `NamespaceManager`.
@@ -0,0 +1,17 @@
# 2026-04-26 — NamespaceManager rewrite, step 22
## Цель шага
Добавить первый runtime adapter для `router` по тому же шаблону, что и для `buildermgr`.
## Что меняем
1. Добавляем router namespace subscriber.
2. Adapter переиспользует существующий `HTTPTriggerSet.AddNamespace()`.
3. `add/resync` path прогоняется через общий helper.
## Что НЕ меняем
- не подключаем subscriber к `StartNSWatcher()`;
- не меняем remove path;
- не меняем текущий production flow.
@@ -0,0 +1,15 @@
# 2026-04-26 — NamespaceManager rewrite, step 23
## Цель шага
Свести текущий watcher flow и новый subscriber flow `router` к одному helper.
## Что меняем
1. `router/ns_watcher.go` больше не дублирует add/resync логику.
2. Watcher вызывает `registerRouterNamespace()`.
## Что НЕ меняем
- не переключаем `StartNSWatcher()` на `NamespaceManager`;
- не меняем внешний API watcher-а.
@@ -0,0 +1,16 @@
# 2026-04-26 — NamespaceManager rewrite, step 24
## Цель шага
Подготовить `executor/multitenant` к subscriber adapter без смены текущего watcher behavior.
## Что меняем
1. Выделяем отдельный helper для прогона `AddNamespace()` по executor type-ам.
2. Оставляем `EnsureNamespaceSA()` в текущем `registerNamespace()`.
3. Добавляем unit test на успешный прогон и propagation ошибок.
## Что НЕ меняем
- не подключаем `NamespaceManager`;
- не меняем внешний API watcher-а.
@@ -0,0 +1,17 @@
# 2026-04-26 — NamespaceManager rewrite, step 25
## Цель шага
Добавить runtime adapter для `executor/multitenant` поверх уже выделенного helper-а.
## Что меняем
1. Добавляем executor namespace subscriber.
2. `add/resync` path переиспользует `registerNamespace()`.
3. Добавляем unit test на вызов executor type-ов.
## Что НЕ меняем
- не подключаем subscriber к watcher-у;
- не меняем remove path;
- не меняем внешний API watcher-а.
@@ -0,0 +1,17 @@
# 2026-04-26 — NamespaceManager rewrite, step 26
## Цель шага
Добавить единый startup bridge для manager: bootstrap model + dispatch в subscriber-ы.
## Что меняем
1. В `NamespaceManager` добавляем `BootstrapAndDispatch()`.
2. Helper сначала делает `Bootstrap()`, потом вызывает `DispatchAdd()` по каждому namespace.
3. Ошибки агрегируются и не останавливают остальные namespace.
4. Добавляем unit tests на success и partial-failure.
## Что НЕ меняем
- не подключаем helper к production startup path;
- не меняем watcher behavior.
@@ -0,0 +1,20 @@
# 2026-04-26 — NamespaceManager rewrite, step 27
## Цель шага
Сделать первый реальный runtime hook на `NamespaceManager` в `buildermgr` watcher.
## Что меняем
1. `buildermgr.StartNSWatcher()` поднимает локальный `NamespaceManager`.
2. В manager заранее bootstrapped текущий snapshot resolver-а.
3. Watcher `Add/Update` события прогоняет через:
- `Upsert()`
- `DispatchAdd()` или `DispatchResync()`
4. Подписчиком manager-а становится уже существующий `buildermgr` subscriber adapter.
## Что НЕ меняем
- не меняем `registerBuilderNamespace()`;
- не добавляем remove path;
- не меняем остальные компоненты.
@@ -0,0 +1,19 @@
# 2026-04-26 — NamespaceManager rewrite, step 28
## Цель шага
Сделать такой же runtime hook на `NamespaceManager` в `router` watcher.
## Что меняем
1. `router.StartNSWatcher()` поднимает локальный `NamespaceManager`.
2. Manager bootstrapped из текущего resolver snapshot.
3. Watcher `Add/Update` события прогоняет через:
- `Upsert()`
- `DispatchAdd()` или `DispatchResync()`
4. Подписчиком manager-а становится router subscriber adapter.
## Что НЕ меняем
- не добавляем remove path;
- не меняем `HTTPTriggerSet.AddNamespace()`.
@@ -0,0 +1,19 @@
# 2026-04-26 — NamespaceManager rewrite, step 29
## Цель шага
Перевести `executor/multitenant` watcher на тот же manager flow, что уже используется в `buildermgr` и `router`.
## Что меняем
1. `StartNSWatcher()` поднимает локальный `NamespaceManager`.
2. Manager bootstrapped из resolver snapshot.
3. Watcher `Add/Update` события прогоняет через:
- `Upsert()`
- `DispatchAdd()` или `DispatchResync()`
4. Подписчиком manager-а становится executor subscriber adapter.
## Что НЕ меняем
- не добавляем remove path;
- не меняем `registerNamespace()` и низкоуровневый executor registration helper.
@@ -0,0 +1,28 @@
# 2026-04-26 — NamespaceManager rewrite, step 3
## Цель шага
Срезать еще один слой прямых чтений `DefaultNSResolver().FissionResourceNS` в runtime code path.
## Почему это отдельный шаг
После step 1 snapshot API уже существует, но runtime loops в executor и storagesvc все еще
читают общую mutable map напрямую. Это не архитектурный rewrite, а чистый safety refactor:
- `container.AdoptExistingResources()`
- `newdeploy.AdoptExistingResources()`
- `newdeploy.doIdleObjectReaper()`
- `poolmgr.AdoptExistingResources()`
- `poolmgr.doIdleObjectReaper()`
- `storagesvc.ArchivePruner.getOrphanArchives()`
## Что меняем
В этих местах цикл переводится на `DefaultNSResolver().Snapshot()`.
## Что НЕ меняем
- не меняем семантику cleanup;
- не меняем behavior watcher-ов;
- не добавляем remove semantics;
- не исправляем router race и buildermgr dedup на этом шаге.
@@ -0,0 +1,15 @@
# 2026-04-26 — NamespaceManager rewrite, step 30
## Цель шага
Закрыть startup gap в `buildermgr`: manager должен отражать и существующие namespace-ы, а не только новые события watcher-а.
## Что меняем
1. `buildermgr.StartNSWatcher()` создаёт пустой `NamespaceManager`.
2. После `Subscribe()` выполняется `BootstrapAndDispatch()` по текущему snapshot resolver-а.
## Что НЕ меняем
- не меняем low-level registration helper;
- не меняем remove path.
@@ -0,0 +1,15 @@
# 2026-04-26 — NamespaceManager rewrite, step 31
## Цель шага
Закрыть startup gap в `router`: локальный manager должен отражать существующие namespace-ы уже на старте.
## Что меняем
1. `router.StartNSWatcher()` создаёт пустой `NamespaceManager`.
2. После `Subscribe()` выполняется `BootstrapAndDispatch()` по snapshot resolver-а.
## Что НЕ меняем
- не меняем `HTTPTriggerSet.AddNamespace()`;
- не добавляем remove path.
@@ -0,0 +1,15 @@
# 2026-04-26 — NamespaceManager rewrite, step 32
## Цель шага
Закрыть startup gap в `executor/multitenant`: manager должен отражать стартовые namespace-ы и прогонять их через тот же subscriber path.
## Что меняем
1. `StartNSWatcher()` создаёт пустой `NamespaceManager`.
2. После `Subscribe()` выполняется `BootstrapAndDispatch()` по snapshot resolver-а.
## Что НЕ меняем
- не меняем `registerNamespace()`;
- не добавляем remove path.
@@ -0,0 +1,17 @@
# 2026-04-26 — NamespaceManager rewrite, step 33
## Цель шага
Убрать несоответствие между contract и manager implementation: `OnNamespaceRemove()` уже есть, а `DispatchRemove()` ещё нет.
## Что меняем
1. В `NamespaceManager` добавляем `DispatchRemove()`.
2. Manager вызывает `OnNamespaceRemove()` у всех subscriber-ов.
3. После dispatch namespace переводится в `removed` через `NamespaceEventRemove`.
4. Добавляем unit tests на success и failure path.
## Что НЕ меняем
- не подключаем remove events в watcher-ы;
- не реализуем physical cleanup в runtime components.
@@ -0,0 +1,19 @@
# 2026-04-26 — NamespaceManager rewrite, step 34
## Цель шага
Подготовить безопасный helper для delete/tombstone событий Namespace informer-а.
## Что меняем
1. Добавляем `NamespaceFromObject()`.
2. Helper поддерживает:
- `*corev1.Namespace`
- `cache.DeletedFinalStateUnknown`
3. Добавляем `NamespaceEventFromObject()`.
4. Добавляем unit tests.
## Что НЕ меняем
- не подключаем delete handling в watcher-ы на этом шаге;
- не меняем runtime behavior.
@@ -0,0 +1,20 @@
# 2026-04-26 — NamespaceManager rewrite, step 35
## Цель шага
Научить watcher-ы фиксировать label-drop/delete в локальном `NamespaceManager`, не трогая реальные runtime регистрации.
## Что меняем
1. Во все три namespace watcher-а добавляем:
- `DeleteFunc`
- обработку `managed -> unmanaged` в `UpdateFunc`
2. При таком событии watcher:
- создаёт `NamespaceEventRemove`
- записывает его в manager через `Upsert()`
- пишет явный log, что runtime cleanup НЕ выполняется
## Что НЕ меняем
- не вызываем `DispatchRemove()` из watcher-ов;
- не удаляем informer-ы, resolver state или runtime registrations.
@@ -0,0 +1,18 @@
# 2026-04-26 — NamespaceManager rewrite, step 36
## Цель шага
Убрать мёртвый код после перевода watcher-ов на `NamespaceManager` flow.
## Что меняем
1. Удаляем неиспользуемые helper-ы:
- `builderNSName()`
- `routerNSName()`
- `namespaceName()`
2. Убираем ставшие неиспользуемыми imports.
## Что НЕ меняем
- не меняем runtime behavior;
- не меняем watcher logic.
@@ -0,0 +1,19 @@
# 2026-04-26 — NamespaceManager rewrite, step 37
## Цель шага
Убрать дублирование startup manager flow в трёх namespace watcher-ах.
## Что меняем
1. В `utils` добавляем helper `NewWatcherNamespaceManager()`.
2. Helper:
- создаёт `NamespaceManager`
- подписывает subscriber-ов
- выполняет `BootstrapAndDispatch()`
3. `buildermgr`, `router`, `executor/multitenant` используют новый helper.
## Что НЕ меняем
- не меняем semantics dispatch;
- не меняем runtime cleanup policy.
@@ -0,0 +1,19 @@
# 2026-04-26 — NamespaceManager rewrite, step 38
## Цель шага
Убрать повторяющуюся lifecycle логiku namespace watcher-ов.
## Что меняем
1. В `utils` добавляем helpers:
- `NamespaceBecameUnmanaged()`
- `DispatchNamespaceAdd()`
- `DispatchNamespaceResync()`
- `RecordNamespaceRemoval()`
2. `buildermgr`, `router`, `executor/multitenant` используют эти helpers.
## Что НЕ меняем
- не меняем runtime semantics;
- remove по-прежнему только bookkeeping, без cleanup.
@@ -0,0 +1,43 @@
# 2026-04-26 — NamespaceManager rewrite, step 39
## Цель шага
Свести три namespace watcher-а к одинаковому lifecycle поведению через общие handlers в `utils`.
## Что меняем
1. Добавляем helpers:
- `HandleWatcherNamespaceAdd()`
- `HandleWatcherNamespaceUpdate()`
- `HandleWatcherNamespaceDelete()`
2. Helpers централизуют:
- dispatch add/resync;
- remove bookkeeping;
- стандартное logging-сообщение.
3. `buildermgr`, `router`, `executor/multitenant` переходят на эти helpers.
## Что НЕ меняем
- не меняем runtime cleanup policy;
- не меняем manager state model.# 2026-04-26 — NamespaceManager rewrite, step 39
## Цель шага
Свести три namespace watcher-а к одинаковому lifecycle поведению через общие handlers в `utils`.
## Что меняем
1. Добавляем helpers:
- `HandleWatcherNamespaceAdd()`
- `HandleWatcherNamespaceUpdate()`
- `HandleWatcherNamespaceDelete()`
2. Helpers централизуют:
- dispatch add/resync;
- remove bookkeeping;
- стандартное logging-сообщение.
3. `buildermgr`, `router`, `executor/multitenant` переходят на эти helpers.
## Что НЕ меняем
- не меняем runtime cleanup policy;
- не меняем manager state model.
@@ -0,0 +1,32 @@
# 2026-04-26 — NamespaceManager rewrite, step 4
## Цель шага
Исправить реальный functional bug в dynamic onboarding buildermgr.
## Дефект
`buildermgr.StartNSWatcher()` вызывает:
1. `envw.AddNamespace()`
2. `pkgw.AddNamespace()`
Но оба watcher-а используют один и тот же глобальный `nsResolver.AddNamespace()` для dedup.
Из-за этого первый вызов добавляет namespace, а второй считает его уже обработанным и
выходит раньше времени. В результате у динамического tenant namespace может подняться только
Environment informer без Package informer.
## Исправление
1. Глобальный resolver обновляется один раз в `buildermgr/ns_watcher.go`.
2. `environmentWatcher` dedup делает только по своей map `envWatchInformer`.
3. `packageWatcher` dedup делает только по своим map `pkgInformer` / `podInformer`.
Так buildermgr становится симметричнее executor path: общий registry обновляется один раз,
а конкретные компоненты сами решают, подписаны ли они уже на namespace.
## Что НЕ меняем
- не добавляем cleanup/remove semantics;
- не меняем router;
- не трогаем newdeploy parity gap на этом шаге.
@@ -0,0 +1,20 @@
# 2026-04-26 — NamespaceManager rewrite, step 40
## Цель шага
Зафиксировать lifecycle policy для namespace removal в коде явно, а не только комментариями и log-сообщениями.
## Что меняем
1. Добавляем `NamespaceRemovalStrategy`.
2. Поддерживаем два режима:
- `track-only`
- `dispatch-remove`
3. Общие watcher handlers принимают strategy.
4. Текущий production flow использует `track-only`.
5. Добавляем unit tests на оба режима.
## Что НЕ меняем
- не включаем реальный remove dispatch в watcher-ах;
- не меняем runtime cleanup policy по умолчанию.
@@ -0,0 +1,16 @@
# 2026-04-26 — NamespaceManager rewrite, step 41
## Цель шага
Довести explicit removal strategy до полного покрытия watcher lifecycle paths.
## Что меняем
1. `HandleWatcherNamespaceUpdate()` теперь тоже принимает `NamespaceRemovalStrategy`.
2. `managed -> unmanaged` path использует ту же policy, что и `DeleteFunc`.
3. Добавляем unit test на update-path с `dispatch-remove`.
## Что НЕ меняем
- текущие watcher-ы остаются на `track-only`;
- runtime cleanup policy по умолчанию не меняется.
@@ -0,0 +1,17 @@
# 2026-04-26 — NamespaceManager rewrite, step 42
## Цель шага
Убрать последний крупный слой дублирования в namespace watcher-ах: сами `ResourceEventHandlerFuncs`.
## Что меняем
1. В `utils` добавляем `NewNamespaceWatcherEventHandlers()`.
2. Конструктор собирает общий `Add/Update/Delete` flow на базе уже существующих handler helper-ов.
3. `buildermgr`, `router`, `executor/multitenant` используют общий конструктор.
## Что НЕ меняем
- не меняем label selector;
- не меняем manager semantics;
- не меняем removal policy по умолчанию.
@@ -0,0 +1,19 @@
# 2026-04-26 — NamespaceManager rewrite, step 43
## Цель шага
Убрать оставшуюся копипасту старта namespace informer-а из `buildermgr`, `router`, `executor/multitenant`.
## Что меняем
1. В `utils` добавляем `StartManagedNamespaceWatcher()`.
2. Helper централизует:
- informer factory с label selector;
- регистрацию event handlers;
- start/cache sync/stop logging через `mgr`.
3. Три watcher-а переходят на общий helper.
## Что НЕ меняем
- не меняем lifecycle logic;
- не меняем selector contract `fission.io/managed=true`.
@@ -0,0 +1,20 @@
# 2026-04-26 — NamespaceManager rewrite, step 44
## Цель шага
Убрать последний дублирующийся orchestration-код из `StartNSWatcher()` в трёх компонентах.
## Что меняем
1. В `utils` добавляем `PrepareManagedNamespaceWatcher()`.
2. Helper:
- создаёт `NamespaceManager`;
- делает bootstrap+dispatch;
- собирает общие event handlers.
3. `buildermgr`, `router`, `executor/multitenant` используют этот helper.
## Что НЕ меняем
- не меняем subscriber logic;
- не меняем managed namespace watcher startup helper;
- не меняем removal strategy по умолчанию.
@@ -0,0 +1,20 @@
# 2026-04-26 — NamespaceManager rewrite, step 45
## Цель шага
Подготовить компактный status/debug surface для `NamespaceManager`.
## Что меняем
1. Добавляем `NamespaceManagerSummary`.
2. В `NamespaceManager` добавляем `Summary()`.
3. Summary считает:
- общее число namespace-ов;
- число по phase;
- список subscriber-ов.
4. Добавляем unit tests.
## Что НЕ меняем
- не публикуем summary наружу через HTTP;
- не меняем watcher behavior.
@@ -0,0 +1,33 @@
# 2026-04-26 — NamespaceManager rewrite, step 46
## Цель шага
Закрыть маленький пробел в debug surface: `LogNamespaceManagerSummary()` уже используется, но отдельно не тестируется.
## Что меняем
1. Добавляем unit test на `LogNamespaceManagerSummary()`.
2. Проверяем, что helper безопасен на `nil` logger и не паникует на заполненном summary.
## Что НЕ меняем
- не меняем runtime behavior;
- не публикуем summary наружу через HTTP.# 2026-04-26 — NamespaceManager rewrite, step 46
## Цель шага
Начать реальное использование `NamespaceManager.Summary()` в orchestration layer.
## Что меняем
1. Добавляем helper `LogNamespaceManagerSummary()`.
2. `PrepareManagedNamespaceWatcher()` пишет summary после bootstrap.
3. В лог попадают:
- общее число namespace-ов;
- subscriber-ы;
- phase counts.
## Что НЕ меняем
- не экспортируем summary наружу через HTTP;
- не меняем runtime behavior watcher-ов.
@@ -0,0 +1,17 @@
# 2026-04-26 — NamespaceManager rewrite, step 47
## Цель шага
Сделать `NamespaceManagerSummary` информативнее для наблюдения за источниками namespace state.
## Что меняем
1. В summary добавляем `SourceCounts`.
2. `Summary()` считает namespace-ы по `NamespaceSource`.
3. `LogNamespaceManagerSummary()` пишет `source_counts`.
4. Обновляем unit tests.
## Что НЕ меняем
- не меняем watcher behavior;
- не меняем semantics state transitions.
@@ -0,0 +1,33 @@
# 2026-04-26 — NamespaceManager rewrite, step 48
## Цель шага
Добавить маленький, но полезный helper поверх summary/debug contract: проверку, есть ли вообще живые namespace-ы.
## Что меняем
1. В `NamespaceManagerSummary` добавляем `HasActiveNamespaces()`.
2. Добавляем unit tests на true/false path.
## Что НЕ меняем
- не меняем summary counters;
- не меняем watcher behavior.# 2026-04-26 — NamespaceManager rewrite, step 48
## Цель шага
Убрать двусмысленность в `NamespaceManagerSummary`: сейчас `TotalNamespaces` включает и removed-записи.
## Что меняем
1. Добавляем `LiveNamespaces`.
2. `Summary()` считает его по `Snapshot()`.
3. `LogNamespaceManagerSummary()` пишет оба значения:
- `total_namespaces`
- `live_namespaces`
4. Обновляем unit tests.
## Что НЕ меняем
- не меняем правила хранения removed records;
- не меняем watcher behavior.
@@ -0,0 +1,35 @@
# 2026-04-26 — NamespaceManager rewrite, step 49
## Цель шага
Довести `HasActiveNamespaces()` до реального use-site, чтобы helper не оставался чисто декларативным.
## Что изменено
1. `LogNamespaceManagerSummary()` теперь пишет флаг `has_active_namespaces`.
2. Добавлен unit test на presence и значение этого поля в structured log.
## Почему это безопасно
- watcher behavior не меняется;
- изменён только debug/logging contract;
- покрыто `go test ./pkg/utils/...`.# 2026-04-26 — NamespaceManager rewrite, step 49
## Цель шага
Собрать `prepare + start` managed namespace watcher в один общий entrypoint.
## Что меняем
1. Добавляем `RunManagedNamespaceWatcher()`.
2. Helper:
- готовит manager;
- строит handlers;
- запускает managed namespace informer.
3. Три `StartNSWatcher()` переходят на новый entrypoint.
4. Добавляем минимальный unit test с fake client.
## Что НЕ меняем
- не меняем subscriber logic;
- не меняем selector/strategy semantics.
@@ -0,0 +1,29 @@
# 2026-04-26 — NamespaceManager rewrite, step 5
## Цель шага
Исправить несимметрию между startup-path и dynamic namespace onboarding в `newdeploy` executor.
## Дефект
На старте `MakeNewDeploy()` регистрирует два вида обработчиков на Fission informers:
- `FunctionEventHandlers()`
- `EnvEventHandlers()`
Но dynamic `AddNamespace()` регистрировал только `FunctionEventHandlers()`.
Это означало, что namespace, появившийся после старта процесса, обслуживается не тем же
код-path, что namespace, известный на старте. Для multi-tenant Layer 1 это плохая семантика:
часть поведения newdeploy зависит не от namespace, а от момента его появления.
## Исправление
В `AddNamespace()` добавляется регистрация `EnvEventHandlers()` перед запуском informer factory.
## Что НЕ меняем
- не меняем container executor;
- не меняем poolmgr;
- не добавляем remove semantics;
- не меняем router.
@@ -0,0 +1,32 @@
# 2026-04-26 — NamespaceManager rewrite, step 50
## Цель шага
Сделать summary/debug surface полезным в реальном watcher lifecycle, а не только на этапе подготовки manager-а.
## Что изменено
1. После успешных add/resync/remove transitions watcher helpers теперь пишут компактный summary manager-а.
2. Добавлен unit test на add-handler path с проверкой structured-log полей.
## Что это даёт
- runtime behavior не меняется;
- появляется последовательный debug trail по изменению manager state;
- новый helper `HasActiveNamespaces()` теперь используется и в general logging path, и в watcher transition path.# 2026-04-26 — NamespaceManager rewrite, step 50
## Цель шага
Сделать orchestration API для managed namespace watcher-а жёстче и читабельнее.
## Что меняем
1. Добавляем `ManagedNamespaceWatcherConfig`.
2. `PrepareManagedNamespaceWatcher()` и `RunManagedNamespaceWatcher()` принимают config struct.
3. Если strategy не задана, используется `track-only`.
4. Обновляем unit tests и call sites.
## Что НЕ меняем
- не меняем runtime semantics;
- не меняем subscriber logic.
@@ -0,0 +1,33 @@
# 2026-04-26 — NamespaceManager rewrite, step 51
## Цель шага
Закрыть observability gap между `prepared namespace manager` и runtime transition logs.
## Что изменено
1. `RunManagedNamespaceWatcher()` теперь пишет единый summary log после старта watcher-а.
2. Добавлен unit test на startup logging path.
## Почему это полезно
- buildermgr, router и executor получают одинаковый startup debug signal без копипасты;
- видно состояние manager-а в момент, когда watcher уже реально подключён;
- runtime semantics не меняется.# 2026-04-26 — NamespaceManager rewrite, step 51
## Цель шага
Убрать из call sites повторение стандартного config для managed namespace watcher-а.
## Что меняем
1. Добавляем `NewDefaultManagedNamespaceWatcherConfig()`.
2. Helper подставляет:
- `DefaultNSResolver().Snapshot()`;
- `track-only` как default removal strategy.
3. `buildermgr`, `router`, `executor/multitenant` используют helper.
## Что НЕ меняем
- не меняем runtime semantics;
- не меняем subscriber logic.
@@ -0,0 +1,17 @@
# 2026-04-26 — NamespaceManager rewrite, step 52
## Цель шага
Убрать хрупкость общего watcher path, где `nil` logger мог привести к panic на error/info ветках.
## Что изменено
1. Введена централизованная нормализация logger-а к `zap.NewNop()`.
2. Hardening применён к prepare/run/start и watcher event handlers.
3. Добавлены regression tests на nil-logger path.
## Почему это важно
- это уже runtime hardening, а не декоративный cleanup;
- общий helper layer стал безопаснее для повторного использования;
- поведение watcher-ов не меняется, меняется только устойчивость logging path.
@@ -0,0 +1,24 @@
# 2026-04-26 — NamespaceManager rewrite, step 53
## Итог step1
`rewrite/layer1-namespace-manager-step1` можно считать завершённым как отдельный этап.
## Критерии, которые теперь выполнены
1. Общий `NamespaceManager` и watcher orchestration вынесены в `pkg/utils`.
2. Buildermgr, router и executor/multitenant используют общий helper layer вместо прежней разрозненной lifecycle-логики.
3. Summary/debug contract стабилизирован и покрыт тестами.
4. Logging path усилен: есть prepare/start/transition summary logs и nil-logger hardening.
## Финальная проверка этапа
Пройден целевой набор:
`go test ./pkg/utils/... ./pkg/buildermgr/... ./pkg/router/... ./pkg/executor/multitenant`
Все пакеты зелёные.
## Что дальше
Следующий этап должен быть уже не про внутреннюю консолидацию watcher layer, а про внешний consumption этой модели: status/debug surface, integration behavior или следующий слой rewrite.
@@ -0,0 +1,34 @@
# 2026-04-26 — NamespaceManager rewrite, step 6
## Цель шага
Закрыть race-surface в router вокруг динамического добавления namespace informer-ов.
## Проблема
В router есть два связанных mutable map:
- `HTTPTriggerSet.triggerInformer`
- `HTTPTriggerSet.funcInformer`
`AddNamespace()` пишет в них на лету, а `updateRouter()` одновременно итерируется по ним.
Кроме того, `functionReferenceResolver` получает `funcInformer` map и читает ее без синхронизации.
Это делает dynamic onboarding потенциальным источником:
- `concurrent map iteration and map write`;
- чтения неполного снимка informer-ов;
- гонок между router rebuild и resolver lookup.
## Исправление
1. В `HTTPTriggerSet` добавляется `RWMutex` для informer maps.
2. Чтение informer-ов переводится на snapshot helpers.
3. `functionReferenceResolver` получает собственный lock и метод `addInformer()`.
4. `router.AddNamespace()` обновляет router map и resolver map под контролируемым доступом.
## Что НЕ меняем
- не переписываем router lifecycle целиком;
- не добавляем remove semantics;
- не меняем trigger/function business logic.
@@ -0,0 +1,36 @@
# 2026-04-26 — NamespaceManager rewrite, step 7
## Цель шага
Добавить минимальную модель данных для будущего `NamespaceManager`, не меняя пока production wiring.
## Почему это отдельный шаг
После шагов 1-6 уже стало ясно, что следующая стадия — не ещё один patch по месту, а переход к явной модели lifecycle.
Но сразу подключать новый manager к watcher-ам и компонентам рано. Сначала нужна опорная модель:
- `NamespacePhase`
- `NamespaceSource`
- `NamespaceEventType`
- `NamespaceRecord`
- `NamespacePartState`
## Что меняем
1. Добавляем новый файл с типами model layer.
2. Добавляем helper-методы:
- `Clone()`
- `IsActive()`
- `IsTerminal()`
3. Добавляем unit tests на:
- корректный deep copy;
- active semantics;
- terminal semantics.
## Что НЕ меняем
- не подключаем manager к production path;
- не меняем watcher-ы;
- не меняем resolver;
- не затрагиваем текущее изменение в `serviceaccount.go`.
@@ -0,0 +1,25 @@
# 2026-04-26 — NamespaceManager rewrite, step 8
## Цель шага
Добавить skeleton `NamespaceManager` с in-memory state и unit tests.
## Что меняем
1. Добавляем interface `NamespaceManager`.
2. Добавляем in-memory реализацию с mutex.
3. Добавляем операции:
- `Snapshot()`
- `SnapshotRecords()`
- `Get()`
- `Upsert()`
- `MarkPartState()`
- `Remove()`
4. Добавляем unit tests на snapshot/get/upsert/remove/part-state.
## Что НЕ меняем
- не подключаем manager к watcher-ам;
- не меняем текущий resolver path;
- не трогаем runtime components;
- не затрагиваем отдельное незакоммиченное изменение в `serviceaccount.go`.
@@ -0,0 +1,20 @@
# 2026-04-26 — NamespaceManager rewrite, step 9
## Цель шага
Добавить subscriber contract в `NamespaceManager`, не подключая его пока к runtime.
## Что меняем
1. Добавляем interface `NamespaceSubscriber`.
2. Добавляем в manager операции:
- `Subscribe()`
- `SnapshotSubscribers()`
3. Добавляем unit tests на регистрацию и snapshot subscriber-ов.
## Что НЕ меняем
- не вызываем subscriber-ов из watcher-ов;
- не строим reconcile loop;
- не трогаем runtime components;
- не затрагиваем внешнее изменение в `serviceaccount.go`.
@@ -0,0 +1,697 @@
# 2026-04-26 — Target design: полноценный NamespaceManager для Layer 1
## Зачем нужен ещё один документ
Уже есть подробный документ про сделанные шаги 1-6.
Но этого недостаточно для следующего этапа, потому что:
1. История исправлений не равна целевой архитектуре.
2. Локальные фиксы уже уменьшили риск, но не дали единого lifecycle contract.
3. Следующий этап уже нельзя начинать как серию хаотичных патчей по месту.
Нужен отдельный документ, который отвечает на вопрос:
какой именно Layer 1 мы хотим получить в результате bounded rewrite.
---
## Коротко: что именно строим
Нужен не просто thread-safe registry namespace-ов, а orchestration layer с явным lifecycle.
То есть не объект вида:
- `map[string]string` + `AddNamespace()`
а объект вида:
- обнаружение namespace;
- нормализация состояния;
- единый жизненный цикл add/remove/reconcile;
- подписка компонентов на события;
- безопасный snapshot для background loops;
- backfill existing namespaces on startup;
- восстановление после restart.
Рабочее имя этой сущности: `NamespaceManager`.
---
## Какую проблему он решает
Сейчас логика размазана по нескольким слоям одновременно:
1. `NamespaceResolver` хранит registry.
2. watcher-ы executor/router/buildermgr сами решают, как регистрировать namespace.
3. components сами придумывают свой dedup.
4. часть background loops читают namespace snapshot.
5. provisioning SA/RBAC живёт как side effect watcher-а.
Из-за этого нет одного ответа на вопросы:
1. Когда namespace считается «принятым» системой?
2. Когда он считается «удалённым»?
3. Что должно происходить при restart компонента?
4. Кто отвечает за cleanup?
5. Кто отвечает за reconcile при расхождении локального и фактического состояния?
`NamespaceManager` нужен именно для того, чтобы эти вопросы получили один общий ответ.
---
## Какие свойства должны быть у новой подсистемы
### 1. Один вход для namespace lifecycle
Все namespace-ы, независимо от того, пришли они:
- из env на старте;
- из уже существующих labeled namespaces;
- из нового namespace event;
- из relabel existing namespace;
должны проходить через один и тот же pipeline.
### 2. Явный state machine
Нельзя больше жить в модели «namespace либо есть в map, либо нет». Нужны как минимум фазы:
- discovered;
- registering;
- active;
- deregistering;
- removed;
- failed.
Не обязательно все эти фазы сразу экспонировать наружу, но внутренняя модель должна понимать, на каком этапе lifecycle находится namespace.
### 3. Разделение ответственности
Нужно развести по слоям:
1. Discovery — кто узнал о namespace.
2. Registry — текущее состояние namespace в памяти процесса.
3. Reconcile — как довести локальное состояние до желаемого.
4. Subscription — как сообщить executor/router/buildermgr о событии.
5. Provisioning — отдельные side effects вроде SA/RBAC.
### 4. Thread-safe чтение и запись
Любой компонент должен иметь один безопасный способ получить:
- snapshot namespace-ов;
- текущее состояние конкретного namespace;
- stream событий.
### 5. Symmetry startup vs runtime
Если namespace был известен на старте или пришёл позже, конечный набор действий должен быть одинаковым.
Именно этот пункт был нарушен в `newdeploy`, и именно он должен стать жёстким архитектурным правилом нового дизайна.
---
## Что не должно быть в новой модели
### 1. Прямых чтений глобальной map из произвольных мест
Любой код, который напрямую читает внутреннюю структуру namespace registry, должен считаться legacy и подлежать выносу.
### 2. Глобального dedup вместо локального lifecycle
Global registry отвечает только на вопрос «namespace известен системе». Он не должен автоматически означать «каждый компонент уже подключил все свои informers».
### 3. Неявных side effects в watcher callback
Watcher должен сообщать о факте, а не выполнять пол-процесса orchestration сам по себе.
### 4. Скрытой зависимости от порядка вызовов
Сейчас уже был пойман дефект, когда второй компонент не регистрировался, потому что первый успел пометить namespace как «уже обработанный». Новая модель должна быть инвариантна к порядку subscriber-ов.
---
## Предлагаемая модель данных
Ниже не обязательно точный конечный код, но это целевая форма.
```go
type NamespacePhase string
const (
NamespacePhaseDiscovered NamespacePhase = "discovered"
NamespacePhaseRegistering NamespacePhase = "registering"
NamespacePhaseActive NamespacePhase = "active"
NamespacePhaseDeregistering NamespacePhase = "deregistering"
NamespacePhaseRemoved NamespacePhase = "removed"
NamespacePhaseFailed NamespacePhase = "failed"
)
type NamespaceRecord struct {
Name string
Source NamespaceSource
Labels map[string]string
Phase NamespacePhase
LastError string
Generation int64
UpdatedAt time.Time
RegisteredParts map[string]NamespacePartState
}
type NamespacePartState struct {
State string
LastError string
UpdatedAt time.Time
}
```
Важная идея: manager должен знать не только список namespace-ов, но и состояние регистрации по частям.
Например:
- executor.poolmgr: active
- executor.newdeploy: active
- router: active
- buildermgr.env: active
- buildermgr.pkg: failed
- provisioning.fetcher-sa: active
Это критично для reconcile. Иначе при частичном падении система знает только «namespace есть», но не знает, что именно недорегистрировано.
---
## Источники namespace-ов
Нужен явный тип источника, чтобы не смешивать namespace-ы с разным происхождением.
```go
type NamespaceSource string
const (
NamespaceSourceEnv NamespaceSource = "env"
NamespaceSourceWatcher NamespaceSource = "watcher"
NamespaceSourceBackfill NamespaceSource = "backfill"
)
```
Почему это важно:
1. Проще расследовать состояние системы.
2. Проще логировать, откуда namespace попал в менеджер.
3. Проще понять, что именно должно переживать restart и что должно исчезать при relabel/delete.
---
## Предлагаемый API NamespaceManager
Ниже не «идеальный forever API», а минимально полезный контракт.
```go
type NamespaceManager interface {
Snapshot() []string
SnapshotRecords() []NamespaceRecord
Get(name string) (NamespaceRecord, bool)
RegisterDesired(ctx context.Context, event NamespaceEvent) error
DeregisterDesired(ctx context.Context, name string, reason string) error
Subscribe(name string, subscriber NamespaceSubscriber)
Start(ctx context.Context)
}
```
И ещё важнее — не только sync API, но и события.
```go
type NamespaceEventType string
const (
NamespaceEventAdd NamespaceEventType = "add"
NamespaceEventUpdate NamespaceEventType = "update"
NamespaceEventRemove NamespaceEventType = "remove"
NamespaceEventResync NamespaceEventType = "resync"
)
type NamespaceEvent struct {
Type NamespaceEventType
Name string
Labels map[string]string
Source NamespaceSource
ObservedAt time.Time
}
type NamespaceSubscriber interface {
Name() string
OnNamespaceAdd(ctx context.Context, ns NamespaceRecord) error
OnNamespaceRemove(ctx context.Context, ns NamespaceRecord) error
OnNamespaceResync(ctx context.Context, ns NamespaceRecord) error
}
```
---
## Как должен работать startup
Это один из самых важных разделов. Сейчас именно startup/runtime symmetry остаётся центральным требованием.
### Текущий анти-pattern
Сначала что-то строится по env namespaces, потом dynamic path делает другой набор действий отдельно.
### Целевой startup
При старте процесса manager должен:
1. Собрать namespaces из env.
2. Сделать backfill всех существующих namespaces с label `fission.io/managed=true`.
3. Нормализовать список без дублей.
4. Сформировать initial desired set.
5. Пропустить весь этот set через тот же reconcile pipeline, что и поздние события.
6. Только потом считать manager готовым.
Иначе говоря:
startup — это просто массовый initial reconcile, а не отдельная логика «в обход».
---
## Как должен работать runtime add
Когда watcher видит новый namespace или relabel в `managed=true`, он не должен сам лезть во все компоненты.
Он должен только отправить event в manager:
```go
RegisterDesired(NamespaceEvent{Type: Add, Name: ns, Source: Watcher, Labels: ...})
```
Дальше manager:
1. Обновляет/создаёт `NamespaceRecord`.
2. Ставит phase `registering`.
3. По подписчикам запускает reconcile `OnNamespaceAdd`.
4. Фиксирует state каждой части.
5. Если все обязательные части успешны, переводит namespace в `active`.
6. Если часть упала, переводит в `failed` с возможностью повторной reconcile.
Это важно: add должен быть idempotent и retry-friendly.
---
## Как должен работать runtime remove
Это следующий большой пробел в текущем Layer 1.
Нужен единый remove path для двух случаев:
1. namespace удалён;
2. label `fission.io/managed=true` снят.
Пайплайн должен быть таким:
1. Watcher сообщает `remove` event.
2. Manager помечает namespace как `deregistering`.
3. Вызывает `OnNamespaceRemove` у подписчиков.
4. Каждый подписчик:
- останавливает локальные informers;
- удаляет namespace из локальных lister maps;
- очищает связанный cache state.
5. После успешного снятия подписок manager переводит namespace в `removed` или удаляет запись полностью.
Главная причина делать это централизованно:
если remove semantics будут разъезжаться по компонентам, получится новая версия текущей проблемы, только уже в lifecycle удаления.
---
## Как должен работать reconcile
Remove/add недостаточно. Нужен ещё reconcile.
Причины:
1. Компонент мог стартовать позже manager-а.
2. Подписчик мог упасть на середине регистрации namespace.
3. Restart процесса может привести к тому, что локальная память пуста, а кластерное состояние уже существует.
Поэтому manager должен уметь периодически или по событию заново прогонять namespace через subscriber-ов.
Например:
```go
OnNamespaceResync(ctx, ns)
```
Или через тот же `OnNamespaceAdd`, если он строго idempotent.
Инженерно я бы предпочёл следующее правило:
1. `OnNamespaceAdd` и `OnNamespaceResync` могут быть одной реализацией.
2. Но семантически различать их всё равно полезно для логов и метрик.
---
## Кто должен быть subscriber-ами
### 1. Executor subscriber
Внутри него можно уже вызывать внутренние add/remove/resync по типам:
- poolmgr
- newdeploy
- container
Но для manager это один subscriber уровня executor.
Почему это лучше:
1. Manager не должен знать детали каждого executor type.
2. Executor сам лучше знает, что для него является complete registration.
### 2. Router subscriber
Отвечает за:
- func informer;
- trigger informer;
- resolver informer registry;
- invalidate/rebuild path.
### 3. BuilderMgr subscriber
Но внутри него стоит сделать внутреннее разделение частей:
- env watcher part;
- pkg watcher part.
Именно потому, что на этом месте уже был пойман баг локального dedup.
### 4. Provisioning subscriber
Отдельный subscriber для:
- `fission-fetcher` SA;
- возможно builder SA;
- связанных Role/RoleBinding path.
Почему это должен быть отдельный subscriber:
сейчас provisioning встроен как side effect watcher-а, а это делает sequencing слишком хрупким и плохо наблюдаемым.
---
## Почему provisioning нужно вынести отдельно
Сейчас логика «namespace зарегистрирован» и логика «в namespace создан нужный service account + RBAC» слишком слеплены.
Это вредно по нескольким причинам:
1. Трудно диагностировать, что именно сломалось: discovery, informer wiring или RBAC provisioning.
2. Нельзя отдельно повторить provisioning без повторного полного namespace registration.
3. Нельзя нормально отслеживать частичный success.
Целевой дизайн:
- manager знает, что provisioning — это отдельная обязательная или полуобязательная часть namespace lifecycle;
- provisioning subscriber отдаёт свой статус отдельно;
- при необходимости его можно повторно reconcile без переинициализации router/executor/buildermgr.
---
## Нужен ли новый объект вместо NamespaceResolver
Да, но не обязательно удалять `NamespaceResolver` в один момент.
Реалистичная стратегия:
### Этап A
Сделать `NamespaceResolver` внутренней реализацией snapshot/compat layer.
### Этап B
Поверх него построить `NamespaceManager` как orchestration layer.
### Этап C
Постепенно вычистить прямые зависимости компонентов от `NamespaceResolver` и перевести их на manager/subscriber contract.
Почему так, а не сразу delete old resolver:
1. Слишком много мест уже используют текущие helper-ы.
2. Нужен период совместного существования старого snapshot API и нового orchestration API.
3. Иначе blast radius снова станет слишком большим.
---
## Минимальный состав внутренних методов manager-а
Ниже не внешний API, а то, что почти наверняка понадобится внутри.
```go
func (m *manager) upsertRecord(event NamespaceEvent) NamespaceRecord
func (m *manager) markPartState(ns string, subscriber string, state NamespacePartState)
func (m *manager) markPhase(ns string, phase NamespacePhase, err error)
func (m *manager) snapshotActiveNamespaces() []string
func (m *manager) emit(event internalEvent)
func (m *manager) reconcileNamespace(ctx context.Context, name string)
func (m *manager) removeNamespace(ctx context.Context, name string)
```
Причина: если manager не умеет хранить part-level state, он снова выродится в glorified map.
---
## Какой порядок вызовов нужен при add
Не просто «вызвать всех subscriber-ов подряд». Нужна осознанная последовательность.
Один из возможных вариантов:
1. Provisioning subscriber
2. BuilderMgr subscriber
3. Executor subscriber
4. Router subscriber
Но это не единственный вариант. Важно другое: порядок должен быть явным и объяснимым.
Почему provisioning логично раньше:
если namespace ещё не имеет нужного service account, часть runtime path может не подняться корректно.
Почему router можно позже:
он меньше зависит от SA provisioning, чем runtime execution path.
Но я бы не жёстко кодировал этот порядок как случайную последовательность callback-ов. Лучше иметь явно заданную subscriber order policy.
---
## Как manager должен вести себя при частичном падении
Это одна из самых важных деталей, потому что сейчас система часто мыслит бинарно: success/fail.
Нужно поведение такого типа:
1. Executor зарегистрировался успешно.
2. Router зарегистрировался успешно.
3. BuilderMgr не зарегистрировался.
4. Namespace получает phase `failed` или `active-with-errors`.
5. В record фиксируется, что именно сломалось.
6. Reconcile можно повторить только для buildermgr part.
Именно это позволит избегать режимов «namespace вроде есть, но реально не полностью обслуживается, а система этого не видит».
---
## Метрики и логирование
Без этого новый manager будет трудно отлаживать.
Нужно как минимум:
### Метрики
- число active namespaces;
- число failed namespaces;
- число reconcile attempts;
- число add/remove events;
- количество ошибок по subscriber-ам.
### Логи
На каждое важное событие должны быть логи такого класса:
- namespace discovered;
- namespace registration started;
- subscriber registration succeeded;
- subscriber registration failed;
- namespace active;
- namespace deregistering;
- namespace removed;
- resync started/completed.
Без этого следующая стадия дебага снова упрётся в разрозненные логи компонентов.
---
## Тестовая стратегия для нового этапа
Нельзя ограничиться только unit tests отдельных helper-ов.
Нужны как минимум четыре слоя проверок.
### 1. Unit tests manager state machine
- add нового namespace;
- повторный add идемпотентен;
- remove переводит в нужную фазу;
- partial failure отражается в part states.
### 2. Unit tests subscriber ordering / reconcile
- add вызывает всех нужных subscriber-ов;
- failure одного subscriber-а не портит состояние других;
- повторный resync догоняет незарегистрированную часть.
### 3. Component tests
- buildermgr add/remove;
- router add/remove;
- newdeploy add parity;
- executor resync.
### 4. End-to-end tests
- startup with existing managed namespaces;
- late namespace add;
- relabel add;
- label removal;
- namespace delete;
- process restart;
- burst onboarding.
---
## Как бы я разбил реализацию следующего этапа на коммиты
Это очень важно: не повторять ошибку большого rewrite.
### Commit A
Добавить скелет `NamespaceManager` и in-memory record model без подключения компонентов.
Цель:
- новый тип существует;
- есть unit tests state model;
- legacy path ещё не тронут.
### Commit B
Подключить discovery path: env + namespace watcher events начинают идти в manager.
Но subscribers пока можно ограничить одним compatibility subscriber.
### Commit C
Сделать provisioning отдельным subscriber-ом.
### Commit D
Перевести buildermgr на manager/subscriber contract.
Почему именно buildermgr первым:
там уже был пойман реальный dedup defect, и логика явно просит более чистый lifecycle.
### Commit E
Перевести router на manager/subscriber contract.
### Commit F
Перевести executor subscriber.
### Commit G
Добавить remove/relabel/delete lifecycle.
### Commit H
Вычистить legacy прямые обращения к resolver там, где это уже возможно.
---
## Что можно оставить совместимым на переходный период
Не всё нужно ломать сразу.
Можно временно оставить:
1. `Snapshot()` API у `NamespaceResolver` как compatibility layer.
2. Часть существующих helper-ов для informer factory creation.
3. Отдельные component-specific `AddNamespace()` методы, но вызывать их уже через manager subscriber.
Это позволит переподключать компоненты последовательно.
---
## Какие риски у самого NamespaceManager rewrite
Нужно честно фиксировать и риски новой архитектуры.
### 1. Over-centralization
Если сделать manager слишком умным, он начнёт знать внутренности каждого компонента, и получится новый монолит уже поверх старого.
Поэтому manager должен оркестрировать lifecycle, но не содержать доменную логику executor/router/buildermgr.
### 2. Deadlocks или долгие lock sections
Если state manager будет держать lock во время вызова subscriber-ов, это плохой дизайн.
Нужно правило:
- lock только на обновление внутреннего state;
- вызовы subscriber-ов делать вне глобального lock.
### 3. Excessive retries
Если reconcile не ограничить и не сделать наблюдаемым, можно получить noisy system с бесконечными повторными попытками.
### 4. Confused ownership
Если не определить, кто отвечает за remove/reconcile конкретной части, получится новая версия старой размазанной логики.
---
## Что я считаю правильным следующим шагом после этого документа
Не сразу кодить full manager.
Сначала нужен ещё один маленький подготовительный шаг:
1. Добавить новый package или файл со skeleton model `NamespaceRecord`, `NamespacePhase`, `NamespaceEvent`.
2. Покрыть его unit tests.
3. Не подключать пока к production lifecycle.
Почему:
это даст опорную модель данных, вокруг которой уже можно строить manager, не смешивая сразу storage, watchers и subscribers.
---
## Итог
Целевой `NamespaceManager` для Layer 1 — это не «один общий namespace» и не «ещё один helper над map`ой`».
Это должен быть orchestration слой с пятью обязательными свойствами:
1. единый lifecycle add/remove/resync;
2. state model с phase и part-level status;
3. подписчики-компоненты вместо хаотичных side effects;
4. symmetry startup и runtime onboarding;
5. безопасный reconcile после ошибок и restart.
Только после этого можно сказать, что Layer 1 действительно перестал быть монопользовательским Fission с набором динамических заплаток и стал многопользовательским control-plane слоем с понятным жизненным циклом.
+135
View File
@@ -0,0 +1,135 @@
# 2026-04-26 — RBAC fix для multi-tenant SA provisioning
## Симптом
`test_layer1.sh` шаг 5 падает: pod poolmgr не создаётся в динамически добавленном NS.
Event: `serviceaccount "fission-fetcher" not found`
## Путь диагностики
1. **Код есть**`EnsureNamespaceSA` добавлена в `serviceaccount.go`, вызывается из `ns_watcher.go:168`
2. **Образ задеплоен** — v8 работает, executor регистрирует NS (шаги 1-4 PASS)
3. **RBAC проверка**: `kubectl auth can-i create serviceaccounts --as=...fission-executor -n l1-test-77773`**`no`**
4. **ClusterRole `fission-executor-multi-ns`** имеет только `get/list/watch` для serviceaccounts, нет rules для `roles`/`rolebindings`
## Вывод
`setupSAAndRoleBindings` вызывается, но k8s отвечает 403 → функция тихо логирует ошибку и возвращает → SA не создаётся.
## Решение
Исправить `deploy/multitenant/rbac.yaml` — добавить ClusterRole с нужными правами + ClusterRoleBinding.
## Сделано
- Добавлен ClusterRole `fission-executor-sa-provisioner` с `create/update/patch` для `serviceaccounts`, `roles`, `rolebindings` (namespace-scoped через ClusterRole)
- Добавлен ClusterRoleBinding к SA `fission-executor` в NS `fission`
- `kubectl apply` — применено
- Верификация: `kubectl auth can-i create serviceaccounts/roles/rolebindings`**`yes/yes/yes`** ✅
## Результат после RBAC fix (2026-04-26)
Применено, RBAC проверка: `yes/yes/yes`
SA `fission-fetcher` создаётся в новом NS за 15 сек ✅
Тест `test_layer1.sh` всё равно 4/5 FAIL ❌
---
## Новая проблема — executor timeout при вызове функции
### Симптом
Шаг 5 (`вызываем функцию`): `HTTP 500 — error sending request to function`
Лог router:
```
function service entry timeout (60.000000)s exceeded
error posting to getting service for function: POST http://executor.fission/v2/getServiceForFunction
giving up after 4 attempt(s): context deadline exceeded
function: {namespace: l1-test-78841, name: hello}
```
### Что происходит
Router обращается к executor `/v2/getServiceForFunction`, executor не отвечает в течение 60 сек.
SA `fission-fetcher` уже есть (RBAC fix помог). Но poolmgr pod так и не запустился или executor не может создать service entry.
### Что нужно проверить
1. Есть ли pod poolmgr в NS `l1-test-78841`?
2. Если pod не создаётся — события в NS (`kubectl get events -n l1-test-78841`)
3. Если pod есть — логи executor (`kubectl logs -n fission deploy/executor`)
4. Может ли executor вообще видеть функции в динамически добавленном NS?
### Гипотезы
A. **Executor не видит функцию** — NS зарегистрирован в NSWatcher, но executor informer не получил Function объект → `getServiceForFunction` не знает о функции → timeout.
B. **poolmgr pod не стартует** — новая RBAC проблема или другой ресурс отсутствует.
C. **Executor видит функцию, но pool не готов** — cold start > 60 сек (маловероятно для Python hello).
---
## Обновление анализа — найден реальный RBAC root cause
### Подтверждённые факты
- Pool pod в новом NS создаётся и выходит в `Running`.
- `readyPod controller started` есть в логах executor.
- Ошибка возникает раньше/ниже: при `EnsureNamespaceSA` executor создаёт `ServiceAccount`, но не может создать `Role` полностью.
### Точный лог ошибки
```
error while creating role for sa fission-fetcher in namespace diag-ns-82702
roles.rbac.authorization.k8s.io ... is forbidden: user "system:serviceaccount:fission:fission-executor"
is attempting to grant RBAC permissions not currently held:
{APIGroups:[""], Resources:["events"], Verbs:["create"]}
```
Также перед этим:
```
localsubjectaccessreviews.authorization.k8s.io is forbidden
User "system:serviceaccount:fission:fission-executor" cannot create resource
"localsubjectaccessreviews"
```
### Вывод
Предыдущий RBAC fix был неполным.
Для динамического SA provisioning executor нужны не только:
- `serviceaccounts.create/update/patch`
- `roles.create/update/patch`
- `rolebindings.create/update/patch`
Но и ещё:
- `events.create` — иначе Kubernetes запрещает executor создавать Role, которая выдаёт `events.create` fetcher-у.
- `authorization.k8s.io/localsubjectaccessreviews.create` — иначе `checkPermission()` не может проверить текущие права SA.
### Исправление
Расширить `deploy/multitenant/rbac.yaml` для `fission-executor-sa-provisioner`:
- core `events`: `create`
- `authorization.k8s.io` `localsubjectaccessreviews`: `create`
После этого нужно:
1. `kubectl apply -f deploy/multitenant/rbac.yaml`
2. Создать новый test NS
3. Убедиться, что `Role` и `RoleBinding` для `fission-fetcher` создаются
4. Повторить `test_layer1.sh`
---
## Следующий найденный blocker — router RBAC
После полного executor RBAC fix `test_layer1.sh` изменил симптом:
- раньше шаг 5 падал с `500` и timeout на `executor /v2/getServiceForFunction`
- теперь шаг 5 падает с постоянным `404`
Лог router:
```
Failed to watch err="failed to list *v1.Namespace: namespaces is forbidden:
User \"system:serviceaccount:fission:fission-router\" cannot list resource
\"namespaces\" in API group \"\" at the cluster scope"
```
### Вывод
Executor-path уже починен, но router NSWatcher не работает, потому что у SA
`fission-router` нет cluster-scope прав `list/watch` на `namespaces`.
### Исправление
Добавить в `deploy/multitenant/rbac.yaml` ещё один набор ресурсов:
- `ClusterRole/fission-router-ns-watcher`
- `ClusterRoleBinding/fission-router-ns-watcher`
С правами:
- core `namespaces`: `list`, `watch`
@@ -0,0 +1,115 @@
# 2026-04-26 - Почему Sonnet 4.6 мог застрять на Layer1 и в чём он может быть сильнее
## Зачем этот документ
После успешного завершения кейса возник мета-вопрос:
- почему другая модель могла не дойти до рабочего решения
- в чём она всё же может быть объективно лучше
Документ нужен как заметка о процессе расследования, а не о самом кодовом fix.
## Почему Sonnet 4.6 мог не дожать именно этот кейс
### Кейс был каскадным
Здесь не было одного простого корня.
Последовательность была такой:
1. отсутствует `fission-fetcher`
2. потом выясняется недостаток прав на `Role/RoleBinding`
3. потом выясняется, что не хватает ещё и делегируемых permission-ов (`events.create`)
4. потом выясняется, что не хватает `localsubjectaccessreviews.create`
5. потом executor-path становится рабочим, но router-path всё ещё сломан
6. затем обнаруживается отсутствие namespace watch/list у `fission-router`
Модель, которая мыслит в режиме "нашёл корень -> исправил -> готово", на таком сценарии часто останавливается слишком рано.
### Симптомы менялись и маскировали прогресс
Промежуточные симптомы были:
- `serviceaccount not found`
- `500 timeout`
- `404`
- `200`
Это классический случай, где изменение симптома означает не провал, а смену активного bottleneck.
Если интерпретировать это неправильно, расследование начинает метаться.
### Нужно было понимать RBAC delegation, а не только RBAC access
Ключевая тонкость кейса:
- executor создаёт `Role` для fetcher
- эта `Role` выдаёт `events.create`
- Kubernetes запрещает создавать `Role`, делегирующую permission, которого нет у самого вызывающего субъекта
Следовательно надо было догадаться, что executor обязан получить `events.create`, хотя сам код падал не на "events usage", а на создании `Role`.
Это не самый очевидный вывод без жёсткой опоры на лог и знание RBAC semantics.
### Нужен был именно инструментальный debugging loop
Решение появилось не после одной сильной гипотезы, а после цикла:
1. найти симптом
2. проверить конкретное право
3. воспроизвести в новом namespace
4. подтвердить создание реальных объектов
5. перезапустить e2e test
6. перейти к следующему симптому
Без этого модель легко даёт хорошее объяснение, но не доводит задачу до зелёного результата.
## Что Sonnet 4.6 может делать лучше меня
### 1. Быстрый широкий синтез
Sonnet часто хорошо работает на старте, когда нужно быстро:
- разложить проблему по подсистемам
- набросать несколько гипотез
- предложить архитектурные альтернативы
- собрать большой черновик текста
### 2. High-level проектирование и brainstorming
На задачах вида:
- "какую архитектуру выбрать"
- "какие trade-off у подходов"
- "как разложить крупный рефактор"
он может давать очень сильный первый проход.
### 3. Большие гладкие черновики
Для первых версий:
- design-doc
- proposal
- API draft
- architecture summary
Sonnet нередко удобен именно скоростью и связностью первой версии.
## Что оказалось важнее в этом кейсе
В этом расследовании решающим было не качество первого explanation, а жёсткость процесса:
- не верить первому найденному root cause
- валидировать каждый шаг через cluster state
- считать fix завершённым только после `PASS=5/5`
- вносить изменения в код/манифесты, а не лечить кластер временными patch-командами
## Итоговая формулировка
Корректно говорить так:
- Sonnet может быть сильнее в широком синтезе, brainstorming, архитектурных черновиках и быстрых первых гипотезах
- в этом конкретном кейсе я оказался сильнее в последовательной инструментальной диагностике, удержании нескольких меняющихся симптомов и доведении расследования до рабочего e2e результата
То есть различие проявилось не в "умнее/глупее", а в типе задачи.
Executable
BIN
View File
Binary file not shown.
+48 -151
View File
@@ -1,6 +1,6 @@
module github.com/fission/fission
go 1.25.3
go 1.25.5
require (
dario.cat/mergo v1.0.2
@@ -10,7 +10,7 @@ require (
github.com/dustin/go-humanize v1.0.1
github.com/fatih/color v1.18.0
github.com/fsnotify/fsnotify v1.9.0
github.com/go-git/go-git/v5 v5.16.3
github.com/go-git/go-git/v5 v5.16.4
github.com/go-logr/zapr v1.3.0
github.com/golang-jwt/jwt/v4 v4.5.2
github.com/google/go-cmp v0.7.0
@@ -20,85 +20,62 @@ require (
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-retryablehttp v0.7.8
github.com/influxdata/influxdb v1.12.2
github.com/kedacore/keda/v2 v2.18.0
github.com/kedacore/keda/v2 v2.18.2
github.com/mholt/archives v0.1.5
github.com/minio/minio-go/v7 v7.0.95
github.com/minio/minio-go/v7 v7.0.97
github.com/ory/dockertest/v3 v3.12.0
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/common v0.67.2
github.com/prometheus/common v0.67.4
github.com/robfig/cron/v3 v3.0.1
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/spf13/cobra v1.10.1
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/stretchr/testify v1.11.1
github.com/wcharczuk/go-chart v2.0.1+incompatible
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0
go.opentelemetry.io/contrib/propagators/autoprop v0.63.0
go.opentelemetry.io/otel v1.38.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0
go.opentelemetry.io/otel/sdk v1.38.0
go.opentelemetry.io/otel/trace v1.38.0
go.uber.org/zap v1.27.0
golang.org/x/net v0.46.0
google.golang.org/grpc v1.76.0
k8s.io/api v0.34.1
k8s.io/apiextensions-apiserver v0.34.1
k8s.io/apimachinery v0.34.1
k8s.io/client-go v0.34.1
k8s.io/metrics v0.34.1
sigs.k8s.io/controller-runtime v0.22.3
sigs.k8s.io/structured-merge-diff/v6 v6.3.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0
go.opentelemetry.io/contrib/propagators/autoprop v0.64.0
go.opentelemetry.io/otel v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0
go.opentelemetry.io/otel/sdk v1.39.0
go.opentelemetry.io/otel/trace v1.39.0
go.uber.org/zap v1.27.1
golang.org/x/net v0.48.0
google.golang.org/grpc v1.77.0
k8s.io/api v0.34.3
k8s.io/apiextensions-apiserver v0.34.3
k8s.io/apimachinery v0.34.3
k8s.io/client-go v0.34.3
k8s.io/metrics v0.34.3
sigs.k8s.io/controller-runtime v0.22.4
sigs.k8s.io/structured-merge-diff/v6 v6.3.1
sigs.k8s.io/yaml v1.6.0
)
require (
cel.dev/expr v0.24.0 // indirect
cloud.google.com/go v0.121.0 // indirect
cloud.google.com/go/auth v0.16.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/compute/metadata v0.9.0 // indirect
cloud.google.com/go/iam v1.5.0 // indirect
cloud.google.com/go/monitoring v1.24.1 // indirect
cloud.google.com/go/storage v1.52.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/ProtonMail/go-crypto v1.1.6 // indirect
github.com/STARRY-S/zip v0.2.3 // indirect
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
github.com/andybalholm/brotli v1.2.0 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/aws/aws-sdk-go v1.55.7 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blend/go-sdk v1.20220112.5 // indirect
github.com/bodgit/plumbing v1.3.0 // indirect
github.com/bodgit/sevenzip v1.6.1 // indirect
github.com/bodgit/windows v1.0.1 // indirect
github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
github.com/containerd/continuity v0.4.5 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
github.com/cyphar/filepath-securejoin v0.5.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dennwc/varint v1.0.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/docker/cli v27.4.1+incompatible // indirect
github.com/docker/docker v28.1.1+incompatible // indirect
github.com/docker/go-connections v0.5.0 // indirect
@@ -107,71 +84,37 @@ require (
github.com/eapache/go-resiliency v1.7.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/edsrzf/mmap-go v1.2.0 // indirect
github.com/elastic/crd-ref-docs v0.2.0 // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/expr-lang/expr v1.17.6 // indirect
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.2 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gobuffalo/flect v1.0.3 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/goccy/go-yaml v1.18.0 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/gogo/status v1.1.1 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/grafana/dashboard-linter v0.0.0-20241224134444-1765d94aec4a // indirect
github.com/grafana/dskit v0.0.0-20241216174023-0450f2ba7c3d // indirect
github.com/grafana/gomemcache v0.0.0-20241016125027-0a5bcc5aef40 // indirect
github.com/grafana/jsonparser v0.0.0-20241004153430-023329977675 // indirect
github.com/grafana/loki/pkg/push v0.0.0-20241220083700-6c49cc07305e // indirect
github.com/grafana/loki/v3 v3.3.2 // indirect
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
github.com/hashicorp/consul/api v1.32.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.1-vault-7 // indirect
github.com/hashicorp/memberlist v0.5.1 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
@@ -183,27 +126,20 @@ require (
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.18.1 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/klauspost/crc32 v1.3.0 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/magiconair/properties v1.8.9 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mdlayher/socket v0.5.1 // indirect
github.com/mdlayher/vsock v1.2.1 // indirect
github.com/miekg/dns v1.1.65 // indirect
github.com/mikelolasagasti/xz v1.0.1 // indirect
github.com/minio/crc64nvme v1.0.2 // indirect
github.com/minio/crc64nvme v1.1.0 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/minlz v1.0.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/spdystream v0.5.0 // indirect
@@ -212,102 +148,64 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/nwaples/rardecode/v2 v2.2.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/opencontainers/runc v1.2.3 // indirect
github.com/opentracing-contrib/go-grpc v0.1.0 // indirect
github.com/opentracing-contrib/go-stdlib v1.1.0 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/opencontainers/runc v1.2.8 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pires/go-proxyproto v0.8.0 // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/exporter-toolkit v0.14.0 // indirect
github.com/prometheus/procfs v0.17.0 // indirect
github.com/prometheus/prometheus v0.55.1 // indirect
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect
github.com/rs/xid v1.6.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.6.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
github.com/sercand/kuberesolver/v5 v5.1.1 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sergi/go-diff v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/sony/gobreaker v1.0.0 // indirect
github.com/sorairolake/lzip-go v0.3.8 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/viper v1.19.0 // indirect
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tinylib/msgp v1.3.0 // indirect
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
github.com/ulikunitz/xz v0.5.15 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/zeebo/errs v1.4.0 // indirect
github.com/zeitlinger/conflate v0.0.0-20240927101413-c06be92f798f // indirect
go.etcd.io/etcd/api/v3 v3.6.4 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect
go.etcd.io/etcd/client/v3 v3.6.4 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/collector/pdata v1.22.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.36.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
go.opentelemetry.io/contrib/propagators/aws v1.38.0 // indirect
go.opentelemetry.io/contrib/propagators/b3 v1.38.0 // indirect
go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 // indirect
go.opentelemetry.io/contrib/propagators/ot v1.38.0 // indirect
go.opentelemetry.io/otel/metric v1.38.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/propagators/aws v1.39.0 // indirect
go.opentelemetry.io/contrib/propagators/b3 v1.39.0 // indirect
go.opentelemetry.io/contrib/propagators/jaeger v1.39.0 // indirect
go.opentelemetry.io/contrib/propagators/ot v1.39.0 // indirect
go.opentelemetry.io/otel/metric v1.39.0 // indirect
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/crypto v0.43.0 // indirect
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/image v0.18.0 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/oauth2 v0.32.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/term v0.36.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/time v0.13.0 // indirect
golang.org/x/tools v0.38.0 // indirect
golang.org/x/mod v0.30.0 // indirect
golang.org/x/oauth2 v0.33.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/term v0.38.0 // indirect
golang.org/x/text v0.32.0 // indirect
golang.org/x/time v0.14.0 // indirect
golang.org/x/tools v0.39.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
google.golang.org/api v0.230.0 // indirect
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/code-generator v0.34.1 // indirect
k8s.io/code-generator v0.34.3 // indirect
k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
@@ -321,7 +219,6 @@ require (
tool (
github.com/elastic/crd-ref-docs
github.com/grafana/dashboard-linter
k8s.io/code-generator
sigs.k8s.io/controller-runtime/tools/setup-envtest
sigs.k8s.io/controller-tools/cmd/controller-gen
+100 -463
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -1,5 +1,7 @@
if ! command -v dashboard-linter >/dev/null 2>&1; then
echo "dashboard-linter is not installed"
echo "Installing dashboard-linter..."
go install github.com/grafana/dashboard-linter@latest
exit 1;
fi
BASE_PATH=$(pwd)
@@ -12,5 +14,5 @@ DASHBOARD_PATH="$BASE_PATH/charts/fission-all/dashboards/*"
for f in $DASHBOARD_PATH
do
go tool dashboard-linter lint --strict --verbose $f
dashboard-linter lint --strict --verbose $f
done
+132
View File
@@ -0,0 +1,132 @@
import re
# ── envwatcher.go ─────────────────────────────────────────────────────────────
with open("/home/naeel/terra/fission-src/pkg/buildermgr/envwatcher.go") as f:
src = f.read()
# добавляем genInformer import если нет
if "genInformer" not in src:
src = src.replace(
'"github.com/fission/fission/pkg/generated/clientset/versioned"',
'"github.com/fission/fission/pkg/generated/clientset/versioned"\n\t'
'genInformer "github.com/fission/fission/pkg/generated/informers/externalversions"',
1
)
# добавляем fmt если нет
if '"fmt"' not in src:
src = src.replace('"context"', '"context"\n\t"fmt"', 1)
addon = r'''
// AddNamespace dynamically registers a new namespace in environmentWatcher.
// Creates a per-NS Environment informer. Safe to call repeatedly — deduplicates via nsResolver.
func (envw *environmentWatcher) AddNamespace(ctx context.Context, ns string, mgr manager.Interface) {
if !envw.nsResolver.AddNamespace(ns) {
return // already registered
}
envw.logger.Info("buildermgr.envWatcher.AddNamespace: setting up informer", zap.String("namespace", ns))
factory := genInformer.NewFilteredSharedInformerFactory(envw.fissionClient, 30*time.Minute, ns, nil)
envInf := factory.Core().V1().Environments().Informer()
_, err := envInf.AddEventHandler(k8sCache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
envObj := obj.(*fv1.Environment)
envw.AddUpdateBuilder(ctx, envObj)
},
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
oldEnvObj := oldObj.(*fv1.Environment)
newEnvObj := newObj.(*fv1.Environment)
if oldEnvObj.ResourceVersion == newEnvObj.ResourceVersion {
return
}
envw.AddUpdateBuilder(ctx, newEnvObj)
},
DeleteFunc: func(obj interface{}) {
envObj, ok := obj.(*fv1.Environment)
if !ok {
return
}
envw.deleteBuilder(ctx, envObj)
},
})
if err != nil {
envw.logger.Error("buildermgr.envWatcher.AddNamespace: add handler failed",
zap.String("namespace", ns), zap.Error(fmt.Errorf("%w", err)))
return
}
envw.envWatchInformer[ns] = envInf
mgr.AddInformers(ctx, map[string]k8sCache.SharedIndexInformer{ns: envInf})
envw.logger.Info("buildermgr.envWatcher.AddNamespace: done", zap.String("namespace", ns))
}
'''
with open("/home/naeel/terra/fission-src/pkg/buildermgr/envwatcher.go", "w") as f:
f.write(src + addon)
print("envwatcher.go: done")
# ── pkgwatcher.go ─────────────────────────────────────────────────────────────
with open("/home/naeel/terra/fission-src/pkg/buildermgr/pkgwatcher.go") as f:
src = f.read()
# добавляем genInformer import если нет
if "genInformer" not in src:
src = src.replace(
'"github.com/fission/fission/pkg/generated/clientset/versioned"',
'"github.com/fission/fission/pkg/generated/clientset/versioned"\n\t'
'genInformer "github.com/fission/fission/pkg/generated/informers/externalversions"',
1
)
# добавляем fmt если нет
if '"fmt"' not in src:
src = src.replace('"context"', '"context"\n\t"fmt"', 1)
# Добавляем k8sInformers если нет
if "k8sInformers" not in src:
src = src.replace(
'"k8s.io/client-go/kubernetes"',
'"k8s.io/client-go/kubernetes"\n\tk8sInformers "k8s.io/client-go/informers"',
1
)
addon2 = r'''
// AddNamespace dynamically registers a new namespace in packageWatcher.
// Creates per-NS Package and Pod informers. Safe to call repeatedly.
func (pkgw *packageWatcher) AddNamespace(ctx context.Context, ns string, mgr manager.Interface) {
if !pkgw.nsResolver.AddNamespace(ns) {
return // already registered
}
pkgw.logger.Info("buildermgr.pkgWatcher.AddNamespace: setting up informers", zap.String("namespace", ns))
// Package informer
fissionFactory := genInformer.NewFilteredSharedInformerFactory(pkgw.fissionClient, 30*time.Minute, ns, nil)
pkgInf := fissionFactory.Core().V1().Packages().Informer()
_, err := pkgInf.AddEventHandler(pkgw.packageInformerHandler(ctx))
if err != nil {
pkgw.logger.Error("buildermgr.pkgWatcher.AddNamespace: pkg handler failed",
zap.String("namespace", ns), zap.Error(fmt.Errorf("%w", err)))
return
}
// Pod informer for build logs
podFactory := k8sInformers.NewSharedInformerFactoryWithOptions(pkgw.k8sClient, 30*time.Minute,
k8sInformers.WithNamespace(ns))
podInf := podFactory.Core().V1().Pods().Informer()
pkgw.pkgInformer[ns] = pkgInf
pkgw.podInformer[ns] = podInf
mgr.AddInformers(ctx, map[string]k8sCache.SharedIndexInformer{
ns + "/pkg": pkgInf,
ns + "/pod": podInf,
})
pkgw.logger.Info("buildermgr.pkgWatcher.AddNamespace: done", zap.String("namespace", ns))
}
'''
with open("/home/naeel/terra/fission-src/pkg/buildermgr/pkgwatcher.go", "w") as f:
f.write(src + addon2)
print("pkgwatcher.go: done")
+4
View File
@@ -74,5 +74,9 @@ func Start(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *
if err != nil {
return err
}
// Multi-tenant: watch namespaces labeled fission.io/managed=true
StartNSWatcher(ctx, logger, kubernetesClient, envWatcher, pkgWatcher, mgr)
return nil
}
+45
View File
@@ -39,6 +39,7 @@ import (
"github.com/fission/fission/pkg/executor/util"
fetcherConfig "github.com/fission/fission/pkg/fetcher/config"
"github.com/fission/fission/pkg/generated/clientset/versioned"
genInformer "github.com/fission/fission/pkg/generated/informers/externalversions"
"github.com/fission/fission/pkg/utils"
"github.com/fission/fission/pkg/utils/manager"
)
@@ -498,3 +499,47 @@ func (envw *environmentWatcher) createBuilderDeployment(ctx context.Context, env
return deployment, nil
}
// AddNamespace dynamically registers a new namespace in environmentWatcher.
// Creates a per-NS Environment informer. Safe to call repeatedly — deduplicates via env informer map.
func (envw *environmentWatcher) AddNamespace(ctx context.Context, ns string, mgr manager.Interface) {
if _, exists := envw.envWatchInformer[ns]; exists {
return // already registered
}
envw.logger.Info("buildermgr.envWatcher.AddNamespace: setting up informer", zap.String("namespace", ns))
factory := genInformer.NewFilteredSharedInformerFactory(envw.fissionClient, 30*time.Minute, ns, nil)
envInf := factory.Core().V1().Environments().Informer()
_, err := envInf.AddEventHandler(k8sCache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
envObj := obj.(*fv1.Environment)
envw.AddUpdateBuilder(ctx, envObj)
},
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
oldEnvObj := oldObj.(*fv1.Environment)
newEnvObj := newObj.(*fv1.Environment)
if oldEnvObj.ResourceVersion == newEnvObj.ResourceVersion {
return
}
envw.AddUpdateBuilder(ctx, newEnvObj)
},
DeleteFunc: func(obj interface{}) {
envObj, ok := obj.(*fv1.Environment)
if !ok {
return
}
envw.DeleteBuilder(ctx, envObj)
},
})
if err != nil {
envw.logger.Error("buildermgr.envWatcher.AddNamespace: add handler failed",
zap.String("namespace", ns), zap.Error(fmt.Errorf("%w", err)))
return
}
envw.envWatchInformer[ns] = envInf
mgr.AddInformers(ctx, map[string]k8sCache.SharedIndexInformer{ns: envInf})
factory.Start(ctx.Done())
envw.logger.Info("buildermgr.envWatcher.AddNamespace: done", zap.String("namespace", ns))
}
+43
View File
@@ -0,0 +1,43 @@
package buildermgr
import (
"context"
"github.com/fission/fission/pkg/utils"
"github.com/fission/fission/pkg/utils/manager"
)
type builderEnvNamespaceAdder interface {
AddNamespace(ctx context.Context, ns string, mgr manager.Interface)
}
type builderPkgNamespaceAdder interface {
AddNamespace(ctx context.Context, ns string, mgr manager.Interface)
}
func NewNamespaceSubscriber(envw builderEnvNamespaceAdder, pkgw builderPkgNamespaceAdder, mgr manager.Interface) utils.NamespaceSubscriber {
return utils.NamespaceSubscriberFuncs{
SubscriberName: "buildermgr",
AddFunc: func(ctx context.Context, record utils.NamespaceRecord) error {
registerBuilderNamespace(ctx, record.Name, envw, pkgw, mgr)
return nil
},
ResyncFunc: func(ctx context.Context, record utils.NamespaceRecord) error {
registerBuilderNamespace(ctx, record.Name, envw, pkgw, mgr)
return nil
},
}
}
func registerBuilderNamespace(ctx context.Context, namespace string, envw builderEnvNamespaceAdder, pkgw builderPkgNamespaceAdder, mgr manager.Interface) {
if namespace == "" {
return
}
utils.DefaultNSResolver().AddNamespace(namespace)
if envw != nil {
envw.AddNamespace(ctx, namespace, mgr)
}
if pkgw != nil {
pkgw.AddNamespace(ctx, namespace, mgr)
}
}
@@ -0,0 +1,52 @@
package buildermgr
import (
"context"
"testing"
"github.com/fission/fission/pkg/utils"
"github.com/fission/fission/pkg/utils/manager"
)
type fakeBuilderEnvNamespaceAdder struct {
lastNamespace string
calls int
}
func (f *fakeBuilderEnvNamespaceAdder) AddNamespace(ctx context.Context, ns string, mgr manager.Interface) {
f.lastNamespace = ns
f.calls++
}
type fakeBuilderPkgNamespaceAdder struct {
lastNamespace string
calls int
}
func (f *fakeBuilderPkgNamespaceAdder) AddNamespace(ctx context.Context, ns string, mgr manager.Interface) {
f.lastNamespace = ns
f.calls++
}
func TestNewNamespaceSubscriberAddAndResync(t *testing.T) {
envw := &fakeBuilderEnvNamespaceAdder{}
pkgw := &fakeBuilderPkgNamespaceAdder{}
subscriber := NewNamespaceSubscriber(envw, pkgw, nil)
record := utils.NamespaceRecord{Name: "tenant-builder-a"}
if subscriber.Name() != "buildermgr" {
t.Fatalf("expected buildermgr subscriber name")
}
if err := subscriber.OnNamespaceAdd(context.Background(), record); err != nil {
t.Fatalf("expected add to succeed: %v", err)
}
if err := subscriber.OnNamespaceResync(context.Background(), record); err != nil {
t.Fatalf("expected resync to succeed: %v", err)
}
if envw.calls != 2 || pkgw.calls != 2 {
t.Fatalf("expected both watchers to be called for add and resync")
}
if envw.lastNamespace != "tenant-builder-a" || pkgw.lastNamespace != "tenant-builder-a" {
t.Fatalf("expected namespace to be forwarded to both watchers")
}
}
+32
View File
@@ -0,0 +1,32 @@
// Package buildermgr — NSWatcher for multi-tenant mode.
//
// Listens for Namespaces labeled fission.io/managed=true and calls
// AddNamespace on envWatcher and packageWatcher so they pick up
// Environments and Packages in new tenant namespaces without a restart.
package buildermgr
import (
"context"
"go.uber.org/zap"
"k8s.io/client-go/kubernetes"
"github.com/fission/fission/pkg/utils"
"github.com/fission/fission/pkg/utils/manager"
)
// StartNSWatcher watches for Namespaces labeled fission.io/managed=true
// and immediately registers per-NS informers in envWatcher and pkgWatcher.
func StartNSWatcher(
ctx context.Context,
logger *zap.Logger,
kubeClient kubernetes.Interface,
envw *environmentWatcher,
pkgw *packageWatcher,
mgr manager.Interface,
) {
_, err := utils.RunManagedNamespaceWatcher(ctx, logger, kubeClient, mgr, utils.NewDefaultManagedNamespaceWatcherConfig("buildermgr.NSWatcher", NewNamespaceSubscriber(envw, pkgw, mgr)))
if err != nil {
logger.Error("buildermgr.NSWatcher: BootstrapAndDispatch failed", zap.Error(err))
}
}
+38
View File
@@ -25,6 +25,7 @@ import (
apiv1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sInformers "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
k8sCache "k8s.io/client-go/tools/cache"
@@ -32,6 +33,7 @@ import (
"github.com/fission/fission/pkg/cache"
"github.com/fission/fission/pkg/crd"
"github.com/fission/fission/pkg/generated/clientset/versioned"
genInformer "github.com/fission/fission/pkg/generated/informers/externalversions"
"github.com/fission/fission/pkg/utils"
"github.com/fission/fission/pkg/utils/manager"
"github.com/fission/fission/pkg/utils/metrics"
@@ -329,3 +331,39 @@ func setInitialBuildStatus(ctx context.Context, fissionClient versioned.Interfac
// TODO: use UpdateStatus to update status
return fissionClient.CoreV1().Packages(pkg.Namespace).Update(ctx, pkg, metav1.UpdateOptions{})
}
// AddNamespace dynamically registers a new namespace in packageWatcher.
// Creates per-NS Package and Pod informers. Safe to call repeatedly — deduplicates via local informer maps.
func (pkgw *packageWatcher) AddNamespace(ctx context.Context, ns string, mgr manager.Interface) {
if _, exists := pkgw.pkgInformer[ns]; exists {
return // already registered
}
pkgw.logger.Info("buildermgr.pkgWatcher.AddNamespace: setting up informers", zap.String("namespace", ns))
// Package informer
fissionFactory := genInformer.NewFilteredSharedInformerFactory(pkgw.fissionClient, 30*time.Minute, ns, nil)
pkgInf := fissionFactory.Core().V1().Packages().Informer()
_, err := pkgInf.AddEventHandler(pkgw.packageInformerHandler(ctx))
if err != nil {
pkgw.logger.Error("buildermgr.pkgWatcher.AddNamespace: pkg handler failed",
zap.String("namespace", ns), zap.Error(fmt.Errorf("%w", err)))
return
}
// Pod informer for build logs
podFactory := k8sInformers.NewSharedInformerFactoryWithOptions(pkgw.k8sClient, 30*time.Minute,
k8sInformers.WithNamespace(ns))
podInf := podFactory.Core().V1().Pods().Informer()
pkgw.pkgInformer[ns] = pkgInf
pkgw.podInformer[ns] = podInf
mgr.AddInformers(ctx, map[string]k8sCache.SharedIndexInformer{
ns + "/pkg": pkgInf,
ns + "/pod": podInf,
})
fissionFactory.Start(ctx.Done())
podFactory.Start(ctx.Done())
pkgw.logger.Info("buildermgr.pkgWatcher.AddNamespace: done", zap.String("namespace", ns))
}
+8 -1
View File
@@ -111,7 +111,13 @@ func (c *client) GetServiceForFunction(ctx context.Context, fn *fv1.Function) (s
func (c *client) UnTapService(ctx context.Context, fnMeta metav1.ObjectMeta, executorType fv1.ExecutorType, serviceURL *url.URL) error {
url := c.executorURL + "/v2/unTapService"
tapSvc := TapServiceRequest{
FnMetadata: fnMeta,
FnMetadata: metav1.ObjectMeta{
Name: fnMeta.Name,
Namespace: fnMeta.Namespace,
ResourceVersion: fnMeta.ResourceVersion,
Generation: fnMeta.Generation,
UID: fnMeta.UID,
},
FnExecutorType: executorType,
ServiceURL: strings.TrimPrefix(serviceURL.String(), "http://"),
}
@@ -175,6 +181,7 @@ func (c *client) TapService(fnMeta metav1.ObjectMeta, executorType fv1.ExecutorT
Name: fnMeta.Name,
Namespace: fnMeta.Namespace,
ResourceVersion: fnMeta.ResourceVersion,
Generation: fnMeta.Generation,
UID: fnMeta.UID,
},
FnExecutorType: executorType,
+8 -1
View File
@@ -37,6 +37,7 @@ import (
"github.com/fission/fission/pkg/executor/executortype/newdeploy"
"github.com/fission/fission/pkg/executor/executortype/poolmgr"
"github.com/fission/fission/pkg/executor/fscache"
"github.com/fission/fission/pkg/executor/multitenant"
"github.com/fission/fission/pkg/executor/util"
fetcherConfig "github.com/fission/fission/pkg/fetcher/config"
"github.com/fission/fission/pkg/generated/clientset/versioned"
@@ -293,7 +294,7 @@ func StartExecutor(ctx context.Context, clientGen crd.ClientGeneratorInterface,
logger.Info("Starting executor", zap.String("instanceID", executorInstanceID))
finformerFactory := make(map[string]genInformer.SharedInformerFactory, 0)
for _, ns := range utils.DefaultNSResolver().FissionResourceNS {
for _, ns := range utils.DefaultNSResolver().Snapshot() {
finformerFactory[ns] = genInformer.NewFilteredSharedInformerFactory(fissionClient, time.Minute*30, ns, nil)
}
@@ -399,6 +400,12 @@ func StartExecutor(ctx context.Context, clientGen crd.ClientGeneratorInterface,
utils.CreateMissingPermissionForSA(ctx, kubernetesClient, logger)
// Start multi-tenant Namespace watcher.
// Detects Namespaces labeled fission.io/managed=true and registers them in all
// executor types without a pod restart. Backward-compatible with FISSION_RESOURCE_NAMESPACES.
// See: pkg/executor/multitenant/ns_watcher.go
multitenant.StartNSWatcher(ctx, logger, kubernetesClient, executorTypes, mgr)
mgr.Add(ctx, func(ctx context.Context) {
metrics.ServeMetrics(ctx, "executor", logger, mgr)
})
@@ -292,7 +292,7 @@ func (caaf *Container) RefreshFuncPods(ctx context.Context, logger *zap.Logger,
func (caaf *Container) AdoptExistingResources(ctx context.Context) {
wg := &sync.WaitGroup{}
for _, namepsace := range utils.DefaultNSResolver().FissionResourceNS {
for _, namepsace := range utils.DefaultNSResolver().Snapshot() {
fnList, err := caaf.fissionClient.CoreV1().Functions(namepsace).List(ctx, metav1.ListOptions{})
if err != nil {
caaf.logger.Error("error getting function list", zap.Error(err))
@@ -792,3 +792,50 @@ func getDeploymentObj(kubeobjs []apiv1.ObjectReference) *apiv1.ObjectReference {
func (caaf *Container) DumpDebugInfo(ctx context.Context) error {
return nil
}
// AddNamespace dynamically registers a new namespace in the container executor without a restart.
// Sets up deployment and service listers so the executor can manage container functions in the new NS.
func (caaf *Container) AddNamespace(ctx context.Context, ns string, mgr manager.Interface) error {
if ns == "" {
return nil
}
// Use container-specific dedup: check if deplLister is already set up for this NS.
// Do NOT use DefaultNSResolver().AddNamespace() — that is a global single-call guard
// shared by all executor types and is now called once in multitenant.registerNamespace.
if _, ok := caaf.deplLister[ns]; ok {
return nil // already registered
}
caaf.logger.Info("AddNamespace: setting up informers for new namespace (container)", zap.String("namespace", ns))
finformer := genInformer.NewFilteredSharedInformerFactory(caaf.fissionClient, 30*time.Minute, ns, nil)
executorLabel, err := utils.GetInformerLabelByExecutor(fv1.ExecutorTypeContainer)
if err != nil {
return fmt.Errorf("AddNamespace %s (container): get executor label: %w", ns, err)
}
cnmInformer := k8sInformers.NewSharedInformerFactoryWithOptions(
caaf.kubernetesClient,
30*time.Minute,
k8sInformers.WithTweakListOptions(func(opts *metav1.ListOptions) {
opts.LabelSelector = executorLabel.String()
}),
k8sInformers.WithNamespace(ns),
)
caaf.deplLister[ns] = cnmInformer.Apps().V1().Deployments().Lister()
caaf.deplListerSynced[ns] = cnmInformer.Apps().V1().Deployments().Informer().HasSynced
caaf.svcLister[ns] = cnmInformer.Core().V1().Services().Lister()
caaf.svcListerSynced[ns] = cnmInformer.Core().V1().Services().Informer().HasSynced
_, err = finformer.Core().V1().Functions().Informer().AddEventHandler(caaf.FuncInformerHandler(ctx))
if err != nil {
return fmt.Errorf("AddNamespace %s (container): add function handler: %w", ns, err)
}
finformer.Start(ctx.Done())
cnmInformer.Start(ctx.Done())
caaf.logger.Info("AddNamespace: done (container)", zap.String("namespace", ns))
return nil
}

Some files were not shown because too many files have changed in this diff Show More