Compare commits
138
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dc0c5637f | ||
|
|
0cae275dbd | ||
|
|
775845b55c | ||
|
|
c9036f716f | ||
|
|
4349d0b239 | ||
|
|
63ce6ea135 | ||
|
|
7b6ff84188 | ||
|
|
55d0b5a9e7 | ||
|
|
813617ffd1 | ||
|
|
7d7fe561a8 | ||
|
|
fed69da335 | ||
|
|
9f0e911b9d | ||
|
|
f4a3bffc6b | ||
|
|
90924cdec7 | ||
|
|
6e037a506d | ||
|
|
d24605a8b8 | ||
|
|
d2ff55f9e0 | ||
|
|
b9236698f3 | ||
|
|
073f2c1504 | ||
|
|
b93e720e12 | ||
|
|
f16aa030db | ||
|
|
5c481b7293 | ||
|
|
67db8d71f1 | ||
|
|
2bbed95c2a | ||
|
|
a1517ba4b2 | ||
|
|
49be1db3a0 | ||
|
|
c3b161da83 | ||
|
|
0755319fac | ||
|
|
340b9cae84 | ||
|
|
4cd4bc9507 | ||
|
|
0e08664ef6 | ||
|
|
d7497dcd34 | ||
|
|
447133d5b2 | ||
|
|
b6f3640bbe | ||
|
|
d09bee3431 | ||
|
|
488157963a | ||
|
|
804bc533db | ||
|
|
65837610a1 | ||
|
|
dd7470922c | ||
|
|
0135a93a30 | ||
|
|
b12a8e5e75 | ||
|
|
ad0f83fd4b | ||
|
|
6f77fa5a9a | ||
|
|
331f531962 | ||
|
|
346399d35f | ||
|
|
33a08f00b3 | ||
|
|
2971029c42 | ||
|
|
3159fba65b | ||
|
|
b200b8bb5b | ||
|
|
126f7cc51c | ||
|
|
bcf34d6b1a | ||
|
|
022960ade7 | ||
|
|
b1e2e6462d | ||
|
|
ae8275d0a7 | ||
|
|
2857398e11 | ||
|
|
834c0de941 | ||
|
|
db4499d8c7 | ||
|
|
b3f99b2b6c | ||
|
|
5e5058ba0e | ||
|
|
42acce308f | ||
|
|
66a3dc2a3c | ||
|
|
910f65b6d4 | ||
|
|
114d5b99af | ||
|
|
ac2638f17d | ||
|
|
97b13a13c2 | ||
|
|
1f53bc1fb7 | ||
|
|
87477d4529 | ||
|
|
94f26b69ee | ||
|
|
56a499a59f | ||
|
|
6102b277c8 | ||
|
|
9ce9829f3b | ||
|
|
c987fa07e8 | ||
|
|
27a280bc03 | ||
|
|
e2dff8db09 | ||
|
|
7faaa9dc1f | ||
|
|
f617913ad9 | ||
|
|
8ccc9fb342 | ||
|
|
161de70576 | ||
|
|
82e1ff76a5 | ||
|
|
e7cfb06afa | ||
|
|
d9d9d226d3 | ||
|
|
bcd1872ffa | ||
|
|
0bd3a5957b | ||
|
|
a450dfebc7 | ||
|
|
5f90095470 | ||
|
|
eb865e137f | ||
|
|
b7819fda76 | ||
|
|
0e2883d0c6 | ||
|
|
a8322b5ed2 | ||
|
|
43dc34ee8f | ||
|
|
0300051e7c | ||
|
|
b8cb98510f | ||
|
|
20e0f6af45 | ||
|
|
50b061527e | ||
|
|
22b30cf92f | ||
|
|
e0c7a80fe0 | ||
|
|
87cfb2fb20 | ||
|
|
ebdce4c0ed | ||
|
|
4ebdb077b5 | ||
|
|
2eb14db055 | ||
|
|
776dec14b7 | ||
|
|
320b1dd5a9 | ||
|
|
a6ecd0496f | ||
|
|
7f3a003200 | ||
|
|
8b1f0ba0b9 | ||
|
|
84631f03c5 | ||
|
|
e506ba2326 | ||
|
|
c5171cf014 | ||
|
|
757b84f952 | ||
|
|
0e89f8af41 | ||
|
|
7403598df9 | ||
|
|
322d3a21b0 | ||
|
|
aa9a2142b8 | ||
|
|
ed64644d10 | ||
|
|
45d6132ffd | ||
|
|
b26e28e733 | ||
|
|
2b13af0a5e | ||
|
|
6cc6498844 | ||
|
|
313ceef1ed | ||
|
|
9e275e7ced | ||
|
|
3ee30cf4f1 | ||
|
|
0ea24b399d | ||
|
|
aea8e0a470 | ||
|
|
ba13d1fd79 | ||
|
|
8ec6f313a4 | ||
|
|
0b4b78ff21 | ||
|
|
52f0b47273 | ||
|
|
df4a121d77 | ||
|
|
f839142530 | ||
|
|
b58525263e | ||
|
|
46c99e382f | ||
|
|
268fee7f94 | ||
|
|
caffed92f4 | ||
|
|
2fd44174ce | ||
|
|
7119380716 | ||
|
|
5eed09a8fc | ||
|
|
3e253c2ee4 | ||
|
|
8d70da4d8e |
@@ -20,6 +20,8 @@ updates:
|
|||||||
schedule:
|
schedule:
|
||||||
interval: weekly
|
interval: weekly
|
||||||
open-pull-requests-limit: 5
|
open-pull-requests-limit: 5
|
||||||
|
exclude-paths:
|
||||||
|
- "test/**"
|
||||||
groups:
|
groups:
|
||||||
docker-images:
|
docker-images:
|
||||||
patterns:
|
patterns:
|
||||||
@@ -30,7 +32,31 @@ updates:
|
|||||||
schedule:
|
schedule:
|
||||||
interval: weekly
|
interval: weekly
|
||||||
open-pull-requests-limit: 5
|
open-pull-requests-limit: 5
|
||||||
|
exclude-paths:
|
||||||
|
- "test/**"
|
||||||
groups:
|
groups:
|
||||||
go-dependencies:
|
go-dependencies:
|
||||||
patterns:
|
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:
|
||||||
|
- "*"
|
||||||
@@ -14,6 +14,10 @@ on:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: fission-codeql-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
CodeQL-Build:
|
CodeQL-Build:
|
||||||
permissions:
|
permissions:
|
||||||
@@ -24,23 +28,23 @@ jobs:
|
|||||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-ci') }}
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-ci') }}
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
|
||||||
- name: setup go
|
- name: setup go
|
||||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||||
with:
|
with:
|
||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
|
uses: github/codeql-action/init@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
|
||||||
with:
|
with:
|
||||||
languages: go
|
languages: go
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
|
uses: github/codeql-action/analyze@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
|
||||||
|
|||||||
@@ -12,16 +12,20 @@ on: [pull_request]
|
|||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: fission-dependency-review-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
dependency-review:
|
dependency-review:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: 'Checkout Repository'
|
- name: 'Checkout Repository'
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
- name: 'Dependency Review'
|
- name: 'Dependency Review'
|
||||||
uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4.5.0
|
uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2
|
||||||
|
|||||||
@@ -21,22 +21,17 @@ jobs:
|
|||||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-ci') }}
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-ci') }}
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||||
with:
|
with:
|
||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
|
|
||||||
- name: Install dashboard linter
|
|
||||||
run: |
|
|
||||||
go get github.com/grafana/dashboard-linter
|
|
||||||
go install github.com/grafana/dashboard-linter
|
|
||||||
|
|
||||||
- name: Run dashboard linter
|
- name: Run dashboard linter
|
||||||
run: ./hack/lint-dashboards.sh
|
run: ./hack/lint-dashboards.sh
|
||||||
|
|||||||
@@ -17,12 +17,16 @@ on:
|
|||||||
- go.sum
|
- go.sum
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GOLANGCI_LINT_VERSION: v1.63.4
|
GOLANGCI_LINT_VERSION: v2.6.2
|
||||||
GOLANGCI_LINT_TIMEOUT: 5m
|
GOLANGCI_LINT_TIMEOUT: 5m
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: fission-lint-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
permissions:
|
permissions:
|
||||||
@@ -32,15 +36,15 @@ jobs:
|
|||||||
# if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-ci') }}
|
# if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-ci') }}
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||||
with:
|
with:
|
||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
cache: true
|
cache: true
|
||||||
@@ -51,7 +55,7 @@ jobs:
|
|||||||
go mod download
|
go mod download
|
||||||
|
|
||||||
- name: Run golangci-lint
|
- name: Run golangci-lint
|
||||||
uses: golangci/golangci-lint-action@ec5d18412c0aeab7936cb16880d708ba2a64e1ae # v6.2.0
|
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
|
||||||
with:
|
with:
|
||||||
skip-cache: true
|
skip-cache: true
|
||||||
version: ${{ env.GOLANGCI_LINT_VERSION }}
|
version: ${{ env.GOLANGCI_LINT_VERSION }}
|
||||||
@@ -72,7 +76,7 @@ jobs:
|
|||||||
run: ./hack/runtests.sh
|
run: ./hack/runtests.sh
|
||||||
|
|
||||||
- name: Upload Coverage report to CodeCov
|
- name: Upload Coverage report to CodeCov
|
||||||
uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2
|
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
flags: unittests
|
flags: unittests
|
||||||
|
|||||||
@@ -22,13 +22,18 @@ on:
|
|||||||
- go.sum
|
- go.sum
|
||||||
|
|
||||||
env:
|
env:
|
||||||
HELM_VERSION: v3.16.4
|
HELM_VERSION: v4.0.1
|
||||||
KIND_VERSION: v0.26.0
|
KIND_VERSION: v0.30.0
|
||||||
KIND_CLUSTER_NAME: kind
|
KIND_CLUSTER_NAME: kind
|
||||||
|
SKAFFOLD_VERSION: v2.17.0
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: fission-ci-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# Job to run change detection
|
# Job to run change detection
|
||||||
integration-test:
|
integration-test:
|
||||||
@@ -37,36 +42,36 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
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]
|
os: [ubuntu-24.04]
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
|
||||||
- name: setup go
|
- name: setup go
|
||||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||||
with:
|
with:
|
||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
repository: fission/examples
|
repository: fission/examples
|
||||||
path: examples
|
path: examples
|
||||||
|
|
||||||
- name: Helm installation
|
- name: Helm installation
|
||||||
uses: Azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0
|
uses: Azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
|
||||||
with:
|
with:
|
||||||
version: ${{ env.HELM_VERSION }}
|
version: ${{ env.HELM_VERSION }}
|
||||||
|
|
||||||
- name: Kind Cluster
|
- name: Kind Cluster
|
||||||
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
|
||||||
with:
|
with:
|
||||||
node_image: kindest/node:${{ matrix.kindversion }}
|
node_image: kindest/node:${{ matrix.kindversion }}
|
||||||
version: ${{ env.KIND_VERSION }}
|
version: ${{ env.KIND_VERSION }}
|
||||||
@@ -87,12 +92,12 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Skaffold
|
- name: Install Skaffold
|
||||||
run: |
|
run: |
|
||||||
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/v2.13.2/skaffold-linux-amd64
|
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/${{ env.SKAFFOLD_VERSION }}/skaffold-linux-amd64
|
||||||
sudo install skaffold /usr/local/bin/
|
sudo install skaffold /usr/local/bin/
|
||||||
skaffold version
|
skaffold version
|
||||||
|
|
||||||
- name: Install GoReleaser
|
- name: Install GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0
|
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
|
||||||
with:
|
with:
|
||||||
install-only: true
|
install-only: true
|
||||||
version: "~> v2"
|
version: "~> v2"
|
||||||
@@ -153,7 +158,7 @@ jobs:
|
|||||||
- name: Archive fission dump
|
- name: Archive fission dump
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
if: ${{ failure() || cancelled() }}
|
if: ${{ failure() || cancelled() }}
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: fission-dump-${{ github.run_id }}-${{ matrix.kindversion }}
|
name: fission-dump-${{ github.run_id }}-${{ matrix.kindversion }}
|
||||||
path: fission-dump/*.zip
|
path: fission-dump/*.zip
|
||||||
@@ -162,7 +167,7 @@ jobs:
|
|||||||
- name: Archive prometheus dump
|
- name: Archive prometheus dump
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: prom-dump-${{ github.run_id }}-${{ matrix.kindversion }}
|
name: prom-dump-${{ github.run_id }}-${{ matrix.kindversion }}
|
||||||
path: /tmp/prometheus/*
|
path: /tmp/prometheus/*
|
||||||
@@ -171,7 +176,7 @@ jobs:
|
|||||||
- name: Archive kind logs
|
- name: Archive kind logs
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: kind-logs-${{ github.run_id }}-${{ matrix.kindversion }}
|
name: kind-logs-${{ github.run_id }}-${{ matrix.kindversion }}
|
||||||
path: kind-logs/*
|
path: kind-logs/*
|
||||||
@@ -185,36 +190,36 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
kindversion: ["v1.19.16"]
|
kindversion: ["v1.31.12"]
|
||||||
os: [ubuntu-24.04]
|
os: [ubuntu-24.04]
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
|
||||||
- name: setup go
|
- name: setup go
|
||||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||||
with:
|
with:
|
||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
repository: fission/examples
|
repository: fission/examples
|
||||||
path: examples
|
path: examples
|
||||||
|
|
||||||
- name: Helm installation
|
- name: Helm installation
|
||||||
uses: Azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0
|
uses: Azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
|
||||||
with:
|
with:
|
||||||
version: ${{ env.HELM_VERSION }}
|
version: ${{ env.HELM_VERSION }}
|
||||||
|
|
||||||
- name: Kind Cluster
|
- name: Kind Cluster
|
||||||
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
|
||||||
with:
|
with:
|
||||||
node_image: kindest/node:${{ matrix.kindversion }}
|
node_image: kindest/node:${{ matrix.kindversion }}
|
||||||
version: ${{ env.KIND_VERSION }}
|
version: ${{ env.KIND_VERSION }}
|
||||||
@@ -235,12 +240,12 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Skaffold
|
- name: Install Skaffold
|
||||||
run: |
|
run: |
|
||||||
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/v2.13.2/skaffold-linux-amd64
|
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/${{ env.SKAFFOLD_VERSION }}/skaffold-linux-amd64
|
||||||
sudo install skaffold /usr/local/bin/
|
sudo install skaffold /usr/local/bin/
|
||||||
skaffold version
|
skaffold version
|
||||||
|
|
||||||
- name: Install GoReleaser
|
- name: Install GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0
|
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
|
||||||
with:
|
with:
|
||||||
install-only: true
|
install-only: true
|
||||||
version: "~> v2"
|
version: "~> v2"
|
||||||
@@ -304,7 +309,7 @@ jobs:
|
|||||||
- name: Archive fission dump
|
- name: Archive fission dump
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
if: ${{ failure() || cancelled() }}
|
if: ${{ failure() || cancelled() }}
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: fission-dump-${{ github.run_id }}-${{ matrix.kindversion }}
|
name: fission-dump-${{ github.run_id }}-${{ matrix.kindversion }}
|
||||||
path: fission-dump/*.zip
|
path: fission-dump/*.zip
|
||||||
@@ -313,7 +318,7 @@ jobs:
|
|||||||
- name: Archive prometheus dump
|
- name: Archive prometheus dump
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: prom-dump-${{ github.run_id }}-${{ matrix.kindversion }}
|
name: prom-dump-${{ github.run_id }}-${{ matrix.kindversion }}
|
||||||
path: /tmp/prometheus/*
|
path: /tmp/prometheus/*
|
||||||
@@ -322,7 +327,7 @@ jobs:
|
|||||||
- name: Archive kind logs
|
- name: Archive kind logs
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: kind-logs-${{ github.run_id }}-${{ matrix.kindversion }}
|
name: kind-logs-${{ github.run_id }}-${{ matrix.kindversion }}
|
||||||
path: kind-logs/*
|
path: kind-logs/*
|
||||||
|
|||||||
+48
-121
@@ -6,36 +6,36 @@ on:
|
|||||||
- v2.**
|
- v2.**
|
||||||
|
|
||||||
env:
|
env:
|
||||||
KIND_VERSION: v0.26.0
|
KIND_VERSION: v0.30.0
|
||||||
KIND_NODE_IMAGE_TAG: v1.28.15
|
KIND_NODE_IMAGE_TAG: v1.28.15
|
||||||
KIND_CLUSTER_NAME: kind
|
KIND_CLUSTER_NAME: kind
|
||||||
COSIGN_VERSION: v2.4.1
|
COSIGN_VERSION: v3.0.3
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
create-draft-release:
|
create-draft-release:
|
||||||
name: Create Draft Release with Goreleaser
|
name: Create Draft Release with Goreleaser
|
||||||
outputs:
|
outputs:
|
||||||
hashes: ${{ steps.binary.outputs.hashes }}
|
|
||||||
ghcr_images: ${{ steps.image.outputs.ghcr_images }}
|
ghcr_images: ${{ steps.image.outputs.ghcr_images }}
|
||||||
version: ${{ steps.get_version.outputs.VERSION }}
|
version: ${{ steps.get_version.outputs.VERSION }}
|
||||||
permissions:
|
permissions:
|
||||||
contents: write # for goreleaser/goreleaser-action to create a GitHub release
|
contents: write # for goreleaser/goreleaser-action to create a GitHub release
|
||||||
packages: write # for goreleaser/goreleaser-action to upload artifacts to GitHub Packages
|
packages: write # for goreleaser/goreleaser-action to upload artifacts to GitHub Packages
|
||||||
id-token: write # for cosign to sign the image and binary
|
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
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup go
|
- name: Setup go
|
||||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||||
with:
|
with:
|
||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
cache: true
|
cache: true
|
||||||
@@ -45,13 +45,13 @@ jobs:
|
|||||||
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
|
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Install GoReleaser
|
- name: Install GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0
|
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
|
||||||
with:
|
with:
|
||||||
install-only: true
|
install-only: true
|
||||||
version: "~> v2"
|
version: "~> v2"
|
||||||
|
|
||||||
- name: Kind Cluster
|
- name: Kind Cluster
|
||||||
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
|
||||||
with:
|
with:
|
||||||
node_image: kindest/node:${{ env.KIND_NODE_IMAGE_TAG }}
|
node_image: kindest/node:${{ env.KIND_NODE_IMAGE_TAG }}
|
||||||
version: ${{ env.KIND_VERSION }}
|
version: ${{ env.KIND_VERSION }}
|
||||||
@@ -59,24 +59,27 @@ jobs:
|
|||||||
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.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
|
- name: Login to ghcr.io
|
||||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
|
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Install Cosign
|
- name: Install Cosign
|
||||||
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0
|
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||||
with:
|
with:
|
||||||
cosign-release: ${{ env.COSIGN_VERSION }}
|
cosign-release: ${{ env.COSIGN_VERSION }}
|
||||||
|
|
||||||
- name: Check cosign install!
|
- name: Check cosign install!
|
||||||
run: cosign version
|
run: cosign version
|
||||||
|
|
||||||
- uses: anchore/sbom-action/download-syft@df80a981bc6edbc4e220a492d3cbe9f5547a6e75 #v0.17.9
|
- uses: anchore/sbom-action/download-syft@43a17d6e7add2b5535efe4dcae9952337c479a93 #v0.20.11
|
||||||
|
|
||||||
- name: Generate yaml for manifest, Minikube and Openshift installation
|
- name: Generate yaml for manifest, Minikube and Openshift installation
|
||||||
run: ${GITHUB_WORKSPACE}/hack/build-yaml.sh $VERSION
|
run: ${GITHUB_WORKSPACE}/hack/build-yaml.sh $VERSION
|
||||||
@@ -86,7 +89,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Run GoReleaser
|
- name: Run GoReleaser
|
||||||
id: goreleaser
|
id: goreleaser
|
||||||
uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0
|
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
|
||||||
with:
|
with:
|
||||||
version: "~> v2"
|
version: "~> v2"
|
||||||
args: release
|
args: release
|
||||||
@@ -95,15 +98,12 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
DOCKER_CLI_EXPERIMENTAL: "enabled"
|
DOCKER_CLI_EXPERIMENTAL: "enabled"
|
||||||
|
|
||||||
- name: Generate binary hashes
|
# Attest binary artifacts
|
||||||
id: binary
|
# https://goreleaser.com/customization/attestations/
|
||||||
env:
|
- name: Attest binary artifacts
|
||||||
ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}"
|
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
|
||||||
run: |
|
with:
|
||||||
set -euo pipefail
|
subject-checksums: ./dist/checksums.txt
|
||||||
|
|
||||||
checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path')
|
|
||||||
echo "hashes=$(cat $checksum_file | base64 -w0)" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Image digest
|
- name: Image digest
|
||||||
id: image
|
id: image
|
||||||
@@ -111,7 +111,7 @@ jobs:
|
|||||||
ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}"
|
ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}"
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
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 '
|
ghcr_images=$(echo "${image_and_digest}" | grep ghcr.io | jq -R -s -c '
|
||||||
split("\n")
|
split("\n")
|
||||||
| map(select(. != ""))
|
| map(select(. != ""))
|
||||||
@@ -124,40 +124,8 @@ jobs:
|
|||||||
)')
|
)')
|
||||||
echo "ghcr_images=$ghcr_images" >> "$GITHUB_OUTPUT"
|
echo "ghcr_images=$ghcr_images" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
binary-provenance:
|
image-sbom-provenance-ghcr:
|
||||||
name: Create Binary Provenance
|
name: Create SBOM & Provenance for container images
|
||||||
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.0.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.0.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
|
|
||||||
# Goreleaser does not support generating SBOM for container images.
|
# Goreleaser does not support generating SBOM for container images.
|
||||||
needs: [create-draft-release]
|
needs: [create-draft-release]
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
@@ -168,82 +136,41 @@ jobs:
|
|||||||
actions: write
|
actions: write
|
||||||
id-token: write
|
id-token: write
|
||||||
packages: write
|
packages: write
|
||||||
|
attestations: write
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
|
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Run Trivy in fs mode to generate SBOM
|
- name: Run Trivy in fs mode to generate SBOM
|
||||||
uses: aquasecurity/trivy-action@18f2510ee396bbf400402947b394f2dd8c87dbb0 # v0.29.0
|
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # v0.33.1
|
||||||
with:
|
with:
|
||||||
scan-type: "fs"
|
scan-type: "fs"
|
||||||
format: "spdx-json"
|
format: "spdx-json"
|
||||||
output: "spdx.sbom.json"
|
output: "sbom.spdx.json"
|
||||||
- name: Install Cosign
|
- name: Attest SBOM for image
|
||||||
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0
|
uses: actions/attest-sbom@4651f806c01d8637787e274ac3bdf724ef169f34 # v3.0.0
|
||||||
with:
|
with:
|
||||||
cosign-release: ${{ env.COSIGN_VERSION }}
|
sbom-path: sbom.spdx.json
|
||||||
- name: Sign image and sbom
|
subject-name: ${{ fromJson(toJson(matrix)).image }}
|
||||||
env:
|
subject-digest: ${{ fromJson(toJson(matrix)).checksum }}
|
||||||
IMAGE: ${{ fromJson(toJson(matrix)).image }}
|
push-to-registry: true
|
||||||
DIGEST: ${{ fromJson(toJson(matrix)).checksum }}
|
- name: Attest provenance for image
|
||||||
run: |
|
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
|
||||||
#!/usr/bin/env bash
|
with:
|
||||||
set -euo pipefail
|
subject-name: ${{ fromJson(toJson(matrix)).image }}
|
||||||
cosign attach sbom --sbom spdx.sbom.json $IMAGE@$DIGEST
|
subject-digest: ${{ fromJson(toJson(matrix)).checksum }}
|
||||||
cosign sign -a git_sha=$GITHUB_SHA --attachment sbom $IMAGE@$DIGEST --yes
|
push-to-registry: true
|
||||||
|
|
||||||
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@3714a2a4684014deb874a0e737dffa0ee02dd647 # v2.6.0
|
|
||||||
|
|
||||||
- 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"
|
|
||||||
|
|
||||||
image-provenance-verification-with-cosign:
|
image-provenance-verification-with-cosign:
|
||||||
name: Verify Image Provenance
|
name: Verify Image Provenance
|
||||||
needs: [create-draft-release, image-provenance-ghcr]
|
needs: [create-draft-release, image-sbom-provenance-ghcr]
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include: ${{ fromJson(needs.create-draft-release.outputs.ghcr_images) }}
|
include: ${{ fromJson(needs.create-draft-release.outputs.ghcr_images) }}
|
||||||
@@ -251,14 +178,14 @@ jobs:
|
|||||||
permissions: read-all
|
permissions: read-all
|
||||||
steps:
|
steps:
|
||||||
- name: Login
|
- name: Login
|
||||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
|
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Install Cosign
|
- name: Install Cosign
|
||||||
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0
|
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||||
with:
|
with:
|
||||||
cosign-release: ${{ env.COSIGN_VERSION }}
|
cosign-release: ${{ env.COSIGN_VERSION }}
|
||||||
|
|
||||||
@@ -269,7 +196,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "Verifying $IMAGE@$DIGEST"
|
echo "Verifying $IMAGE@$DIGEST"
|
||||||
cosign verify-attestation \
|
cosign verify-attestation \
|
||||||
--type slsaprovenance \
|
--type https://slsa.dev/provenance/v1 \
|
||||||
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
|
--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]+$' \
|
--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
|
$IMAGE@$DIGEST
|
||||||
|
|||||||
@@ -32,17 +32,17 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: "Run analysis"
|
- name: "Run analysis"
|
||||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
|
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
|
||||||
with:
|
with:
|
||||||
results_file: results.sarif
|
results_file: results.sarif
|
||||||
results_format: sarif
|
results_format: sarif
|
||||||
@@ -64,7 +64,7 @@ jobs:
|
|||||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||||
# format to the repository Actions tab.
|
# format to the repository Actions tab.
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v3.pre.node20
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v3.pre.node20
|
||||||
with:
|
with:
|
||||||
name: SARIF file
|
name: SARIF file
|
||||||
path: results.sarif
|
path: results.sarif
|
||||||
@@ -73,6 +73,6 @@ jobs:
|
|||||||
# Upload the results to GitHub's code scanning dashboard (optional).
|
# Upload the results to GitHub's code scanning dashboard (optional).
|
||||||
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
|
uses: github/codeql-action/upload-sarif@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|||||||
@@ -22,13 +22,17 @@ on:
|
|||||||
- go.sum
|
- go.sum
|
||||||
|
|
||||||
env:
|
env:
|
||||||
HELM_VERSION: v3.16.4
|
HELM_VERSION: v3.19.0
|
||||||
KIND_VERSION: v0.26.0
|
KIND_VERSION: v0.30.0
|
||||||
KIND_CLUSTER_NAME: kind
|
KIND_CLUSTER_NAME: kind
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: fission-upgrade-test-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
upgrade-test:
|
upgrade-test:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
@@ -36,37 +40,37 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
kindversion: ["v1.28.15"]
|
kindversion: ["v1.31.12"]
|
||||||
os: [ubuntu-24.04]
|
os: [ubuntu-24.04]
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Checkout action sources
|
- name: Checkout action sources
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
|
||||||
- name: Setup go
|
- name: Setup go
|
||||||
uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
|
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
|
||||||
with:
|
with:
|
||||||
go-version-file: "go.mod"
|
go-version-file: "go.mod"
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
- name: Setup Helm
|
- name: Setup Helm
|
||||||
uses: Azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0
|
uses: Azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
|
||||||
with:
|
with:
|
||||||
version: ${{ env.HELM_VERSION }}
|
version: ${{ env.HELM_VERSION }}
|
||||||
|
|
||||||
- name: Setup Kind Cluster
|
- name: Setup Kind Cluster
|
||||||
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
|
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
|
||||||
with:
|
with:
|
||||||
node_image: kindest/node:${{ matrix.kindversion }}
|
node_image: kindest/node:${{ matrix.kindversion }}
|
||||||
version: ${{ env.KIND_VERSION }}
|
version: ${{ env.KIND_VERSION }}
|
||||||
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
||||||
|
|
||||||
- name: Install GoReleaser
|
- name: Install GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0
|
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
|
||||||
with:
|
with:
|
||||||
install-only: true
|
install-only: true
|
||||||
version: "~> v2"
|
version: "~> v2"
|
||||||
@@ -114,7 +118,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Archive fission dump
|
- name: Archive fission dump
|
||||||
if: ${{ failure() || cancelled() }}
|
if: ${{ failure() || cancelled() }}
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: fission-dump-${{ github.run_id }}-${{ matrix.kindversion }}
|
name: fission-dump-${{ github.run_id }}-${{ matrix.kindversion }}
|
||||||
path: fission-dump/*.zip
|
path: fission-dump/*.zip
|
||||||
@@ -122,7 +126,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Archive kind logs
|
- name: Archive kind logs
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: kind-logs-${{ github.run_id }}-${{ matrix.kindversion }}
|
name: kind-logs-${{ github.run_id }}-${{ matrix.kindversion }}
|
||||||
path: kind-logs/*
|
path: kind-logs/*
|
||||||
|
|||||||
+43
-27
@@ -1,35 +1,51 @@
|
|||||||
|
version: "2"
|
||||||
linters:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
# Default linter
|
|
||||||
- errcheck
|
- errcheck
|
||||||
- gosimple
|
|
||||||
- govet
|
- govet
|
||||||
- ineffassign
|
- ineffassign
|
||||||
- staticcheck
|
|
||||||
- typecheck
|
|
||||||
- unused
|
|
||||||
# Additional linters
|
|
||||||
- gofmt
|
|
||||||
- goimports
|
|
||||||
- misspell
|
- misspell
|
||||||
- nakedret
|
- nakedret
|
||||||
- unconvert
|
|
||||||
- promlinter
|
- promlinter
|
||||||
# Enable in future
|
- unconvert
|
||||||
# - bodyclose
|
- unused
|
||||||
# - dogsled
|
- staticcheck
|
||||||
# - dupl
|
settings:
|
||||||
# - gosec
|
errcheck:
|
||||||
# - nilerr
|
exclude-functions:
|
||||||
# - prealloc
|
- (*go.uber.org/zap.Logger).Sync
|
||||||
# - revive
|
exclusions:
|
||||||
# - unparam
|
generated: lax
|
||||||
# - wrapcheck
|
presets:
|
||||||
# - gocritic
|
- comments
|
||||||
linters-settings:
|
- common-false-positives
|
||||||
errcheck:
|
- legacy
|
||||||
ignore: go.uber.org/zap:Sync
|
- std-error-handling
|
||||||
goimports:
|
paths:
|
||||||
# put imports beginning with prefix after 3rd-party packages;
|
- third_party$
|
||||||
# it's a comma-separated list of prefixes
|
- builtin$
|
||||||
local: github.com/fission/fission
|
- examples$
|
||||||
|
rules:
|
||||||
|
- linters:
|
||||||
|
- staticcheck
|
||||||
|
text: "QF1008"
|
||||||
|
- linters:
|
||||||
|
- staticcheck
|
||||||
|
text: "QF1001"
|
||||||
|
- linters:
|
||||||
|
- staticcheck
|
||||||
|
text: "QF1003"
|
||||||
|
formatters:
|
||||||
|
enable:
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
settings:
|
||||||
|
goimports:
|
||||||
|
local-prefixes:
|
||||||
|
- github.com/fission/fission
|
||||||
|
exclusions:
|
||||||
|
generated: lax
|
||||||
|
paths:
|
||||||
|
- third_party$
|
||||||
|
- builtin$
|
||||||
|
- examples$
|
||||||
|
|||||||
+84
-220
@@ -70,235 +70,100 @@ builds:
|
|||||||
id: reporter
|
id: reporter
|
||||||
binary: reporter
|
binary: reporter
|
||||||
dir: ./cmd/reporter
|
dir: ./cmd/reporter
|
||||||
dockers:
|
dockers_v2:
|
||||||
- &docker-amd64
|
- id: builder
|
||||||
use: buildx
|
tags:
|
||||||
goos: linux
|
- latest
|
||||||
goarch: amd64
|
- "{{ .Tag }}"
|
||||||
ids:
|
images:
|
||||||
- builder
|
- "{{ .Env.GHCR_REPO }}/builder"
|
||||||
image_templates:
|
labels:
|
||||||
- "{{ .Env.GHCR_REPO }}/builder:latest-amd64"
|
org.opencontainers.image.description: "The builder assists in building the fission function source code for deployment."
|
||||||
- "{{ .Env.GHCR_REPO }}/builder:{{ .Tag }}-amd64"
|
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
|
dockerfile: cmd/builder/Dockerfile
|
||||||
build_flag_templates:
|
- id: fetcher
|
||||||
- "--label=org.opencontainers.image.description=The builder assists in building the fission function source code for deployment."
|
tags:
|
||||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
- latest
|
||||||
- "--platform=linux/amd64"
|
- "{{ .Tag }}"
|
||||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
images:
|
||||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
- "{{ .Env.GHCR_REPO }}/fetcher"
|
||||||
- "--label=org.opencontainers.image.version={{.Tag}}"
|
labels:
|
||||||
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
|
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.vendor=Fission"
|
org.opencontainers.image.source: "{{.GitURL}}"
|
||||||
- "--label=org.opencontainers.image.url=https://fission.io/"
|
org.opencontainers.image.created: "{{.Date}}"
|
||||||
- <<: *docker-amd64
|
org.opencontainers.image.revision: "{{.FullCommit}}"
|
||||||
ids:
|
org.opencontainers.image.version: "{{.Tag}}"
|
||||||
- fetcher
|
org.opencontainers.image.authors: "The Fission Authors https://fission.io/"
|
||||||
image_templates:
|
org.opencontainers.image.vendor: "Fission"
|
||||||
- "{{ .Env.GHCR_REPO }}/fetcher:latest-amd64"
|
org.opencontainers.image.url: "https://fission.io/"
|
||||||
- "{{ .Env.GHCR_REPO }}/fetcher:{{ .Tag }}-amd64"
|
|
||||||
dockerfile: cmd/fetcher/Dockerfile
|
dockerfile: cmd/fetcher/Dockerfile
|
||||||
build_flag_templates:
|
- id: fission-bundle
|
||||||
- "--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."
|
tags:
|
||||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
- latest
|
||||||
- "--platform=linux/amd64"
|
- "{{ .Tag }}"
|
||||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
images:
|
||||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
- "{{ .Env.GHCR_REPO }}/fission-bundle"
|
||||||
- "--label=org.opencontainers.image.version={{.Tag}}"
|
labels:
|
||||||
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
|
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.vendor=Fission"
|
org.opencontainers.image.source: "{{.GitURL}}"
|
||||||
- "--label=org.opencontainers.image.url=https://fission.io/"
|
org.opencontainers.image.created: "{{.Date}}"
|
||||||
- <<: *docker-amd64
|
org.opencontainers.image.revision: "{{.FullCommit}}"
|
||||||
ids:
|
org.opencontainers.image.version: "{{.Tag}}"
|
||||||
- fission-bundle
|
org.opencontainers.image.authors: "The Fission Authors https://fission.io/"
|
||||||
image_templates:
|
org.opencontainers.image.vendor: "Fission"
|
||||||
- "{{ .Env.GHCR_REPO }}/fission-bundle:latest-amd64"
|
org.opencontainers.image.url: "https://fission.io/"
|
||||||
- "{{ .Env.GHCR_REPO }}/fission-bundle:{{ .Tag }}-amd64"
|
|
||||||
dockerfile: cmd/fission-bundle/Dockerfile
|
dockerfile: cmd/fission-bundle/Dockerfile
|
||||||
build_flag_templates:
|
- id: pre-upgrade-checks
|
||||||
- "--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."
|
tags:
|
||||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
- latest
|
||||||
- "--platform=linux/amd64"
|
- "{{ .Tag }}"
|
||||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
images:
|
||||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks"
|
||||||
- "--label=org.opencontainers.image.version={{.Tag}}"
|
labels:
|
||||||
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
|
org.opencontainers.image.description: "Preupgradechecks ensures that Fission is ready for the targeted version upgrade by performing checks beforehand."
|
||||||
- "--label=org.opencontainers.image.vendor=Fission"
|
org.opencontainers.image.source: "{{.GitURL}}"
|
||||||
- "--label=org.opencontainers.image.url=https://fission.io/"
|
org.opencontainers.image.created: "{{.Date}}"
|
||||||
- <<: *docker-amd64
|
org.opencontainers.image.revision: "{{.FullCommit}}"
|
||||||
ids:
|
org.opencontainers.image.version: "{{.Tag}}"
|
||||||
- pre-upgrade-checks
|
org.opencontainers.image.authors: "The Fission Authors https://fission.io/"
|
||||||
image_templates:
|
org.opencontainers.image.vendor: "Fission"
|
||||||
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:latest-amd64"
|
org.opencontainers.image.url: "https://fission.io/"
|
||||||
- "{{ .Env.GHCR_REPO }}/pre-upgrade-checks:{{ .Tag }}-amd64"
|
|
||||||
dockerfile: cmd/preupgradechecks/Dockerfile
|
dockerfile: cmd/preupgradechecks/Dockerfile
|
||||||
build_flag_templates:
|
- id: reporter
|
||||||
- "--label=org.opencontainers.image.description=Preupgradechecks ensures that Fission is ready for the targeted version upgrade by performing checks beforehand."
|
tags:
|
||||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
- latest
|
||||||
- "--platform=linux/amd64"
|
- "{{ .Tag }}"
|
||||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
images:
|
||||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
- "{{ .Env.GHCR_REPO }}/reporter"
|
||||||
- "--label=org.opencontainers.image.version={{.Tag}}"
|
labels:
|
||||||
- "--label=org.opencontainers.image.authors=The Fission Authors https://fission.io/"
|
org.opencontainers.image.description: "The reporter gathers information that assists in improving fission."
|
||||||
- "--label=org.opencontainers.image.vendor=Fission"
|
org.opencontainers.image.source: "{{.GitURL}}"
|
||||||
- "--label=org.opencontainers.image.url=https://fission.io/"
|
org.opencontainers.image.created: "{{.Date}}"
|
||||||
- <<: *docker-amd64
|
org.opencontainers.image.revision: "{{.FullCommit}}"
|
||||||
ids:
|
org.opencontainers.image.version: "{{.Tag}}"
|
||||||
- reporter
|
org.opencontainers.image.authors: "The Fission Authors https://fission.io/"
|
||||||
image_templates:
|
org.opencontainers.image.vendor: "Fission"
|
||||||
- "{{ .Env.GHCR_REPO }}/reporter:latest-amd64"
|
org.opencontainers.image.url: "https://fission.io/"
|
||||||
- "{{ .Env.GHCR_REPO }}/reporter:{{ .Tag }}-amd64"
|
|
||||||
dockerfile: cmd/reporter/Dockerfile
|
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:
|
changelog:
|
||||||
disable: true
|
disable: true
|
||||||
archives:
|
archives:
|
||||||
- id: fission
|
- id: fission
|
||||||
builds:
|
ids:
|
||||||
- fission-cli
|
- fission-cli
|
||||||
name_template: "{{ .ProjectName }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}"
|
name_template: "{{ .ProjectName }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}"
|
||||||
format: binary
|
formats:
|
||||||
|
- binary
|
||||||
checksum:
|
checksum:
|
||||||
name_template: "checksums.txt"
|
name_template: "checksums.txt"
|
||||||
algorithm: sha256
|
docker_digest:
|
||||||
|
name_template: "docker-digests.txt"
|
||||||
|
|
||||||
# signs the checksum file
|
# signs the checksum file
|
||||||
# https://goreleaser.com/customization/sign
|
# https://goreleaser.com/customization/sign
|
||||||
@@ -306,13 +171,12 @@ signs:
|
|||||||
- id: cosign-binary
|
- id: cosign-binary
|
||||||
env:
|
env:
|
||||||
- COSIGN_EXPERIMENTAL=1
|
- COSIGN_EXPERIMENTAL=1
|
||||||
certificate: "${artifact}.pem"
|
signature: "${artifact}.sig.bundle"
|
||||||
cmd: cosign
|
cmd: cosign
|
||||||
artifacts: binary
|
artifacts: all
|
||||||
args:
|
args:
|
||||||
- sign-blob
|
- sign-blob
|
||||||
- "--output-signature=${signature}"
|
- "--bundle=${signature}"
|
||||||
- "--output-certificate=${certificate}"
|
|
||||||
- "${artifact}"
|
- "${artifact}"
|
||||||
- "--yes" # needed for cosign 2.0.0+
|
- "--yes" # needed for cosign 2.0.0+
|
||||||
|
|
||||||
|
|||||||
@@ -61,17 +61,17 @@ install-fission-cli:
|
|||||||
### Codegen
|
### Codegen
|
||||||
codegen:
|
codegen:
|
||||||
@./hack/update-codegen.sh
|
@./hack/update-codegen.sh
|
||||||
go run sigs.k8s.io/controller-tools/cmd/controller-gen object:headerFile="hack/boilerplate.txt" paths="./..."
|
go tool controller-gen object:headerFile="hack/boilerplate.txt" paths="./..."
|
||||||
|
|
||||||
### CRDs
|
### CRDs
|
||||||
generate-crds:
|
generate-crds:
|
||||||
go run sigs.k8s.io/controller-tools/cmd/controller-gen crd \
|
go tool controller-gen crd \
|
||||||
paths=./pkg/apis/core/v1 \
|
paths=./pkg/apis/core/v1 \
|
||||||
output:crd:artifacts:config=crds/v1
|
output:crd:artifacts:config=crds/v1
|
||||||
|
|
||||||
### Webhook generation: it generates webhook configs with help of kubebuilder:webhook tag
|
### Webhook generation: it generates webhook configs with help of kubebuilder:webhook tag
|
||||||
generate-webhooks:
|
generate-webhooks:
|
||||||
go run sigs.k8s.io/controller-tools/cmd/controller-gen webhook \
|
go tool controller-gen webhook \
|
||||||
paths=./pkg/webhook \
|
paths=./pkg/webhook \
|
||||||
output:dir=charts/fission-all/templates/webhook-server
|
output:dir=charts/fission-all/templates/webhook-server
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ generate-cli-docs:
|
|||||||
|
|
||||||
generate-crd-ref-docs:
|
generate-crd-ref-docs:
|
||||||
# crd-ref-docs: https://github.com/elastic/crd-ref-docs
|
# crd-ref-docs: https://github.com/elastic/crd-ref-docs
|
||||||
go run github.com/elastic/crd-ref-docs --source-path=pkg/apis/core/v1 --config=tools/crd-ref-docs/config.yaml --renderer markdown
|
go tool crd-ref-docs --source-path=pkg/apis/core/v1 --config=tools/crd-ref-docs/config.yaml --renderer markdown
|
||||||
cp tools/crd-ref-docs/header.md crd_docs.md
|
cp tools/crd-ref-docs/header.md crd_docs.md
|
||||||
cat out.md >> crd_docs.md && rm out.md
|
cat out.md >> crd_docs.md && rm out.md
|
||||||
mv crd_docs.md ../fission.io/content/en/docs/reference/crd-reference.md
|
mv crd_docs.md ../fission.io/content/en/docs/reference/crd-reference.md
|
||||||
@@ -112,6 +112,7 @@ skaffold-prebuild:
|
|||||||
@cp -v cmd/fission-bundle/Dockerfile dist/fission-bundle_linux_amd64_v1/Dockerfile
|
@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/reporter/Dockerfile dist/reporter_linux_amd64_v1/Dockerfile
|
||||||
@cp -v cmd/preupgradechecks/Dockerfile dist/pre-upgrade-checks_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-deploy: skaffold-prebuild
|
||||||
skaffold run -p $(SKAFFOLD_PROFILE)
|
skaffold run -p $(SKAFFOLD_PROFILE)
|
||||||
@@ -122,10 +123,3 @@ release:
|
|||||||
@./hack/release.sh $(VERSION)
|
@./hack/release.sh $(VERSION)
|
||||||
@./hack/release-tag.sh $(VERSION)
|
@./hack/release-tag.sh $(VERSION)
|
||||||
@./hack/changelog.sh
|
@./hack/changelog.sh
|
||||||
|
|
||||||
## Envtest
|
|
||||||
install-envtest:
|
|
||||||
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
|
|
||||||
|
|
||||||
setup-envtest:
|
|
||||||
setup-envtest -p path use 1.30.x
|
|
||||||
|
|||||||
@@ -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/."
|
||||||
@@ -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">
|
<p align="center">
|
||||||
<img src="https://fission.io/images/logo-gh.svg" width="300" />
|
<img src="https://fission.io/images/logo-gh.svg" width="300" />
|
||||||
<br>
|
<br>
|
||||||
@@ -39,6 +54,9 @@
|
|||||||
<a href="https://scorecard.dev/viewer/?uri=github.com/fission/fission">
|
<a href="https://scorecard.dev/viewer/?uri=github.com/fission/fission">
|
||||||
<image alt="OpenSSF Scorecard" src="https://api.scorecard.dev/projects/github.com/fission/fission/badge">
|
<image alt="OpenSSF Scorecard" src="https://api.scorecard.dev/projects/github.com/fission/fission/badge">
|
||||||
</a>
|
</a>
|
||||||
|
<a href="https://www.bestpractices.dev/projects/4986">
|
||||||
|
<img src="https://www.bestpractices.dev/projects/4986/badge">
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
|
||||||
|
COPY fission-bundle /
|
||||||
|
ENTRYPOINT ["/fission-bundle"]
|
||||||
Executable
BIN
Binary file not shown.
@@ -1,9 +1,9 @@
|
|||||||
apiVersion: v2
|
apiVersion: v2
|
||||||
name: fission-all
|
name: fission-all
|
||||||
version: v1.21.0
|
version: 1.22.0
|
||||||
appVersion: v1.21.0
|
appVersion: v1.22.0
|
||||||
description: Fission is a fast serverless framework for Kubernetes.
|
description: Fission is a fast serverless framework for Kubernetes.
|
||||||
kubeVersion: ">=1.27.0-0"
|
kubeVersion: ">=1.28.0-0"
|
||||||
home: https://fission.io/
|
home: https://fission.io/
|
||||||
icon: https://fission.io/images/fission-logo-white.svg
|
icon: https://fission.io/images/fission-logo-white.svg
|
||||||
sources:
|
sources:
|
||||||
@@ -21,7 +21,6 @@ maintainers:
|
|||||||
email: vishal@infracloud.io
|
email: vishal@infracloud.io
|
||||||
- name: Sanket Sudake
|
- name: Sanket Sudake
|
||||||
email: sanket@infracloud.io
|
email: sanket@infracloud.io
|
||||||
engine: gotpl
|
|
||||||
type: application
|
type: application
|
||||||
annotations:
|
annotations:
|
||||||
artifacthub.io/signKey: |
|
artifacthub.io/signKey: |
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- Kubernetes 1.23+
|
- Kubernetes 1.28+
|
||||||
- Helm 3+
|
- Helm 3+
|
||||||
|
|
||||||
## Get Repo Info
|
## Get Repo Info
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ spec:
|
|||||||
matchLabels:
|
matchLabels:
|
||||||
svc: storagesvc
|
svc: storagesvc
|
||||||
application: fission-storage
|
application: fission-storage
|
||||||
|
strategy:
|
||||||
|
type: {{ .Values.storagesvc.deploymentStrategy.type }}
|
||||||
|
{{- if eq .Values.storagesvc.deploymentStrategy.type "RollingUpdate" }}
|
||||||
|
rollingUpdate:
|
||||||
|
{{- toYaml .Values.storagesvc.deploymentStrategy.rollingUpdate | nindent 6}}
|
||||||
|
{{- end }}
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
@@ -113,7 +119,7 @@ spec:
|
|||||||
priorityClassName: {{ .Values.priorityClassName }}
|
priorityClassName: {{ .Values.priorityClassName }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- with .Values.imagePullSecrets }}
|
{{- with .Values.imagePullSecrets }}
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if .Values.extraCoreComponentPodConfig }}
|
{{- if .Values.extraCoreComponentPodConfig }}
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ image: fission/fission-bundle
|
|||||||
## It is also used by the chart to identify version of the few more images apart from fission-bundle.
|
## It is also used by the chart to identify version of the few more images apart from fission-bundle.
|
||||||
## Keep it empty for using latest tag.
|
## Keep it empty for using latest tag.
|
||||||
##
|
##
|
||||||
imageTag: v1.21.0
|
imageTag: v1.22.0
|
||||||
|
|
||||||
## pullPolicy represents the pull policy to use for images in the chart.
|
## pullPolicy represents the pull policy to use for images in the chart.
|
||||||
##
|
##
|
||||||
pullPolicy: IfNotPresent
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
## imageppullsecrets
|
## imagepullsecrets
|
||||||
imagePullSecrets: []
|
imagePullSecrets: []
|
||||||
|
|
||||||
## priorityClassName represents the priority class name to use for Fission components.
|
## priorityClassName represents the priority class name to use for Fission components.
|
||||||
@@ -80,7 +80,7 @@ builderNamespace: ""
|
|||||||
functionNamespace: ""
|
functionNamespace: ""
|
||||||
|
|
||||||
## Fission will watch the following namespaces along with the `defaultNamespace` for fission custom resources.
|
## Fission will watch the following namespaces along with the `defaultNamespace` for fission custom resources.
|
||||||
## additionalFissionNamespaces:
|
## additionalFissionNamespaces:
|
||||||
## - namespace1
|
## - namespace1
|
||||||
## - namespace2
|
## - namespace2
|
||||||
## - namespace3
|
## - namespace3
|
||||||
@@ -124,7 +124,7 @@ fetcher:
|
|||||||
## image represents the image of the fetcher component.
|
## image represents the image of the fetcher component.
|
||||||
image: fission/fetcher
|
image: fission/fetcher
|
||||||
## imageTag represents the tag of the image of the fetcher component.
|
## imageTag represents the tag of the image of the fetcher component.
|
||||||
imageTag: v1.21.0
|
imageTag: v1.22.0
|
||||||
|
|
||||||
## Fetcher is only for to downloading or uploading archive.
|
## Fetcher is only for to downloading or uploading archive.
|
||||||
## Normally, you don't need to change the value here, unless necessary.
|
## Normally, you don't need to change the value here, unless necessary.
|
||||||
@@ -163,7 +163,7 @@ executor:
|
|||||||
## This is applicable to Pool Manager executor type only.
|
## This is applicable to Pool Manager executor type only.
|
||||||
##
|
##
|
||||||
podReadyTimeout: 300s
|
podReadyTimeout: 300s
|
||||||
|
|
||||||
## Pod resources as:
|
## Pod resources as:
|
||||||
## resources:
|
## resources:
|
||||||
## limits:
|
## limits:
|
||||||
@@ -336,7 +336,7 @@ router:
|
|||||||
runAsGroup: 10001
|
runAsGroup: 10001
|
||||||
|
|
||||||
## The builder manager watches the package & environments CRD changes and manages the builds of function source code.
|
## The builder manager watches the package & environments CRD changes and manages the builds of function source code.
|
||||||
##
|
##
|
||||||
buildermgr:
|
buildermgr:
|
||||||
## Pod resources as:
|
## Pod resources as:
|
||||||
## resources:
|
## resources:
|
||||||
@@ -362,7 +362,7 @@ buildermgr:
|
|||||||
runAsGroup: 10001
|
runAsGroup: 10001
|
||||||
|
|
||||||
## webhook is the component that validates API calls.
|
## webhook is the component that validates API calls.
|
||||||
## It contains validation and mutation for functions, triggers, environments, Kubernetes event watches, etc.
|
## It contains validation and mutation for functions, triggers, environments, Kubernetes event watches, etc.
|
||||||
##
|
##
|
||||||
webhook:
|
webhook:
|
||||||
## Pod resources as:
|
## Pod resources as:
|
||||||
@@ -439,6 +439,16 @@ storagesvc:
|
|||||||
##
|
##
|
||||||
resources: {}
|
resources: {}
|
||||||
|
|
||||||
|
## Deployment strategy defaults to RollingUpdate but use Recreate if new pods fail to
|
||||||
|
## attach to the volume until the old pod has released it.
|
||||||
|
## deploymentStrategy:
|
||||||
|
## type: Recreate
|
||||||
|
deploymentStrategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
rollingUpdate:
|
||||||
|
maxSurge: 25%
|
||||||
|
maxUnavailable: 25%
|
||||||
|
|
||||||
## Archive pruner removes archives from storage which are not referenced by any package.
|
## Archive pruner removes archives from storage which are not referenced by any package.
|
||||||
archivePruner:
|
archivePruner:
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -541,7 +551,7 @@ serviceMonitor:
|
|||||||
# key: "value"
|
# key: "value"
|
||||||
|
|
||||||
# The following components expose Prometheus metrics and have podmonitors in this chart (disabled by default)
|
# The following components expose Prometheus metrics and have podmonitors in this chart (disabled by default)
|
||||||
#
|
#
|
||||||
podMonitor:
|
podMonitor:
|
||||||
enabled: false
|
enabled: false
|
||||||
##namespace in which you want to deploy podmonitor
|
##namespace in which you want to deploy podmonitor
|
||||||
@@ -577,7 +587,7 @@ persistence:
|
|||||||
# region: <awsRegion>
|
# region: <awsRegion>
|
||||||
## For Minio and other s3 compatible storage systems set endPoint property
|
## For Minio and other s3 compatible storage systems set endPoint property
|
||||||
# endPoint: <s3StorageUrl>
|
# endPoint: <s3StorageUrl>
|
||||||
|
|
||||||
## A manually managed Persistent Volume Claim name
|
## A manually managed Persistent Volume Claim name
|
||||||
## Requires persistence.enabled: true
|
## Requires persistence.enabled: true
|
||||||
## If defined, PVC must be created manually before volume will be bound
|
## If defined, PVC must be created manually before volume will be bound
|
||||||
@@ -696,7 +706,7 @@ preUpgradeChecks:
|
|||||||
image: fission/pre-upgrade-checks
|
image: fission/pre-upgrade-checks
|
||||||
## pre-install/pre-upgrade checks image version
|
## pre-install/pre-upgrade checks image version
|
||||||
##
|
##
|
||||||
imageTag: v1.21.0
|
imageTag: v1.22.0
|
||||||
|
|
||||||
## Fission post-install/post-upgrade reporting live in this image
|
## Fission post-install/post-upgrade reporting live in this image
|
||||||
##
|
##
|
||||||
@@ -764,12 +774,12 @@ authentication:
|
|||||||
## jwtSigningKey is the signing key used for
|
## jwtSigningKey is the signing key used for
|
||||||
## signing the JWT token
|
## signing the JWT token
|
||||||
##
|
##
|
||||||
jwtSigningKey:
|
jwtSigningKey:
|
||||||
## jwtExpiryTime is the JWT expiry time
|
## jwtExpiryTime is the JWT expiry time
|
||||||
## in seconds
|
## in seconds
|
||||||
## default '120'
|
## default '120'
|
||||||
##
|
##
|
||||||
jwtExpiryTime:
|
jwtExpiryTime:
|
||||||
## jwtIssuer is the issuer of JWT
|
## jwtIssuer is the issuer of JWT
|
||||||
## default 'fission'
|
## default 'fission'
|
||||||
##
|
##
|
||||||
@@ -874,7 +884,7 @@ runtimePodSpec:
|
|||||||
## Setting it false by default so that integration tests pass
|
## Setting it false by default so that integration tests pass
|
||||||
##
|
##
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
## Checkout PodSpec in https://fission.io/docs/reference/crd-reference/#runtime
|
## Checkout PodSpec in https://fission.io/docs/reference/crd-reference/#runtime
|
||||||
##
|
##
|
||||||
podSpec:
|
podSpec:
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
FROM cgr.dev/chainguard/static:latest@sha256:5497b01f36ef14a5198c0165e50ae6a0006d0c7457d4566f1110257e1c0812ed
|
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
|
||||||
COPY builder /builder
|
ARG TARGETPLATFORM
|
||||||
|
COPY $TARGETPLATFORM/builder /builder
|
||||||
ENTRYPOINT ["/builder"]
|
ENTRYPOINT ["/builder"]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
FROM cgr.dev/chainguard/static:latest@sha256:5497b01f36ef14a5198c0165e50ae6a0006d0c7457d4566f1110257e1c0812ed
|
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
|
||||||
COPY fetcher /
|
ARG TARGETPLATFORM
|
||||||
|
COPY $TARGETPLATFORM/fetcher /
|
||||||
ENTRYPOINT ["/fetcher"]
|
ENTRYPOINT ["/fetcher"]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
FROM cgr.dev/chainguard/static:latest@sha256:5497b01f36ef14a5198c0165e50ae6a0006d0c7457d4566f1110257e1c0812ed
|
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
|
||||||
COPY fission-bundle /
|
ARG TARGETPLATFORM
|
||||||
|
COPY $TARGETPLATFORM/fission-bundle /
|
||||||
ENTRYPOINT ["/fission-bundle"]
|
ENTRYPOINT ["/fission-bundle"]
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
|
||||||
|
COPY fission-bundle /
|
||||||
|
ENTRYPOINT ["/fission-bundle"]
|
||||||
BIN
Binary file not shown.
+181
-175
@@ -21,9 +21,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
docopt "github.com/docopt/docopt-go"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
|
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
|
||||||
cnwebhook "sigs.k8s.io/controller-runtime/pkg/webhook"
|
cnwebhook "sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||||
@@ -48,116 +46,35 @@ import (
|
|||||||
"github.com/fission/fission/pkg/webhook"
|
"github.com/fission/fission/pkg/webhook"
|
||||||
)
|
)
|
||||||
|
|
||||||
// runWebhook starts admission webhook server
|
// Command line arguments
|
||||||
func runWebhook(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, port int) error {
|
type CommandLineArgs struct {
|
||||||
return webhook.Start(ctx, clientGen, logger, cnwebhook.Options{
|
// Flags
|
||||||
Port: port,
|
canaryConfig bool
|
||||||
})
|
kubewatcher bool
|
||||||
|
timer bool
|
||||||
|
mqt bool
|
||||||
|
mqt_keda bool
|
||||||
|
builderMgr bool
|
||||||
|
showVersion bool
|
||||||
|
logger bool
|
||||||
|
|
||||||
|
// Port values
|
||||||
|
webhookPort int
|
||||||
|
routerPort int
|
||||||
|
executorPort int
|
||||||
|
storageServicePort int
|
||||||
|
|
||||||
|
// URL values
|
||||||
|
executorUrl string
|
||||||
|
routerUrl string
|
||||||
|
storageSvcUrl string
|
||||||
|
|
||||||
|
// Other configurations
|
||||||
|
storageType string
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCanaryConfigServer(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface) error {
|
// Usage information
|
||||||
return canaryconfigmgr.StartCanaryServer(ctx, clientGen, logger, mgr, false)
|
const usageText string = `fission-bundle: Package of all fission microservices: router, executor.
|
||||||
}
|
|
||||||
|
|
||||||
func runRouter(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface, port int, executorUrl string) error {
|
|
||||||
return router.Start(ctx, clientGen, logger, mgr, port, eclient.MakeClient(logger, executorUrl))
|
|
||||||
}
|
|
||||||
|
|
||||||
func runExecutor(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface, port int) error {
|
|
||||||
return executor.StartExecutor(ctx, clientGen, logger, mgr, port)
|
|
||||||
}
|
|
||||||
|
|
||||||
func runKubeWatcher(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface, routerUrl string) error {
|
|
||||||
return kubewatcher.Start(ctx, clientGen, logger, mgr, routerUrl)
|
|
||||||
}
|
|
||||||
|
|
||||||
func runTimer(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface, routerUrl string) error {
|
|
||||||
return timer.Start(ctx, clientGen, logger, mgr, routerUrl)
|
|
||||||
}
|
|
||||||
|
|
||||||
func runMessageQueueMgr(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface, routerUrl string) error {
|
|
||||||
return mqtrigger.Start(ctx, clientGen, logger, mgr, routerUrl)
|
|
||||||
}
|
|
||||||
|
|
||||||
// KEDA based MessageQueue Trigger Manager
|
|
||||||
func runMQManager(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface, routerURL string) error {
|
|
||||||
return mqt.StartScalerManager(ctx, clientGen, logger, mgr, routerURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
func runStorageSvc(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface, port int, storage storagesvc.Storage) error {
|
|
||||||
return storagesvc.Start(ctx, clientGen, logger, storage, mgr, port)
|
|
||||||
}
|
|
||||||
|
|
||||||
func runBuilderMgr(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface, storageSvcUrl string) error {
|
|
||||||
return buildermgr.Start(ctx, clientGen, logger, mgr, storageSvcUrl)
|
|
||||||
}
|
|
||||||
|
|
||||||
func runLogger(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger) error {
|
|
||||||
return functionLogger.Start(ctx, clientGen, logger)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPort(logger *zap.Logger, portArg interface{}) int {
|
|
||||||
portArgStr := portArg.(string)
|
|
||||||
port, err := strconv.Atoi(portArgStr)
|
|
||||||
if err != nil {
|
|
||||||
logger.Fatal("invalid port number", zap.Error(err), zap.String("port", portArgStr))
|
|
||||||
}
|
|
||||||
return port
|
|
||||||
}
|
|
||||||
|
|
||||||
func getStringArgWithDefault(arg interface{}, defaultValue string) string {
|
|
||||||
if arg != nil {
|
|
||||||
return arg.(string)
|
|
||||||
} else {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getServiceName(arguments map[string]interface{}) string {
|
|
||||||
serviceName := "Fission-Unknown"
|
|
||||||
|
|
||||||
if arguments["--routerPort"] != nil {
|
|
||||||
serviceName = "Fission-Router"
|
|
||||||
} else if arguments["--executorPort"] != nil {
|
|
||||||
serviceName = "Fission-Executor"
|
|
||||||
} else if arguments["--kubewatcher"] == true {
|
|
||||||
serviceName = "Fission-KubeWatcher"
|
|
||||||
} else if arguments["--timer"] == true {
|
|
||||||
serviceName = "Fission-Timer"
|
|
||||||
} else if arguments["--mqt"] == true {
|
|
||||||
serviceName = "Fission-MessageQueueTrigger"
|
|
||||||
} else if arguments["--builderMgr"] == true {
|
|
||||||
serviceName = "Fission-BuilderMgr"
|
|
||||||
} else if arguments["--storageServicePort"] != nil {
|
|
||||||
serviceName = "Fission-StorageSvc"
|
|
||||||
} else if arguments["--mqt_keda"] == true {
|
|
||||||
serviceName = "Fission-Keda-MQTrigger"
|
|
||||||
}
|
|
||||||
|
|
||||||
return serviceName
|
|
||||||
}
|
|
||||||
|
|
||||||
func exitWithSync(logger *zap.Logger) {
|
|
||||||
// Ignore error, safe to ignore as per https://github.com/uber-go/zap/issues/328
|
|
||||||
_ = logger.Sync()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
mgr := manager.New()
|
|
||||||
defer mgr.Wait()
|
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// From https://github.com/containous/traefik/pull/1817/files
|
|
||||||
// Tell glog to log into STDERR. Otherwise, we risk
|
|
||||||
// certain kinds of API errors getting logged into a directory not
|
|
||||||
// available in a `FROM scratch` Docker container, causing glog to abort
|
|
||||||
// hard with an exit code > 0.
|
|
||||||
// TODO: fix the lint error. Error checking here is causing all components to crash with error "logtostderr not found"
|
|
||||||
flag.Set("logtostderr", "true") //nolint: errcheck
|
|
||||||
|
|
||||||
usage := `fission-bundle: Package of all fission microservices: router, executor.
|
|
||||||
|
|
||||||
Use it to start one or more of the fission servers:
|
Use it to start one or more of the fission servers:
|
||||||
|
|
||||||
@@ -197,142 +114,231 @@ Options:
|
|||||||
--storageServicePort=<port> Port that the storage service should listen on.
|
--storageServicePort=<port> Port that the storage service should listen on.
|
||||||
--executorUrl=<url> Executor URL. Not required if --executorPort is specified.
|
--executorUrl=<url> Executor URL. Not required if --executorPort is specified.
|
||||||
--routerUrl=<url> Router URL.
|
--routerUrl=<url> Router URL.
|
||||||
--etcdUrl=<etcdUrl> Etcd URL.
|
|
||||||
--storageSvcUrl=<url> StorageService URL.
|
--storageSvcUrl=<url> StorageService URL.
|
||||||
--filePath=<filePath> Directory to store functions in.
|
|
||||||
--namespace=<namespace> Kubernetes namespace in which to run function containers. Defaults to 'fission-function'.
|
|
||||||
--kubewatcher Start Kubernetes events watcher.
|
--kubewatcher Start Kubernetes events watcher.
|
||||||
--timer Start Timer.
|
--timer Start Timer.
|
||||||
--mqt Start message queue trigger.
|
--mqt Start message queue trigger.
|
||||||
--mqt_keda Start message queue trigger of kind KEDA
|
--mqt_keda Start message queue trigger of kind KEDA
|
||||||
--builderMgr Start builder manager.
|
--builderMgr Start builder manager.
|
||||||
--version Print version information
|
--version Print version information`
|
||||||
`
|
|
||||||
logger := loggerfactory.GetLogger()
|
|
||||||
defer exitWithSync(logger)
|
|
||||||
|
|
||||||
ctx := signals.SetupSignalHandler()
|
func main() {
|
||||||
profile.ProfileIfEnabled(ctx, logger, mgr)
|
mgr := manager.New()
|
||||||
|
defer mgr.Wait()
|
||||||
|
|
||||||
version := fmt.Sprintf("Fission Bundle Version: %s", info.BuildInfo().String())
|
// Set up command line parsing
|
||||||
arguments, err := docopt.ParseArgs(usage, nil, version)
|
args := setupCommandLineArgs()
|
||||||
if err != nil {
|
|
||||||
logger.Error("failed to parse arguments", zap.Error(err))
|
// Handle version request specially - exit after printing
|
||||||
return
|
if args.showVersion {
|
||||||
|
fmt.Printf("Fission Bundle Version: %s\n", info.BuildInfo().String())
|
||||||
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdown, err := otel.InitProvider(ctx, logger, getServiceName(arguments))
|
// Initialize logger
|
||||||
|
logger := loggerfactory.GetLogger()
|
||||||
|
defer func() {
|
||||||
|
// Ignore error, safe to ignore as per https://github.com/uber-go/zap/issues/328
|
||||||
|
_ = logger.Sync()
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Set up signal handling for graceful shutdown
|
||||||
|
ctx := signals.SetupSignalHandler()
|
||||||
|
|
||||||
|
// Enable profiling if configured
|
||||||
|
profile.ProfileIfEnabled(ctx, logger, mgr)
|
||||||
|
|
||||||
|
// Initialize OpenTelemetry
|
||||||
|
serviceName := getServiceNameFromArgs(args)
|
||||||
|
shutdown, err := otel.InitProvider(ctx, logger, serviceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("error initializing provider for OTLP", zap.Error(err), zap.Any("argument", arguments))
|
logger.Error("error initializing provider for OTLP", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if shutdown != nil {
|
if shutdown != nil {
|
||||||
defer shutdown(ctx)
|
defer shutdown(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
executorUrl := getStringArgWithDefault(arguments["--executorUrl"], "http://executor.fission")
|
// Initialize client generator
|
||||||
routerUrl := getStringArgWithDefault(arguments["--routerUrl"], "http://router.fission")
|
|
||||||
storageSvcUrl := getStringArgWithDefault(arguments["--storageSvcUrl"], "http://storagesvc.fission")
|
|
||||||
clientGen := crd.NewClientGenerator()
|
clientGen := crd.NewClientGenerator()
|
||||||
|
|
||||||
if arguments["--webhookPort"] != nil {
|
// Start the appropriate service based on command line arguments
|
||||||
port := getPort(logger, arguments["--webhookPort"])
|
startRequestedService(ctx, args, clientGen, logger, mgr)
|
||||||
err = runWebhook(ctx, clientGen, logger, port)
|
|
||||||
|
<-ctx.Done()
|
||||||
|
logger.Error("exiting")
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupCommandLineArgs parses command line arguments and returns them
|
||||||
|
func setupCommandLineArgs() *CommandLineArgs {
|
||||||
|
args := &CommandLineArgs{}
|
||||||
|
|
||||||
|
// Override the default usage function
|
||||||
|
flag.Usage = func() {
|
||||||
|
fmt.Println(usageText)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell glog to log into STDERR
|
||||||
|
flag.Set("logtostderr", "true") //nolint: errcheck
|
||||||
|
|
||||||
|
// Define flags
|
||||||
|
flag.BoolVar(&args.canaryConfig, "canaryConfig", false, "Start canary config server")
|
||||||
|
flag.BoolVar(&args.kubewatcher, "kubewatcher", false, "Start Kubernetes events watcher")
|
||||||
|
flag.BoolVar(&args.timer, "timer", false, "Start Timer")
|
||||||
|
flag.BoolVar(&args.mqt, "mqt", false, "Start message queue trigger")
|
||||||
|
flag.BoolVar(&args.mqt_keda, "mqt_keda", false, "Start message queue trigger of kind KEDA")
|
||||||
|
flag.BoolVar(&args.builderMgr, "builderMgr", false, "Start builder manager")
|
||||||
|
flag.BoolVar(&args.showVersion, "version", false, "Print version information")
|
||||||
|
flag.BoolVar(&args.logger, "logger", false, "Start logger")
|
||||||
|
|
||||||
|
// Port flags
|
||||||
|
flag.IntVar(&args.webhookPort, "webhookPort", 0, "Port that the webhook should listen on")
|
||||||
|
flag.IntVar(&args.routerPort, "routerPort", 0, "Port that the router should listen on")
|
||||||
|
flag.IntVar(&args.executorPort, "executorPort", 0, "Port that the executor should listen on")
|
||||||
|
flag.IntVar(&args.storageServicePort, "storageServicePort", 0, "Port that the storage service should listen on")
|
||||||
|
|
||||||
|
// URL flags
|
||||||
|
flag.StringVar(&args.executorUrl, "executorUrl", "http://executor.fission", "Executor URL")
|
||||||
|
flag.StringVar(&args.routerUrl, "routerUrl", "http://router.fission", "Router URL")
|
||||||
|
flag.StringVar(&args.storageSvcUrl, "storageSvcUrl", "http://storagesvc.fission", "StorageService URL")
|
||||||
|
|
||||||
|
// Other configuration flags
|
||||||
|
flag.StringVar(&args.storageType, "storageType", "", "Type of storage to use")
|
||||||
|
|
||||||
|
// Parse flags
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
|
// getServiceNameFromArgs determines which service is being started based on command line args
|
||||||
|
func getServiceNameFromArgs(args *CommandLineArgs) string {
|
||||||
|
serviceName := "Fission-Unknown"
|
||||||
|
|
||||||
|
if args.routerPort != 0 {
|
||||||
|
serviceName = "Fission-Router"
|
||||||
|
} else if args.executorPort != 0 {
|
||||||
|
serviceName = "Fission-Executor"
|
||||||
|
} else if args.kubewatcher {
|
||||||
|
serviceName = "Fission-KubeWatcher"
|
||||||
|
} else if args.timer {
|
||||||
|
serviceName = "Fission-Timer"
|
||||||
|
} else if args.mqt {
|
||||||
|
serviceName = "Fission-MessageQueueTrigger"
|
||||||
|
} else if args.builderMgr {
|
||||||
|
serviceName = "Fission-BuilderMgr"
|
||||||
|
} else if args.storageServicePort != 0 {
|
||||||
|
serviceName = "Fission-StorageSvc"
|
||||||
|
} else if args.mqt_keda {
|
||||||
|
serviceName = "Fission-Keda-MQTrigger"
|
||||||
|
}
|
||||||
|
|
||||||
|
return serviceName
|
||||||
|
}
|
||||||
|
|
||||||
|
// startRequestedService starts the service specified by command line arguments
|
||||||
|
func startRequestedService(ctx context.Context, args *CommandLineArgs, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Start the requested service based on command line arguments
|
||||||
|
if args.webhookPort != 0 {
|
||||||
|
err = webhook.Start(ctx, clientGen, logger, cnwebhook.Options{
|
||||||
|
Port: args.webhookPort,
|
||||||
|
})
|
||||||
logger.Error("webhook server exited:", zap.Error(err))
|
logger.Error("webhook server exited:", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arguments["--canaryConfig"] == true {
|
if args.canaryConfig {
|
||||||
err := runCanaryConfigServer(ctx, clientGen, logger, mgr)
|
err = canaryconfigmgr.StartCanaryServer(ctx, clientGen, logger, mgr, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("canary config server exited with error: ", zap.Error(err))
|
logger.Error("canary config server exited with error: ", zap.Error(err))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arguments["--routerPort"] != nil {
|
if args.routerPort != 0 {
|
||||||
port := getPort(logger, arguments["--routerPort"])
|
err = router.Start(ctx, clientGen, logger, mgr, args.routerPort, eclient.MakeClient(logger, args.executorUrl))
|
||||||
err = runRouter(ctx, clientGen, logger, mgr, port, executorUrl)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("router exited", zap.Error(err))
|
logger.Error("router exited", zap.Error(err))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arguments["--executorPort"] != nil {
|
if args.executorPort != 0 {
|
||||||
port := getPort(logger, arguments["--executorPort"])
|
err = executor.StartExecutor(ctx, clientGen, logger, mgr, args.executorPort)
|
||||||
err = runExecutor(ctx, clientGen, logger, mgr, port)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("executor exited", zap.Error(err))
|
logger.Error("executor exited", zap.Error(err))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arguments["--kubewatcher"] == true {
|
if args.kubewatcher {
|
||||||
err = runKubeWatcher(ctx, clientGen, logger, mgr, routerUrl)
|
err = kubewatcher.Start(ctx, clientGen, logger, mgr, args.routerUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("kubewatcher exited", zap.Error(err))
|
logger.Error("kubewatcher exited", zap.Error(err))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arguments["--timer"] == true {
|
if args.timer {
|
||||||
err = runTimer(ctx, clientGen, logger, mgr, routerUrl)
|
err = timer.Start(ctx, clientGen, logger, mgr, args.routerUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("timer exited", zap.Error(err))
|
logger.Error("timer exited", zap.Error(err))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arguments["--mqt"] == true {
|
if args.mqt {
|
||||||
err = runMessageQueueMgr(ctx, clientGen, logger, mgr, routerUrl)
|
err = mqtrigger.Start(ctx, clientGen, logger, mgr, args.routerUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("message queue manager exited", zap.Error(err))
|
logger.Error("message queue manager exited", zap.Error(err))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arguments["--mqt_keda"] == true {
|
if args.mqt_keda {
|
||||||
err = runMQManager(ctx, clientGen, logger, mgr, routerUrl)
|
err = mqt.StartScalerManager(ctx, clientGen, logger, mgr, args.routerUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("mqt scaler manager exited", zap.Error(err))
|
logger.Error("mqt scaler manager exited", zap.Error(err))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arguments["--builderMgr"] == true {
|
if args.builderMgr {
|
||||||
err = runBuilderMgr(ctx, clientGen, logger, mgr, storageSvcUrl)
|
err = buildermgr.Start(ctx, clientGen, logger, mgr, args.storageSvcUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("builder manager exited", zap.Error(err))
|
logger.Error("builder manager exited", zap.Error(err))
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arguments["--logger"] == true {
|
if args.logger {
|
||||||
err = runLogger(ctx, clientGen, logger)
|
err = functionLogger.Start(ctx, clientGen, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("logger exited", zap.Error(err))
|
logger.Error("logger exited", zap.Error(err))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if arguments["--storageServicePort"] != nil {
|
if args.storageServicePort != 0 {
|
||||||
port := getPort(logger, arguments["--storageServicePort"])
|
startStorageService(ctx, args, clientGen, logger, mgr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var storage storagesvc.Storage
|
// startStorageService initializes and starts the storage service
|
||||||
|
func startStorageService(ctx context.Context, args *CommandLineArgs, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface) {
|
||||||
|
var storage storagesvc.Storage
|
||||||
|
|
||||||
if arguments["--storageType"] != nil && arguments["--storageType"] == string(storagesvc.StorageTypeS3) {
|
if args.storageType == string(storagesvc.StorageTypeS3) {
|
||||||
storage = storagesvc.NewS3Storage()
|
storage = storagesvc.NewS3Storage()
|
||||||
} else if arguments["--storageType"] == string(storagesvc.StorageTypeLocal) {
|
} else if args.storageType == string(storagesvc.StorageTypeLocal) {
|
||||||
storage = storagesvc.NewLocalStorage("/fission")
|
storage = storagesvc.NewLocalStorage("/fission")
|
||||||
}
|
|
||||||
err := runStorageSvc(ctx, clientGen, logger, mgr, port, storage)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("storage service exited", zap.Error(err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<-ctx.Done()
|
err := storagesvc.Start(ctx, clientGen, logger, storage, mgr, args.storageServicePort)
|
||||||
logger.Error("exiting")
|
if err != nil {
|
||||||
|
logger.Error("storage service exited", zap.Error(err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||||
@@ -41,12 +40,12 @@ import (
|
|||||||
func Start(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface, routerUrl string) error {
|
func Start(ctx context.Context, clientGen crd.ClientGeneratorInterface, logger *zap.Logger, mgr manager.Interface, routerUrl string) error {
|
||||||
fissionClient, err := clientGen.GetFissionClient()
|
fissionClient, err := clientGen.GetFissionClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get fission client")
|
return fmt.Errorf("failed to get fission client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = crd.WaitForFunctionCRDs(ctx, logger, fissionClient)
|
err = crd.WaitForFunctionCRDs(ctx, logger, fissionClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "error waiting for CRDs")
|
return fmt.Errorf("error waiting for CRDs: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mqType := (fv1.MessageQueueType)(os.Getenv("MESSAGE_QUEUE_TYPE"))
|
mqType := (fv1.MessageQueueType)(os.Getenv("MESSAGE_QUEUE_TYPE"))
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ limitations under the License.
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"fmt"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||||
@@ -65,7 +66,7 @@ func App(clientOptions cmd.ClientOptions) *cobra.Command {
|
|||||||
// }
|
// }
|
||||||
client, err := cmd.NewClient(clientOptions)
|
client, err := cmd.NewClient(clientOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get fission client")
|
return fmt.Errorf("failed to get fission client: %w", err)
|
||||||
}
|
}
|
||||||
cmd.SetClientset(*client)
|
cmd.SetClientset(*client)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
FROM cgr.dev/chainguard/static:latest@sha256:5497b01f36ef14a5198c0165e50ae6a0006d0c7457d4566f1110257e1c0812ed
|
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
|
||||||
COPY pre-upgrade-checks /
|
ARG TARGETPLATFORM
|
||||||
|
COPY $TARGETPLATFORM/pre-upgrade-checks /
|
||||||
ENTRYPOINT ["/pre-upgrade-checks"]
|
ENTRYPOINT ["/pre-upgrade-checks"]
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@@ -12,8 +11,7 @@ import (
|
|||||||
func TestPreUpgradeTaskClient(t *testing.T) {
|
func TestPreUpgradeTaskClient(t *testing.T) {
|
||||||
f := framework.NewFramework()
|
f := framework.NewFramework()
|
||||||
defer f.Logger().Sync()
|
defer f.Logger().Sync()
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx := t.Context()
|
||||||
defer cancel()
|
|
||||||
err := f.Start(ctx)
|
err := f.Start(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
FROM cgr.dev/chainguard/static:latest@sha256:5497b01f36ef14a5198c0165e50ae6a0006d0c7457d4566f1110257e1c0812ed
|
FROM cgr.dev/chainguard/static:latest@sha256:a301031ffd4ed67f35ca7fa6cf3dad9937b5fa47d7493955a18d9b4ca5412d1a
|
||||||
COPY reporter /
|
ARG TARGETPLATFORM
|
||||||
|
COPY $TARGETPLATFORM/reporter /
|
||||||
ENTRYPOINT ["/reporter"]
|
ENTRYPOINT ["/reporter"]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
|||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.1
|
controller-gen.kubebuilder.io/version: v0.17.2
|
||||||
name: canaryconfigs.fission.io
|
name: canaryconfigs.fission.io
|
||||||
spec:
|
spec:
|
||||||
group: fission.io
|
group: fission.io
|
||||||
|
|||||||
+1122
-144
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
|||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.1
|
controller-gen.kubebuilder.io/version: v0.17.2
|
||||||
name: functions.fission.io
|
name: functions.fission.io
|
||||||
spec:
|
spec:
|
||||||
group: fission.io
|
group: fission.io
|
||||||
@@ -93,7 +93,9 @@ spec:
|
|||||||
policies:
|
policies:
|
||||||
description: |-
|
description: |-
|
||||||
policies is a list of potential scaling polices which can be used during scaling.
|
policies is a list of potential scaling polices which can be used during scaling.
|
||||||
At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid
|
If not set, use the default values:
|
||||||
|
- For scale up: allow doubling the number of pods, or an absolute change of 4 pods in a 15s window.
|
||||||
|
- For scale down: allow all pods to be removed in a 15s window.
|
||||||
items:
|
items:
|
||||||
description: HPAScalingPolicy is a single policy
|
description: HPAScalingPolicy is a single policy
|
||||||
which must hold true for a specified past interval.
|
which must hold true for a specified past interval.
|
||||||
@@ -136,6 +138,24 @@ spec:
|
|||||||
- For scale down: 300 (i.e. the stabilization window is 300 seconds long).
|
- For scale down: 300 (i.e. the stabilization window is 300 seconds long).
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
|
tolerance:
|
||||||
|
anyOf:
|
||||||
|
- type: integer
|
||||||
|
- type: string
|
||||||
|
description: |-
|
||||||
|
tolerance is the tolerance on the ratio between the current and desired
|
||||||
|
metric value under which no updates are made to the desired number of
|
||||||
|
replicas (e.g. 0.01 for 1%). Must be greater than or equal to zero. If not
|
||||||
|
set, the default cluster-wide tolerance is applied (by default 10%).
|
||||||
|
|
||||||
|
For example, if autoscaling is configured with a memory consumption target of 100Mi,
|
||||||
|
and scale-down and scale-up tolerances of 5% and 1% respectively, scaling will be
|
||||||
|
triggered when the actual consumption falls below 95Mi or exceeds 101Mi.
|
||||||
|
|
||||||
|
This is an alpha field and requires enabling the HPAConfigurableTolerance
|
||||||
|
feature gate.
|
||||||
|
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||||
|
x-kubernetes-int-or-string: true
|
||||||
type: object
|
type: object
|
||||||
scaleUp:
|
scaleUp:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -148,7 +168,9 @@ spec:
|
|||||||
policies:
|
policies:
|
||||||
description: |-
|
description: |-
|
||||||
policies is a list of potential scaling polices which can be used during scaling.
|
policies is a list of potential scaling polices which can be used during scaling.
|
||||||
At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid
|
If not set, use the default values:
|
||||||
|
- For scale up: allow doubling the number of pods, or an absolute change of 4 pods in a 15s window.
|
||||||
|
- For scale down: allow all pods to be removed in a 15s window.
|
||||||
items:
|
items:
|
||||||
description: HPAScalingPolicy is a single policy
|
description: HPAScalingPolicy is a single policy
|
||||||
which must hold true for a specified past interval.
|
which must hold true for a specified past interval.
|
||||||
@@ -191,6 +213,24 @@ spec:
|
|||||||
- For scale down: 300 (i.e. the stabilization window is 300 seconds long).
|
- For scale down: 300 (i.e. the stabilization window is 300 seconds long).
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
|
tolerance:
|
||||||
|
anyOf:
|
||||||
|
- type: integer
|
||||||
|
- type: string
|
||||||
|
description: |-
|
||||||
|
tolerance is the tolerance on the ratio between the current and desired
|
||||||
|
metric value under which no updates are made to the desired number of
|
||||||
|
replicas (e.g. 0.01 for 1%). Must be greater than or equal to zero. If not
|
||||||
|
set, the default cluster-wide tolerance is applied (by default 10%).
|
||||||
|
|
||||||
|
For example, if autoscaling is configured with a memory consumption target of 100Mi,
|
||||||
|
and scale-down and scale-up tolerances of 5% and 1% respectively, scaling will be
|
||||||
|
triggered when the actual consumption falls below 95Mi or exceeds 101Mi.
|
||||||
|
|
||||||
|
This is an alpha field and requires enabling the HPAConfigurableTolerance
|
||||||
|
feature gate.
|
||||||
|
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||||
|
x-kubernetes-int-or-string: true
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
hpaMetrics:
|
hpaMetrics:
|
||||||
@@ -1047,7 +1087,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
||||||
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -1062,7 +1101,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
||||||
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -1229,7 +1267,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
||||||
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -1244,7 +1281,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
||||||
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -1338,8 +1374,8 @@ spec:
|
|||||||
most preferred is the one with the greatest sum of weights, i.e.
|
most preferred is the one with the greatest sum of weights, i.e.
|
||||||
for each node that meets all of the scheduling requirements (resource
|
for each node that meets all of the scheduling requirements (resource
|
||||||
request, requiredDuringScheduling anti-affinity expressions, etc.),
|
request, requiredDuringScheduling anti-affinity expressions, etc.),
|
||||||
compute a sum by iterating through the elements of this field and adding
|
compute a sum by iterating through the elements of this field and subtracting
|
||||||
"weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the
|
"weight" from the sum if the node has pods which matches the corresponding podAffinityTerm; the
|
||||||
node(s) with the highest sum are the most preferred.
|
node(s) with the highest sum are the most preferred.
|
||||||
items:
|
items:
|
||||||
description: The weights of all of the matched WeightedPodAffinityTerm
|
description: The weights of all of the matched WeightedPodAffinityTerm
|
||||||
@@ -1409,7 +1445,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
||||||
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -1424,7 +1459,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
||||||
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -1591,7 +1625,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
||||||
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -1606,7 +1639,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
||||||
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -1739,8 +1771,9 @@ spec:
|
|||||||
present in a Container.
|
present in a Container.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
description: Name of the environment variable. Must
|
description: |-
|
||||||
be a C_IDENTIFIER.
|
Name of the environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
value:
|
value:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -1798,6 +1831,43 @@ spec:
|
|||||||
- fieldPath
|
- fieldPath
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
|
fileKeyRef:
|
||||||
|
description: |-
|
||||||
|
FileKeyRef selects a key of the env file.
|
||||||
|
Requires the EnvFiles feature gate to be enabled.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key within the env file. An invalid key will prevent the pod from starting.
|
||||||
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
|
During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters.
|
||||||
|
type: string
|
||||||
|
optional:
|
||||||
|
default: false
|
||||||
|
description: |-
|
||||||
|
Specify whether the file or its key must be defined. If the file or key
|
||||||
|
does not exist, then the env var is not published.
|
||||||
|
If optional is set to true and the specified key does not exist,
|
||||||
|
the environment variable will not be set in the Pod's containers.
|
||||||
|
|
||||||
|
If optional is set to false and the specified key does not exist,
|
||||||
|
an error will be returned during Pod creation.
|
||||||
|
type: boolean
|
||||||
|
path:
|
||||||
|
description: |-
|
||||||
|
The path within the volume from which to select the file.
|
||||||
|
Must be relative and may not contain the '..' path or start with '..'.
|
||||||
|
type: string
|
||||||
|
volumeName:
|
||||||
|
description: The name of the volume mount
|
||||||
|
containing the env file.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- key
|
||||||
|
- path
|
||||||
|
- volumeName
|
||||||
|
type: object
|
||||||
|
x-kubernetes-map-type: atomic
|
||||||
resourceFieldRef:
|
resourceFieldRef:
|
||||||
description: |-
|
description: |-
|
||||||
Selects a resource of the container: only resources limits and requests
|
Selects a resource of the container: only resources limits and requests
|
||||||
@@ -1858,14 +1928,14 @@ spec:
|
|||||||
envFrom:
|
envFrom:
|
||||||
description: |-
|
description: |-
|
||||||
List of sources to populate environment variables in the container.
|
List of sources to populate environment variables in the container.
|
||||||
The keys defined within a source must be a C_IDENTIFIER. All invalid keys
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
will be reported as an event when the container is starting. When a key exists in multiple
|
When a key exists in multiple
|
||||||
sources, the value associated with the last source will take precedence.
|
sources, the value associated with the last source will take precedence.
|
||||||
Values defined by an Env with a duplicate key will take precedence.
|
Values defined by an Env with a duplicate key will take precedence.
|
||||||
Cannot be updated.
|
Cannot be updated.
|
||||||
items:
|
items:
|
||||||
description: EnvFromSource represents the source of a
|
description: EnvFromSource represents the source of a
|
||||||
set of ConfigMaps
|
set of ConfigMaps or Secrets
|
||||||
properties:
|
properties:
|
||||||
configMapRef:
|
configMapRef:
|
||||||
description: The ConfigMap to select from
|
description: The ConfigMap to select from
|
||||||
@@ -1886,8 +1956,9 @@ spec:
|
|||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
prefix:
|
prefix:
|
||||||
description: An optional identifier to prepend to
|
description: |-
|
||||||
each key in the ConfigMap. Must be a C_IDENTIFIER.
|
Optional text to prepend to the name of each environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
secretRef:
|
secretRef:
|
||||||
description: The Secret to select from
|
description: The Secret to select from
|
||||||
@@ -2151,6 +2222,12 @@ spec:
|
|||||||
- port
|
- port
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
|
stopSignal:
|
||||||
|
description: |-
|
||||||
|
StopSignal defines which signal will be sent to a container when it is being stopped.
|
||||||
|
If not specified, the default is defined by the container runtime in use.
|
||||||
|
StopSignal can only be set for Pods with a non-empty .spec.os.name
|
||||||
|
type: string
|
||||||
type: object
|
type: object
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -2558,7 +2635,7 @@ spec:
|
|||||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
that are used by this container.
|
that are used by this container.
|
||||||
|
|
||||||
This is an alpha field and requires enabling the
|
This field depends on the
|
||||||
DynamicResourceAllocation feature gate.
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
This field is immutable. It can only be set for containers.
|
This field is immutable. It can only be set for containers.
|
||||||
@@ -2613,10 +2690,10 @@ spec:
|
|||||||
restartPolicy:
|
restartPolicy:
|
||||||
description: |-
|
description: |-
|
||||||
RestartPolicy defines the restart behavior of individual containers in a pod.
|
RestartPolicy defines the restart behavior of individual containers in a pod.
|
||||||
This field may only be set for init containers, and the only allowed value is "Always".
|
This overrides the pod-level restart policy. When this field is not specified,
|
||||||
For non-init containers or when this field is not specified,
|
|
||||||
the restart behavior is defined by the Pod's restart policy and the container type.
|
the restart behavior is defined by the Pod's restart policy and the container type.
|
||||||
Setting the RestartPolicy as "Always" for the init container will have the following effect:
|
Additionally, setting the RestartPolicy as "Always" for the init container will
|
||||||
|
have the following effect:
|
||||||
this init container will be continually restarted on
|
this init container will be continually restarted on
|
||||||
exit until all regular containers have terminated. Once all regular
|
exit until all regular containers have terminated. Once all regular
|
||||||
containers have completed, all init containers with restartPolicy "Always"
|
containers have completed, all init containers with restartPolicy "Always"
|
||||||
@@ -2628,6 +2705,59 @@ spec:
|
|||||||
init container is started, or after any startupProbe has successfully
|
init container is started, or after any startupProbe has successfully
|
||||||
completed.
|
completed.
|
||||||
type: string
|
type: string
|
||||||
|
restartPolicyRules:
|
||||||
|
description: |-
|
||||||
|
Represents a list of rules to be checked to determine if the
|
||||||
|
container should be restarted on exit. The rules are evaluated in
|
||||||
|
order. Once a rule matches a container exit condition, the remaining
|
||||||
|
rules are ignored. If no rule matches the container exit condition,
|
||||||
|
the Container-level restart policy determines the whether the container
|
||||||
|
is restarted or not. Constraints on the rules:
|
||||||
|
- At most 20 rules are allowed.
|
||||||
|
- Rules can have the same action.
|
||||||
|
- Identical rules are not forbidden in validations.
|
||||||
|
When rules are specified, container MUST set RestartPolicy explicitly
|
||||||
|
even it if matches the Pod's RestartPolicy.
|
||||||
|
items:
|
||||||
|
description: ContainerRestartRule describes how a container
|
||||||
|
exit is handled.
|
||||||
|
properties:
|
||||||
|
action:
|
||||||
|
description: |-
|
||||||
|
Specifies the action taken on a container exit if the requirements
|
||||||
|
are satisfied. The only possible value is "Restart" to restart the
|
||||||
|
container.
|
||||||
|
type: string
|
||||||
|
exitCodes:
|
||||||
|
description: Represents the exit codes to check on
|
||||||
|
container exits.
|
||||||
|
properties:
|
||||||
|
operator:
|
||||||
|
description: |-
|
||||||
|
Represents the relationship between the container exit code(s) and the
|
||||||
|
specified values. Possible values are:
|
||||||
|
- In: the requirement is satisfied if the container exit code is in the
|
||||||
|
set of specified values.
|
||||||
|
- NotIn: the requirement is satisfied if the container exit code is
|
||||||
|
not in the set of specified values.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: |-
|
||||||
|
Specifies the set of values to check for container exit codes.
|
||||||
|
At most 255 elements are allowed.
|
||||||
|
items:
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: set
|
||||||
|
required:
|
||||||
|
- operator
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- action
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: atomic
|
||||||
securityContext:
|
securityContext:
|
||||||
description: |-
|
description: |-
|
||||||
SecurityContext defines the security options the container should be run with.
|
SecurityContext defines the security options the container should be run with.
|
||||||
@@ -3246,8 +3376,9 @@ spec:
|
|||||||
present in a Container.
|
present in a Container.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
description: Name of the environment variable. Must
|
description: |-
|
||||||
be a C_IDENTIFIER.
|
Name of the environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
value:
|
value:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -3305,6 +3436,43 @@ spec:
|
|||||||
- fieldPath
|
- fieldPath
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
|
fileKeyRef:
|
||||||
|
description: |-
|
||||||
|
FileKeyRef selects a key of the env file.
|
||||||
|
Requires the EnvFiles feature gate to be enabled.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key within the env file. An invalid key will prevent the pod from starting.
|
||||||
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
|
During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters.
|
||||||
|
type: string
|
||||||
|
optional:
|
||||||
|
default: false
|
||||||
|
description: |-
|
||||||
|
Specify whether the file or its key must be defined. If the file or key
|
||||||
|
does not exist, then the env var is not published.
|
||||||
|
If optional is set to true and the specified key does not exist,
|
||||||
|
the environment variable will not be set in the Pod's containers.
|
||||||
|
|
||||||
|
If optional is set to false and the specified key does not exist,
|
||||||
|
an error will be returned during Pod creation.
|
||||||
|
type: boolean
|
||||||
|
path:
|
||||||
|
description: |-
|
||||||
|
The path within the volume from which to select the file.
|
||||||
|
Must be relative and may not contain the '..' path or start with '..'.
|
||||||
|
type: string
|
||||||
|
volumeName:
|
||||||
|
description: The name of the volume mount
|
||||||
|
containing the env file.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- key
|
||||||
|
- path
|
||||||
|
- volumeName
|
||||||
|
type: object
|
||||||
|
x-kubernetes-map-type: atomic
|
||||||
resourceFieldRef:
|
resourceFieldRef:
|
||||||
description: |-
|
description: |-
|
||||||
Selects a resource of the container: only resources limits and requests
|
Selects a resource of the container: only resources limits and requests
|
||||||
@@ -3365,14 +3533,14 @@ spec:
|
|||||||
envFrom:
|
envFrom:
|
||||||
description: |-
|
description: |-
|
||||||
List of sources to populate environment variables in the container.
|
List of sources to populate environment variables in the container.
|
||||||
The keys defined within a source must be a C_IDENTIFIER. All invalid keys
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
will be reported as an event when the container is starting. When a key exists in multiple
|
When a key exists in multiple
|
||||||
sources, the value associated with the last source will take precedence.
|
sources, the value associated with the last source will take precedence.
|
||||||
Values defined by an Env with a duplicate key will take precedence.
|
Values defined by an Env with a duplicate key will take precedence.
|
||||||
Cannot be updated.
|
Cannot be updated.
|
||||||
items:
|
items:
|
||||||
description: EnvFromSource represents the source of a
|
description: EnvFromSource represents the source of a
|
||||||
set of ConfigMaps
|
set of ConfigMaps or Secrets
|
||||||
properties:
|
properties:
|
||||||
configMapRef:
|
configMapRef:
|
||||||
description: The ConfigMap to select from
|
description: The ConfigMap to select from
|
||||||
@@ -3393,8 +3561,9 @@ spec:
|
|||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
prefix:
|
prefix:
|
||||||
description: An optional identifier to prepend to
|
description: |-
|
||||||
each key in the ConfigMap. Must be a C_IDENTIFIER.
|
Optional text to prepend to the name of each environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
secretRef:
|
secretRef:
|
||||||
description: The Secret to select from
|
description: The Secret to select from
|
||||||
@@ -3654,6 +3823,12 @@ spec:
|
|||||||
- port
|
- port
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
|
stopSignal:
|
||||||
|
description: |-
|
||||||
|
StopSignal defines which signal will be sent to a container when it is being stopped.
|
||||||
|
If not specified, the default is defined by the container runtime in use.
|
||||||
|
StopSignal can only be set for Pods with a non-empty .spec.os.name
|
||||||
|
type: string
|
||||||
type: object
|
type: object
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
description: Probes are not allowed for ephemeral containers.
|
description: Probes are not allowed for ephemeral containers.
|
||||||
@@ -4044,7 +4219,7 @@ spec:
|
|||||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
that are used by this container.
|
that are used by this container.
|
||||||
|
|
||||||
This is an alpha field and requires enabling the
|
This field depends on the
|
||||||
DynamicResourceAllocation feature gate.
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
This field is immutable. It can only be set for containers.
|
This field is immutable. It can only be set for containers.
|
||||||
@@ -4100,9 +4275,53 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
Restart policy for the container to manage the restart behavior of each
|
Restart policy for the container to manage the restart behavior of each
|
||||||
container within a pod.
|
container within a pod.
|
||||||
This may only be set for init containers. You cannot set this field on
|
You cannot set this field on ephemeral containers.
|
||||||
ephemeral containers.
|
|
||||||
type: string
|
type: string
|
||||||
|
restartPolicyRules:
|
||||||
|
description: |-
|
||||||
|
Represents a list of rules to be checked to determine if the
|
||||||
|
container should be restarted on exit. You cannot set this field on
|
||||||
|
ephemeral containers.
|
||||||
|
items:
|
||||||
|
description: ContainerRestartRule describes how a container
|
||||||
|
exit is handled.
|
||||||
|
properties:
|
||||||
|
action:
|
||||||
|
description: |-
|
||||||
|
Specifies the action taken on a container exit if the requirements
|
||||||
|
are satisfied. The only possible value is "Restart" to restart the
|
||||||
|
container.
|
||||||
|
type: string
|
||||||
|
exitCodes:
|
||||||
|
description: Represents the exit codes to check on
|
||||||
|
container exits.
|
||||||
|
properties:
|
||||||
|
operator:
|
||||||
|
description: |-
|
||||||
|
Represents the relationship between the container exit code(s) and the
|
||||||
|
specified values. Possible values are:
|
||||||
|
- In: the requirement is satisfied if the container exit code is in the
|
||||||
|
set of specified values.
|
||||||
|
- NotIn: the requirement is satisfied if the container exit code is
|
||||||
|
not in the set of specified values.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: |-
|
||||||
|
Specifies the set of values to check for container exit codes.
|
||||||
|
At most 255 elements are allowed.
|
||||||
|
items:
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: set
|
||||||
|
required:
|
||||||
|
- operator
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- action
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: atomic
|
||||||
securityContext:
|
securityContext:
|
||||||
description: |-
|
description: |-
|
||||||
Optional: SecurityContext defines the security options the ephemeral container should be run with.
|
Optional: SecurityContext defines the security options the ephemeral container should be run with.
|
||||||
@@ -4640,7 +4859,9 @@ spec:
|
|||||||
hostNetwork:
|
hostNetwork:
|
||||||
description: |-
|
description: |-
|
||||||
Host networking requested for this pod. Use the host's network namespace.
|
Host networking requested for this pod. Use the host's network namespace.
|
||||||
If this option is set, the ports that will be used must be specified.
|
When using HostNetwork you should specify ports so the scheduler is aware.
|
||||||
|
When `hostNetwork` is true, specified `hostPort` fields in port definitions must match `containerPort`,
|
||||||
|
and unspecified `hostPort` fields in port definitions are defaulted to match `containerPort`.
|
||||||
Default to false.
|
Default to false.
|
||||||
type: boolean
|
type: boolean
|
||||||
hostPID:
|
hostPID:
|
||||||
@@ -4665,6 +4886,19 @@ spec:
|
|||||||
Specifies the hostname of the Pod
|
Specifies the hostname of the Pod
|
||||||
If not specified, the pod's hostname will be set to a system-defined value.
|
If not specified, the pod's hostname will be set to a system-defined value.
|
||||||
type: string
|
type: string
|
||||||
|
hostnameOverride:
|
||||||
|
description: |-
|
||||||
|
HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod.
|
||||||
|
This field only specifies the pod's hostname and does not affect its DNS records.
|
||||||
|
When this field is set to a non-empty string:
|
||||||
|
- It takes precedence over the values set in `hostname` and `subdomain`.
|
||||||
|
- The Pod's hostname will be set to this value.
|
||||||
|
- `setHostnameAsFQDN` must be nil or set to false.
|
||||||
|
- `hostNetwork` must be set to false.
|
||||||
|
|
||||||
|
This field must be a valid DNS subdomain as defined in RFC 1123 and contain at most 64 characters.
|
||||||
|
Requires the HostnameOverride feature gate to be enabled.
|
||||||
|
type: string
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
description: |-
|
description: |-
|
||||||
ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
|
ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
|
||||||
@@ -4700,7 +4934,7 @@ spec:
|
|||||||
Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes.
|
Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes.
|
||||||
The resourceRequirements of an init container are taken into account during scheduling
|
The resourceRequirements of an init container are taken into account during scheduling
|
||||||
by finding the highest request/limit for each resource type, and then using the max of
|
by finding the highest request/limit for each resource type, and then using the max of
|
||||||
of that value or the sum of the normal containers. Limits are applied to init containers
|
that value or the sum of the normal containers. Limits are applied to init containers
|
||||||
in a similar fashion.
|
in a similar fashion.
|
||||||
Init containers cannot currently be added or removed.
|
Init containers cannot currently be added or removed.
|
||||||
Cannot be updated.
|
Cannot be updated.
|
||||||
@@ -4746,8 +4980,9 @@ spec:
|
|||||||
present in a Container.
|
present in a Container.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
description: Name of the environment variable. Must
|
description: |-
|
||||||
be a C_IDENTIFIER.
|
Name of the environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
value:
|
value:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -4805,6 +5040,43 @@ spec:
|
|||||||
- fieldPath
|
- fieldPath
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
|
fileKeyRef:
|
||||||
|
description: |-
|
||||||
|
FileKeyRef selects a key of the env file.
|
||||||
|
Requires the EnvFiles feature gate to be enabled.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key within the env file. An invalid key will prevent the pod from starting.
|
||||||
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
|
During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters.
|
||||||
|
type: string
|
||||||
|
optional:
|
||||||
|
default: false
|
||||||
|
description: |-
|
||||||
|
Specify whether the file or its key must be defined. If the file or key
|
||||||
|
does not exist, then the env var is not published.
|
||||||
|
If optional is set to true and the specified key does not exist,
|
||||||
|
the environment variable will not be set in the Pod's containers.
|
||||||
|
|
||||||
|
If optional is set to false and the specified key does not exist,
|
||||||
|
an error will be returned during Pod creation.
|
||||||
|
type: boolean
|
||||||
|
path:
|
||||||
|
description: |-
|
||||||
|
The path within the volume from which to select the file.
|
||||||
|
Must be relative and may not contain the '..' path or start with '..'.
|
||||||
|
type: string
|
||||||
|
volumeName:
|
||||||
|
description: The name of the volume mount
|
||||||
|
containing the env file.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- key
|
||||||
|
- path
|
||||||
|
- volumeName
|
||||||
|
type: object
|
||||||
|
x-kubernetes-map-type: atomic
|
||||||
resourceFieldRef:
|
resourceFieldRef:
|
||||||
description: |-
|
description: |-
|
||||||
Selects a resource of the container: only resources limits and requests
|
Selects a resource of the container: only resources limits and requests
|
||||||
@@ -4865,14 +5137,14 @@ spec:
|
|||||||
envFrom:
|
envFrom:
|
||||||
description: |-
|
description: |-
|
||||||
List of sources to populate environment variables in the container.
|
List of sources to populate environment variables in the container.
|
||||||
The keys defined within a source must be a C_IDENTIFIER. All invalid keys
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
will be reported as an event when the container is starting. When a key exists in multiple
|
When a key exists in multiple
|
||||||
sources, the value associated with the last source will take precedence.
|
sources, the value associated with the last source will take precedence.
|
||||||
Values defined by an Env with a duplicate key will take precedence.
|
Values defined by an Env with a duplicate key will take precedence.
|
||||||
Cannot be updated.
|
Cannot be updated.
|
||||||
items:
|
items:
|
||||||
description: EnvFromSource represents the source of a
|
description: EnvFromSource represents the source of a
|
||||||
set of ConfigMaps
|
set of ConfigMaps or Secrets
|
||||||
properties:
|
properties:
|
||||||
configMapRef:
|
configMapRef:
|
||||||
description: The ConfigMap to select from
|
description: The ConfigMap to select from
|
||||||
@@ -4893,8 +5165,9 @@ spec:
|
|||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
prefix:
|
prefix:
|
||||||
description: An optional identifier to prepend to
|
description: |-
|
||||||
each key in the ConfigMap. Must be a C_IDENTIFIER.
|
Optional text to prepend to the name of each environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
secretRef:
|
secretRef:
|
||||||
description: The Secret to select from
|
description: The Secret to select from
|
||||||
@@ -5158,6 +5431,12 @@ spec:
|
|||||||
- port
|
- port
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
|
stopSignal:
|
||||||
|
description: |-
|
||||||
|
StopSignal defines which signal will be sent to a container when it is being stopped.
|
||||||
|
If not specified, the default is defined by the container runtime in use.
|
||||||
|
StopSignal can only be set for Pods with a non-empty .spec.os.name
|
||||||
|
type: string
|
||||||
type: object
|
type: object
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -5565,7 +5844,7 @@ spec:
|
|||||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
that are used by this container.
|
that are used by this container.
|
||||||
|
|
||||||
This is an alpha field and requires enabling the
|
This field depends on the
|
||||||
DynamicResourceAllocation feature gate.
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
This field is immutable. It can only be set for containers.
|
This field is immutable. It can only be set for containers.
|
||||||
@@ -5620,10 +5899,10 @@ spec:
|
|||||||
restartPolicy:
|
restartPolicy:
|
||||||
description: |-
|
description: |-
|
||||||
RestartPolicy defines the restart behavior of individual containers in a pod.
|
RestartPolicy defines the restart behavior of individual containers in a pod.
|
||||||
This field may only be set for init containers, and the only allowed value is "Always".
|
This overrides the pod-level restart policy. When this field is not specified,
|
||||||
For non-init containers or when this field is not specified,
|
|
||||||
the restart behavior is defined by the Pod's restart policy and the container type.
|
the restart behavior is defined by the Pod's restart policy and the container type.
|
||||||
Setting the RestartPolicy as "Always" for the init container will have the following effect:
|
Additionally, setting the RestartPolicy as "Always" for the init container will
|
||||||
|
have the following effect:
|
||||||
this init container will be continually restarted on
|
this init container will be continually restarted on
|
||||||
exit until all regular containers have terminated. Once all regular
|
exit until all regular containers have terminated. Once all regular
|
||||||
containers have completed, all init containers with restartPolicy "Always"
|
containers have completed, all init containers with restartPolicy "Always"
|
||||||
@@ -5635,6 +5914,59 @@ spec:
|
|||||||
init container is started, or after any startupProbe has successfully
|
init container is started, or after any startupProbe has successfully
|
||||||
completed.
|
completed.
|
||||||
type: string
|
type: string
|
||||||
|
restartPolicyRules:
|
||||||
|
description: |-
|
||||||
|
Represents a list of rules to be checked to determine if the
|
||||||
|
container should be restarted on exit. The rules are evaluated in
|
||||||
|
order. Once a rule matches a container exit condition, the remaining
|
||||||
|
rules are ignored. If no rule matches the container exit condition,
|
||||||
|
the Container-level restart policy determines the whether the container
|
||||||
|
is restarted or not. Constraints on the rules:
|
||||||
|
- At most 20 rules are allowed.
|
||||||
|
- Rules can have the same action.
|
||||||
|
- Identical rules are not forbidden in validations.
|
||||||
|
When rules are specified, container MUST set RestartPolicy explicitly
|
||||||
|
even it if matches the Pod's RestartPolicy.
|
||||||
|
items:
|
||||||
|
description: ContainerRestartRule describes how a container
|
||||||
|
exit is handled.
|
||||||
|
properties:
|
||||||
|
action:
|
||||||
|
description: |-
|
||||||
|
Specifies the action taken on a container exit if the requirements
|
||||||
|
are satisfied. The only possible value is "Restart" to restart the
|
||||||
|
container.
|
||||||
|
type: string
|
||||||
|
exitCodes:
|
||||||
|
description: Represents the exit codes to check on
|
||||||
|
container exits.
|
||||||
|
properties:
|
||||||
|
operator:
|
||||||
|
description: |-
|
||||||
|
Represents the relationship between the container exit code(s) and the
|
||||||
|
specified values. Possible values are:
|
||||||
|
- In: the requirement is satisfied if the container exit code is in the
|
||||||
|
set of specified values.
|
||||||
|
- NotIn: the requirement is satisfied if the container exit code is
|
||||||
|
not in the set of specified values.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: |-
|
||||||
|
Specifies the set of values to check for container exit codes.
|
||||||
|
At most 255 elements are allowed.
|
||||||
|
items:
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: set
|
||||||
|
required:
|
||||||
|
- operator
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- action
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: atomic
|
||||||
securityContext:
|
securityContext:
|
||||||
description: |-
|
description: |-
|
||||||
SecurityContext defines the security options the container should be run with.
|
SecurityContext defines the security options the container should be run with.
|
||||||
@@ -6167,6 +6499,7 @@ spec:
|
|||||||
- spec.hostPID
|
- spec.hostPID
|
||||||
- spec.hostIPC
|
- spec.hostIPC
|
||||||
- spec.hostUsers
|
- spec.hostUsers
|
||||||
|
- spec.resources
|
||||||
- spec.securityContext.appArmorProfile
|
- spec.securityContext.appArmorProfile
|
||||||
- spec.securityContext.seLinuxOptions
|
- spec.securityContext.seLinuxOptions
|
||||||
- spec.securityContext.seccompProfile
|
- spec.securityContext.seccompProfile
|
||||||
@@ -6320,7 +6653,7 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
Resources is the total amount of CPU and Memory resources required by all
|
Resources is the total amount of CPU and Memory resources required by all
|
||||||
containers in the pod. It supports specifying Requests and Limits for
|
containers in the pod. It supports specifying Requests and Limits for
|
||||||
"cpu" and "memory" resource names only. ResourceClaims are not supported.
|
"cpu", "memory" and "hugepages-" resource names only. ResourceClaims are not supported.
|
||||||
|
|
||||||
This field enables fine-grained control over resource allocation for the
|
This field enables fine-grained control over resource allocation for the
|
||||||
entire pod, allowing resource sharing among containers in a pod.
|
entire pod, allowing resource sharing among containers in a pod.
|
||||||
@@ -6333,7 +6666,7 @@ spec:
|
|||||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
that are used by this container.
|
that are used by this container.
|
||||||
|
|
||||||
This is an alpha field and requires enabling the
|
This field depends on the
|
||||||
DynamicResourceAllocation feature gate.
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
This field is immutable. It can only be set for containers.
|
This field is immutable. It can only be set for containers.
|
||||||
@@ -6870,7 +7203,6 @@ spec:
|
|||||||
- Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.
|
- Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.
|
||||||
|
|
||||||
If this value is nil, the behavior is equivalent to the Honor policy.
|
If this value is nil, the behavior is equivalent to the Honor policy.
|
||||||
This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
|
|
||||||
type: string
|
type: string
|
||||||
nodeTaintsPolicy:
|
nodeTaintsPolicy:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -6881,7 +7213,6 @@ spec:
|
|||||||
- Ignore: node taints are ignored. All nodes are included.
|
- Ignore: node taints are ignored. All nodes are included.
|
||||||
|
|
||||||
If this value is nil, the behavior is equivalent to the Ignore policy.
|
If this value is nil, the behavior is equivalent to the Ignore policy.
|
||||||
This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
|
|
||||||
type: string
|
type: string
|
||||||
topologyKey:
|
topologyKey:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -7606,15 +7937,13 @@ spec:
|
|||||||
volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
|
volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
|
||||||
If specified, the CSI driver will create or update the volume with the attributes defined
|
If specified, the CSI driver will create or update the volume with the attributes defined
|
||||||
in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
|
in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
|
||||||
it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
|
it can be changed after the claim is created. An empty string or nil value indicates that no
|
||||||
will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
|
VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state,
|
||||||
If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
|
this field can be reset to its previous value (including nil) to cancel the modification.
|
||||||
will be set by the persistentvolume controller if it exists.
|
|
||||||
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
|
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
|
||||||
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
|
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
|
||||||
exists.
|
exists.
|
||||||
More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
|
More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
|
||||||
(Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).
|
|
||||||
type: string
|
type: string
|
||||||
volumeMode:
|
volumeMode:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -7796,12 +8125,10 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.
|
glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.
|
||||||
Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported.
|
Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported.
|
||||||
More info: https://examples.k8s.io/volumes/glusterfs/README.md
|
|
||||||
properties:
|
properties:
|
||||||
endpoints:
|
endpoints:
|
||||||
description: |-
|
description: endpoints is the endpoint name that details
|
||||||
endpoints is the endpoint name that details Glusterfs topology.
|
Glusterfs topology.
|
||||||
More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
|
|
||||||
type: string
|
type: string
|
||||||
path:
|
path:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -7855,7 +8182,7 @@ spec:
|
|||||||
The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field.
|
The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field.
|
||||||
The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images.
|
The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images.
|
||||||
The volume will be mounted read-only (ro) and non-executable files (noexec).
|
The volume will be mounted read-only (ro) and non-executable files (noexec).
|
||||||
Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath).
|
Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33.
|
||||||
The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.
|
The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.
|
||||||
properties:
|
properties:
|
||||||
pullPolicy:
|
pullPolicy:
|
||||||
@@ -7880,7 +8207,7 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
iscsi represents an ISCSI Disk resource that is attached to a
|
iscsi represents an ISCSI Disk resource that is attached to a
|
||||||
kubelet's host machine and then exposed to the pod.
|
kubelet's host machine and then exposed to the pod.
|
||||||
More info: https://examples.k8s.io/volumes/iscsi/README.md
|
More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi
|
||||||
properties:
|
properties:
|
||||||
chapAuthDiscovery:
|
chapAuthDiscovery:
|
||||||
description: chapAuthDiscovery defines whether support
|
description: chapAuthDiscovery defines whether support
|
||||||
@@ -8302,6 +8629,111 @@ spec:
|
|||||||
type: array
|
type: array
|
||||||
x-kubernetes-list-type: atomic
|
x-kubernetes-list-type: atomic
|
||||||
type: object
|
type: object
|
||||||
|
podCertificate:
|
||||||
|
description: |-
|
||||||
|
Projects an auto-rotating credential bundle (private key and certificate
|
||||||
|
chain) that the pod can use either as a TLS client or server.
|
||||||
|
|
||||||
|
Kubelet generates a private key and uses it to send a
|
||||||
|
PodCertificateRequest to the named signer. Once the signer approves the
|
||||||
|
request and issues a certificate chain, Kubelet writes the key and
|
||||||
|
certificate chain to the pod filesystem. The pod does not start until
|
||||||
|
certificates have been issued for each podCertificate projected volume
|
||||||
|
source in its spec.
|
||||||
|
|
||||||
|
Kubelet will begin trying to rotate the certificate at the time indicated
|
||||||
|
by the signer using the PodCertificateRequest.Status.BeginRefreshAt
|
||||||
|
timestamp.
|
||||||
|
|
||||||
|
Kubelet can write a single file, indicated by the credentialBundlePath
|
||||||
|
field, or separate files, indicated by the keyPath and
|
||||||
|
certificateChainPath fields.
|
||||||
|
|
||||||
|
The credential bundle is a single file in PEM format. The first PEM
|
||||||
|
entry is the private key (in PKCS#8 format), and the remaining PEM
|
||||||
|
entries are the certificate chain issued by the signer (typically,
|
||||||
|
signers will return their certificate chain in leaf-to-root order).
|
||||||
|
|
||||||
|
Prefer using the credential bundle format, since your application code
|
||||||
|
can read it atomically. If you use keyPath and certificateChainPath,
|
||||||
|
your application must make two separate file reads. If these coincide
|
||||||
|
with a certificate rotation, it is possible that the private key and leaf
|
||||||
|
certificate you read may not correspond to each other. Your application
|
||||||
|
will need to check for this condition, and re-read until they are
|
||||||
|
consistent.
|
||||||
|
|
||||||
|
The named signer controls chooses the format of the certificate it
|
||||||
|
issues; consult the signer implementation's documentation to learn how to
|
||||||
|
use the certificates it issues.
|
||||||
|
properties:
|
||||||
|
certificateChainPath:
|
||||||
|
description: |-
|
||||||
|
Write the certificate chain at this path in the projected volume.
|
||||||
|
|
||||||
|
Most applications should use credentialBundlePath. When using keyPath
|
||||||
|
and certificateChainPath, your application needs to check that the key
|
||||||
|
and leaf certificate are consistent, because it is possible to read the
|
||||||
|
files mid-rotation.
|
||||||
|
type: string
|
||||||
|
credentialBundlePath:
|
||||||
|
description: |-
|
||||||
|
Write the credential bundle at this path in the projected volume.
|
||||||
|
|
||||||
|
The credential bundle is a single file that contains multiple PEM blocks.
|
||||||
|
The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private
|
||||||
|
key.
|
||||||
|
|
||||||
|
The remaining blocks are CERTIFICATE blocks, containing the issued
|
||||||
|
certificate chain from the signer (leaf and any intermediates).
|
||||||
|
|
||||||
|
Using credentialBundlePath lets your Pod's application code make a single
|
||||||
|
atomic read that retrieves a consistent key and certificate chain. If you
|
||||||
|
project them to separate files, your application code will need to
|
||||||
|
additionally check that the leaf certificate was issued to the key.
|
||||||
|
type: string
|
||||||
|
keyPath:
|
||||||
|
description: |-
|
||||||
|
Write the key at this path in the projected volume.
|
||||||
|
|
||||||
|
Most applications should use credentialBundlePath. When using keyPath
|
||||||
|
and certificateChainPath, your application needs to check that the key
|
||||||
|
and leaf certificate are consistent, because it is possible to read the
|
||||||
|
files mid-rotation.
|
||||||
|
type: string
|
||||||
|
keyType:
|
||||||
|
description: |-
|
||||||
|
The type of keypair Kubelet will generate for the pod.
|
||||||
|
|
||||||
|
Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384",
|
||||||
|
"ECDSAP521", and "ED25519".
|
||||||
|
type: string
|
||||||
|
maxExpirationSeconds:
|
||||||
|
description: |-
|
||||||
|
maxExpirationSeconds is the maximum lifetime permitted for the
|
||||||
|
certificate.
|
||||||
|
|
||||||
|
Kubelet copies this value verbatim into the PodCertificateRequests it
|
||||||
|
generates for this projection.
|
||||||
|
|
||||||
|
If omitted, kube-apiserver will set it to 86400(24 hours). kube-apiserver
|
||||||
|
will reject values shorter than 3600 (1 hour). The maximum allowable
|
||||||
|
value is 7862400 (91 days).
|
||||||
|
|
||||||
|
The signer implementation is then free to issue a certificate with any
|
||||||
|
lifetime *shorter* than MaxExpirationSeconds, but no shorter than 3600
|
||||||
|
seconds (1 hour). This constraint is enforced by kube-apiserver.
|
||||||
|
`kubernetes.io` signers will never issue certificates with a lifetime
|
||||||
|
longer than 24 hours.
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
signerName:
|
||||||
|
description: Kubelet's generated CSRs will
|
||||||
|
be addressed to this signer.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- keyType
|
||||||
|
- signerName
|
||||||
|
type: object
|
||||||
secret:
|
secret:
|
||||||
description: secret information about the secret
|
description: secret information about the secret
|
||||||
data to project
|
data to project
|
||||||
@@ -8436,7 +8868,6 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
rbd represents a Rados Block Device mount on the host that shares a pod's lifetime.
|
rbd represents a Rados Block Device mount on the host that shares a pod's lifetime.
|
||||||
Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported.
|
Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported.
|
||||||
More info: https://examples.k8s.io/volumes/rbd/README.md
|
|
||||||
properties:
|
properties:
|
||||||
fsType:
|
fsType:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -8742,7 +9173,7 @@ spec:
|
|||||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
that are used by this container.
|
that are used by this container.
|
||||||
|
|
||||||
This is an alpha field and requires enabling the
|
This field depends on the
|
||||||
DynamicResourceAllocation feature gate.
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
This field is immutable. It can only be set for containers.
|
This field is immutable. It can only be set for containers.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
|||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.1
|
controller-gen.kubebuilder.io/version: v0.17.2
|
||||||
name: httptriggers.fission.io
|
name: httptriggers.fission.io
|
||||||
spec:
|
spec:
|
||||||
group: fission.io
|
group: fission.io
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
|||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.1
|
controller-gen.kubebuilder.io/version: v0.17.2
|
||||||
name: kuberneteswatchtriggers.fission.io
|
name: kuberneteswatchtriggers.fission.io
|
||||||
spec:
|
spec:
|
||||||
group: fission.io
|
group: fission.io
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
|||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.1
|
controller-gen.kubebuilder.io/version: v0.17.2
|
||||||
name: messagequeuetriggers.fission.io
|
name: messagequeuetriggers.fission.io
|
||||||
spec:
|
spec:
|
||||||
group: fission.io
|
group: fission.io
|
||||||
@@ -412,7 +412,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
||||||
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -427,7 +426,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
||||||
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -594,7 +592,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
||||||
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -609,7 +606,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
||||||
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -703,8 +699,8 @@ spec:
|
|||||||
most preferred is the one with the greatest sum of weights, i.e.
|
most preferred is the one with the greatest sum of weights, i.e.
|
||||||
for each node that meets all of the scheduling requirements (resource
|
for each node that meets all of the scheduling requirements (resource
|
||||||
request, requiredDuringScheduling anti-affinity expressions, etc.),
|
request, requiredDuringScheduling anti-affinity expressions, etc.),
|
||||||
compute a sum by iterating through the elements of this field and adding
|
compute a sum by iterating through the elements of this field and subtracting
|
||||||
"weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the
|
"weight" from the sum if the node has pods which matches the corresponding podAffinityTerm; the
|
||||||
node(s) with the highest sum are the most preferred.
|
node(s) with the highest sum are the most preferred.
|
||||||
items:
|
items:
|
||||||
description: The weights of all of the matched WeightedPodAffinityTerm
|
description: The weights of all of the matched WeightedPodAffinityTerm
|
||||||
@@ -774,7 +770,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
||||||
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -789,7 +784,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
||||||
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -956,7 +950,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both matchLabelKeys and labelSelector.
|
||||||
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
Also, matchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -971,7 +964,6 @@ spec:
|
|||||||
pod labels will be ignored. The default value is empty.
|
pod labels will be ignored. The default value is empty.
|
||||||
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.
|
||||||
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
Also, mismatchLabelKeys cannot be set when labelSelector isn't set.
|
||||||
This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).
|
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
@@ -1104,8 +1096,9 @@ spec:
|
|||||||
present in a Container.
|
present in a Container.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
description: Name of the environment variable. Must
|
description: |-
|
||||||
be a C_IDENTIFIER.
|
Name of the environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
value:
|
value:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -1163,6 +1156,43 @@ spec:
|
|||||||
- fieldPath
|
- fieldPath
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
|
fileKeyRef:
|
||||||
|
description: |-
|
||||||
|
FileKeyRef selects a key of the env file.
|
||||||
|
Requires the EnvFiles feature gate to be enabled.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key within the env file. An invalid key will prevent the pod from starting.
|
||||||
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
|
During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters.
|
||||||
|
type: string
|
||||||
|
optional:
|
||||||
|
default: false
|
||||||
|
description: |-
|
||||||
|
Specify whether the file or its key must be defined. If the file or key
|
||||||
|
does not exist, then the env var is not published.
|
||||||
|
If optional is set to true and the specified key does not exist,
|
||||||
|
the environment variable will not be set in the Pod's containers.
|
||||||
|
|
||||||
|
If optional is set to false and the specified key does not exist,
|
||||||
|
an error will be returned during Pod creation.
|
||||||
|
type: boolean
|
||||||
|
path:
|
||||||
|
description: |-
|
||||||
|
The path within the volume from which to select the file.
|
||||||
|
Must be relative and may not contain the '..' path or start with '..'.
|
||||||
|
type: string
|
||||||
|
volumeName:
|
||||||
|
description: The name of the volume mount
|
||||||
|
containing the env file.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- key
|
||||||
|
- path
|
||||||
|
- volumeName
|
||||||
|
type: object
|
||||||
|
x-kubernetes-map-type: atomic
|
||||||
resourceFieldRef:
|
resourceFieldRef:
|
||||||
description: |-
|
description: |-
|
||||||
Selects a resource of the container: only resources limits and requests
|
Selects a resource of the container: only resources limits and requests
|
||||||
@@ -1223,14 +1253,14 @@ spec:
|
|||||||
envFrom:
|
envFrom:
|
||||||
description: |-
|
description: |-
|
||||||
List of sources to populate environment variables in the container.
|
List of sources to populate environment variables in the container.
|
||||||
The keys defined within a source must be a C_IDENTIFIER. All invalid keys
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
will be reported as an event when the container is starting. When a key exists in multiple
|
When a key exists in multiple
|
||||||
sources, the value associated with the last source will take precedence.
|
sources, the value associated with the last source will take precedence.
|
||||||
Values defined by an Env with a duplicate key will take precedence.
|
Values defined by an Env with a duplicate key will take precedence.
|
||||||
Cannot be updated.
|
Cannot be updated.
|
||||||
items:
|
items:
|
||||||
description: EnvFromSource represents the source of a
|
description: EnvFromSource represents the source of a
|
||||||
set of ConfigMaps
|
set of ConfigMaps or Secrets
|
||||||
properties:
|
properties:
|
||||||
configMapRef:
|
configMapRef:
|
||||||
description: The ConfigMap to select from
|
description: The ConfigMap to select from
|
||||||
@@ -1251,8 +1281,9 @@ spec:
|
|||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
prefix:
|
prefix:
|
||||||
description: An optional identifier to prepend to
|
description: |-
|
||||||
each key in the ConfigMap. Must be a C_IDENTIFIER.
|
Optional text to prepend to the name of each environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
secretRef:
|
secretRef:
|
||||||
description: The Secret to select from
|
description: The Secret to select from
|
||||||
@@ -1516,6 +1547,12 @@ spec:
|
|||||||
- port
|
- port
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
|
stopSignal:
|
||||||
|
description: |-
|
||||||
|
StopSignal defines which signal will be sent to a container when it is being stopped.
|
||||||
|
If not specified, the default is defined by the container runtime in use.
|
||||||
|
StopSignal can only be set for Pods with a non-empty .spec.os.name
|
||||||
|
type: string
|
||||||
type: object
|
type: object
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -1923,7 +1960,7 @@ spec:
|
|||||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
that are used by this container.
|
that are used by this container.
|
||||||
|
|
||||||
This is an alpha field and requires enabling the
|
This field depends on the
|
||||||
DynamicResourceAllocation feature gate.
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
This field is immutable. It can only be set for containers.
|
This field is immutable. It can only be set for containers.
|
||||||
@@ -1978,10 +2015,10 @@ spec:
|
|||||||
restartPolicy:
|
restartPolicy:
|
||||||
description: |-
|
description: |-
|
||||||
RestartPolicy defines the restart behavior of individual containers in a pod.
|
RestartPolicy defines the restart behavior of individual containers in a pod.
|
||||||
This field may only be set for init containers, and the only allowed value is "Always".
|
This overrides the pod-level restart policy. When this field is not specified,
|
||||||
For non-init containers or when this field is not specified,
|
|
||||||
the restart behavior is defined by the Pod's restart policy and the container type.
|
the restart behavior is defined by the Pod's restart policy and the container type.
|
||||||
Setting the RestartPolicy as "Always" for the init container will have the following effect:
|
Additionally, setting the RestartPolicy as "Always" for the init container will
|
||||||
|
have the following effect:
|
||||||
this init container will be continually restarted on
|
this init container will be continually restarted on
|
||||||
exit until all regular containers have terminated. Once all regular
|
exit until all regular containers have terminated. Once all regular
|
||||||
containers have completed, all init containers with restartPolicy "Always"
|
containers have completed, all init containers with restartPolicy "Always"
|
||||||
@@ -1993,6 +2030,59 @@ spec:
|
|||||||
init container is started, or after any startupProbe has successfully
|
init container is started, or after any startupProbe has successfully
|
||||||
completed.
|
completed.
|
||||||
type: string
|
type: string
|
||||||
|
restartPolicyRules:
|
||||||
|
description: |-
|
||||||
|
Represents a list of rules to be checked to determine if the
|
||||||
|
container should be restarted on exit. The rules are evaluated in
|
||||||
|
order. Once a rule matches a container exit condition, the remaining
|
||||||
|
rules are ignored. If no rule matches the container exit condition,
|
||||||
|
the Container-level restart policy determines the whether the container
|
||||||
|
is restarted or not. Constraints on the rules:
|
||||||
|
- At most 20 rules are allowed.
|
||||||
|
- Rules can have the same action.
|
||||||
|
- Identical rules are not forbidden in validations.
|
||||||
|
When rules are specified, container MUST set RestartPolicy explicitly
|
||||||
|
even it if matches the Pod's RestartPolicy.
|
||||||
|
items:
|
||||||
|
description: ContainerRestartRule describes how a container
|
||||||
|
exit is handled.
|
||||||
|
properties:
|
||||||
|
action:
|
||||||
|
description: |-
|
||||||
|
Specifies the action taken on a container exit if the requirements
|
||||||
|
are satisfied. The only possible value is "Restart" to restart the
|
||||||
|
container.
|
||||||
|
type: string
|
||||||
|
exitCodes:
|
||||||
|
description: Represents the exit codes to check on
|
||||||
|
container exits.
|
||||||
|
properties:
|
||||||
|
operator:
|
||||||
|
description: |-
|
||||||
|
Represents the relationship between the container exit code(s) and the
|
||||||
|
specified values. Possible values are:
|
||||||
|
- In: the requirement is satisfied if the container exit code is in the
|
||||||
|
set of specified values.
|
||||||
|
- NotIn: the requirement is satisfied if the container exit code is
|
||||||
|
not in the set of specified values.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: |-
|
||||||
|
Specifies the set of values to check for container exit codes.
|
||||||
|
At most 255 elements are allowed.
|
||||||
|
items:
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: set
|
||||||
|
required:
|
||||||
|
- operator
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- action
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: atomic
|
||||||
securityContext:
|
securityContext:
|
||||||
description: |-
|
description: |-
|
||||||
SecurityContext defines the security options the container should be run with.
|
SecurityContext defines the security options the container should be run with.
|
||||||
@@ -2611,8 +2701,9 @@ spec:
|
|||||||
present in a Container.
|
present in a Container.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
description: Name of the environment variable. Must
|
description: |-
|
||||||
be a C_IDENTIFIER.
|
Name of the environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
value:
|
value:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -2670,6 +2761,43 @@ spec:
|
|||||||
- fieldPath
|
- fieldPath
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
|
fileKeyRef:
|
||||||
|
description: |-
|
||||||
|
FileKeyRef selects a key of the env file.
|
||||||
|
Requires the EnvFiles feature gate to be enabled.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key within the env file. An invalid key will prevent the pod from starting.
|
||||||
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
|
During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters.
|
||||||
|
type: string
|
||||||
|
optional:
|
||||||
|
default: false
|
||||||
|
description: |-
|
||||||
|
Specify whether the file or its key must be defined. If the file or key
|
||||||
|
does not exist, then the env var is not published.
|
||||||
|
If optional is set to true and the specified key does not exist,
|
||||||
|
the environment variable will not be set in the Pod's containers.
|
||||||
|
|
||||||
|
If optional is set to false and the specified key does not exist,
|
||||||
|
an error will be returned during Pod creation.
|
||||||
|
type: boolean
|
||||||
|
path:
|
||||||
|
description: |-
|
||||||
|
The path within the volume from which to select the file.
|
||||||
|
Must be relative and may not contain the '..' path or start with '..'.
|
||||||
|
type: string
|
||||||
|
volumeName:
|
||||||
|
description: The name of the volume mount
|
||||||
|
containing the env file.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- key
|
||||||
|
- path
|
||||||
|
- volumeName
|
||||||
|
type: object
|
||||||
|
x-kubernetes-map-type: atomic
|
||||||
resourceFieldRef:
|
resourceFieldRef:
|
||||||
description: |-
|
description: |-
|
||||||
Selects a resource of the container: only resources limits and requests
|
Selects a resource of the container: only resources limits and requests
|
||||||
@@ -2730,14 +2858,14 @@ spec:
|
|||||||
envFrom:
|
envFrom:
|
||||||
description: |-
|
description: |-
|
||||||
List of sources to populate environment variables in the container.
|
List of sources to populate environment variables in the container.
|
||||||
The keys defined within a source must be a C_IDENTIFIER. All invalid keys
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
will be reported as an event when the container is starting. When a key exists in multiple
|
When a key exists in multiple
|
||||||
sources, the value associated with the last source will take precedence.
|
sources, the value associated with the last source will take precedence.
|
||||||
Values defined by an Env with a duplicate key will take precedence.
|
Values defined by an Env with a duplicate key will take precedence.
|
||||||
Cannot be updated.
|
Cannot be updated.
|
||||||
items:
|
items:
|
||||||
description: EnvFromSource represents the source of a
|
description: EnvFromSource represents the source of a
|
||||||
set of ConfigMaps
|
set of ConfigMaps or Secrets
|
||||||
properties:
|
properties:
|
||||||
configMapRef:
|
configMapRef:
|
||||||
description: The ConfigMap to select from
|
description: The ConfigMap to select from
|
||||||
@@ -2758,8 +2886,9 @@ spec:
|
|||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
prefix:
|
prefix:
|
||||||
description: An optional identifier to prepend to
|
description: |-
|
||||||
each key in the ConfigMap. Must be a C_IDENTIFIER.
|
Optional text to prepend to the name of each environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
secretRef:
|
secretRef:
|
||||||
description: The Secret to select from
|
description: The Secret to select from
|
||||||
@@ -3019,6 +3148,12 @@ spec:
|
|||||||
- port
|
- port
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
|
stopSignal:
|
||||||
|
description: |-
|
||||||
|
StopSignal defines which signal will be sent to a container when it is being stopped.
|
||||||
|
If not specified, the default is defined by the container runtime in use.
|
||||||
|
StopSignal can only be set for Pods with a non-empty .spec.os.name
|
||||||
|
type: string
|
||||||
type: object
|
type: object
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
description: Probes are not allowed for ephemeral containers.
|
description: Probes are not allowed for ephemeral containers.
|
||||||
@@ -3409,7 +3544,7 @@ spec:
|
|||||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
that are used by this container.
|
that are used by this container.
|
||||||
|
|
||||||
This is an alpha field and requires enabling the
|
This field depends on the
|
||||||
DynamicResourceAllocation feature gate.
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
This field is immutable. It can only be set for containers.
|
This field is immutable. It can only be set for containers.
|
||||||
@@ -3465,9 +3600,53 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
Restart policy for the container to manage the restart behavior of each
|
Restart policy for the container to manage the restart behavior of each
|
||||||
container within a pod.
|
container within a pod.
|
||||||
This may only be set for init containers. You cannot set this field on
|
You cannot set this field on ephemeral containers.
|
||||||
ephemeral containers.
|
|
||||||
type: string
|
type: string
|
||||||
|
restartPolicyRules:
|
||||||
|
description: |-
|
||||||
|
Represents a list of rules to be checked to determine if the
|
||||||
|
container should be restarted on exit. You cannot set this field on
|
||||||
|
ephemeral containers.
|
||||||
|
items:
|
||||||
|
description: ContainerRestartRule describes how a container
|
||||||
|
exit is handled.
|
||||||
|
properties:
|
||||||
|
action:
|
||||||
|
description: |-
|
||||||
|
Specifies the action taken on a container exit if the requirements
|
||||||
|
are satisfied. The only possible value is "Restart" to restart the
|
||||||
|
container.
|
||||||
|
type: string
|
||||||
|
exitCodes:
|
||||||
|
description: Represents the exit codes to check on
|
||||||
|
container exits.
|
||||||
|
properties:
|
||||||
|
operator:
|
||||||
|
description: |-
|
||||||
|
Represents the relationship between the container exit code(s) and the
|
||||||
|
specified values. Possible values are:
|
||||||
|
- In: the requirement is satisfied if the container exit code is in the
|
||||||
|
set of specified values.
|
||||||
|
- NotIn: the requirement is satisfied if the container exit code is
|
||||||
|
not in the set of specified values.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: |-
|
||||||
|
Specifies the set of values to check for container exit codes.
|
||||||
|
At most 255 elements are allowed.
|
||||||
|
items:
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: set
|
||||||
|
required:
|
||||||
|
- operator
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- action
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: atomic
|
||||||
securityContext:
|
securityContext:
|
||||||
description: |-
|
description: |-
|
||||||
Optional: SecurityContext defines the security options the ephemeral container should be run with.
|
Optional: SecurityContext defines the security options the ephemeral container should be run with.
|
||||||
@@ -4005,7 +4184,9 @@ spec:
|
|||||||
hostNetwork:
|
hostNetwork:
|
||||||
description: |-
|
description: |-
|
||||||
Host networking requested for this pod. Use the host's network namespace.
|
Host networking requested for this pod. Use the host's network namespace.
|
||||||
If this option is set, the ports that will be used must be specified.
|
When using HostNetwork you should specify ports so the scheduler is aware.
|
||||||
|
When `hostNetwork` is true, specified `hostPort` fields in port definitions must match `containerPort`,
|
||||||
|
and unspecified `hostPort` fields in port definitions are defaulted to match `containerPort`.
|
||||||
Default to false.
|
Default to false.
|
||||||
type: boolean
|
type: boolean
|
||||||
hostPID:
|
hostPID:
|
||||||
@@ -4030,6 +4211,19 @@ spec:
|
|||||||
Specifies the hostname of the Pod
|
Specifies the hostname of the Pod
|
||||||
If not specified, the pod's hostname will be set to a system-defined value.
|
If not specified, the pod's hostname will be set to a system-defined value.
|
||||||
type: string
|
type: string
|
||||||
|
hostnameOverride:
|
||||||
|
description: |-
|
||||||
|
HostnameOverride specifies an explicit override for the pod's hostname as perceived by the pod.
|
||||||
|
This field only specifies the pod's hostname and does not affect its DNS records.
|
||||||
|
When this field is set to a non-empty string:
|
||||||
|
- It takes precedence over the values set in `hostname` and `subdomain`.
|
||||||
|
- The Pod's hostname will be set to this value.
|
||||||
|
- `setHostnameAsFQDN` must be nil or set to false.
|
||||||
|
- `hostNetwork` must be set to false.
|
||||||
|
|
||||||
|
This field must be a valid DNS subdomain as defined in RFC 1123 and contain at most 64 characters.
|
||||||
|
Requires the HostnameOverride feature gate to be enabled.
|
||||||
|
type: string
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
description: |-
|
description: |-
|
||||||
ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
|
ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
|
||||||
@@ -4065,7 +4259,7 @@ spec:
|
|||||||
Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes.
|
Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes.
|
||||||
The resourceRequirements of an init container are taken into account during scheduling
|
The resourceRequirements of an init container are taken into account during scheduling
|
||||||
by finding the highest request/limit for each resource type, and then using the max of
|
by finding the highest request/limit for each resource type, and then using the max of
|
||||||
of that value or the sum of the normal containers. Limits are applied to init containers
|
that value or the sum of the normal containers. Limits are applied to init containers
|
||||||
in a similar fashion.
|
in a similar fashion.
|
||||||
Init containers cannot currently be added or removed.
|
Init containers cannot currently be added or removed.
|
||||||
Cannot be updated.
|
Cannot be updated.
|
||||||
@@ -4111,8 +4305,9 @@ spec:
|
|||||||
present in a Container.
|
present in a Container.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
description: Name of the environment variable. Must
|
description: |-
|
||||||
be a C_IDENTIFIER.
|
Name of the environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
value:
|
value:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -4170,6 +4365,43 @@ spec:
|
|||||||
- fieldPath
|
- fieldPath
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
|
fileKeyRef:
|
||||||
|
description: |-
|
||||||
|
FileKeyRef selects a key of the env file.
|
||||||
|
Requires the EnvFiles feature gate to be enabled.
|
||||||
|
properties:
|
||||||
|
key:
|
||||||
|
description: |-
|
||||||
|
The key within the env file. An invalid key will prevent the pod from starting.
|
||||||
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
|
During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters.
|
||||||
|
type: string
|
||||||
|
optional:
|
||||||
|
default: false
|
||||||
|
description: |-
|
||||||
|
Specify whether the file or its key must be defined. If the file or key
|
||||||
|
does not exist, then the env var is not published.
|
||||||
|
If optional is set to true and the specified key does not exist,
|
||||||
|
the environment variable will not be set in the Pod's containers.
|
||||||
|
|
||||||
|
If optional is set to false and the specified key does not exist,
|
||||||
|
an error will be returned during Pod creation.
|
||||||
|
type: boolean
|
||||||
|
path:
|
||||||
|
description: |-
|
||||||
|
The path within the volume from which to select the file.
|
||||||
|
Must be relative and may not contain the '..' path or start with '..'.
|
||||||
|
type: string
|
||||||
|
volumeName:
|
||||||
|
description: The name of the volume mount
|
||||||
|
containing the env file.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- key
|
||||||
|
- path
|
||||||
|
- volumeName
|
||||||
|
type: object
|
||||||
|
x-kubernetes-map-type: atomic
|
||||||
resourceFieldRef:
|
resourceFieldRef:
|
||||||
description: |-
|
description: |-
|
||||||
Selects a resource of the container: only resources limits and requests
|
Selects a resource of the container: only resources limits and requests
|
||||||
@@ -4230,14 +4462,14 @@ spec:
|
|||||||
envFrom:
|
envFrom:
|
||||||
description: |-
|
description: |-
|
||||||
List of sources to populate environment variables in the container.
|
List of sources to populate environment variables in the container.
|
||||||
The keys defined within a source must be a C_IDENTIFIER. All invalid keys
|
The keys defined within a source may consist of any printable ASCII characters except '='.
|
||||||
will be reported as an event when the container is starting. When a key exists in multiple
|
When a key exists in multiple
|
||||||
sources, the value associated with the last source will take precedence.
|
sources, the value associated with the last source will take precedence.
|
||||||
Values defined by an Env with a duplicate key will take precedence.
|
Values defined by an Env with a duplicate key will take precedence.
|
||||||
Cannot be updated.
|
Cannot be updated.
|
||||||
items:
|
items:
|
||||||
description: EnvFromSource represents the source of a
|
description: EnvFromSource represents the source of a
|
||||||
set of ConfigMaps
|
set of ConfigMaps or Secrets
|
||||||
properties:
|
properties:
|
||||||
configMapRef:
|
configMapRef:
|
||||||
description: The ConfigMap to select from
|
description: The ConfigMap to select from
|
||||||
@@ -4258,8 +4490,9 @@ spec:
|
|||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
prefix:
|
prefix:
|
||||||
description: An optional identifier to prepend to
|
description: |-
|
||||||
each key in the ConfigMap. Must be a C_IDENTIFIER.
|
Optional text to prepend to the name of each environment variable.
|
||||||
|
May consist of any printable ASCII characters except '='.
|
||||||
type: string
|
type: string
|
||||||
secretRef:
|
secretRef:
|
||||||
description: The Secret to select from
|
description: The Secret to select from
|
||||||
@@ -4523,6 +4756,12 @@ spec:
|
|||||||
- port
|
- port
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
|
stopSignal:
|
||||||
|
description: |-
|
||||||
|
StopSignal defines which signal will be sent to a container when it is being stopped.
|
||||||
|
If not specified, the default is defined by the container runtime in use.
|
||||||
|
StopSignal can only be set for Pods with a non-empty .spec.os.name
|
||||||
|
type: string
|
||||||
type: object
|
type: object
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -4930,7 +5169,7 @@ spec:
|
|||||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
that are used by this container.
|
that are used by this container.
|
||||||
|
|
||||||
This is an alpha field and requires enabling the
|
This field depends on the
|
||||||
DynamicResourceAllocation feature gate.
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
This field is immutable. It can only be set for containers.
|
This field is immutable. It can only be set for containers.
|
||||||
@@ -4985,10 +5224,10 @@ spec:
|
|||||||
restartPolicy:
|
restartPolicy:
|
||||||
description: |-
|
description: |-
|
||||||
RestartPolicy defines the restart behavior of individual containers in a pod.
|
RestartPolicy defines the restart behavior of individual containers in a pod.
|
||||||
This field may only be set for init containers, and the only allowed value is "Always".
|
This overrides the pod-level restart policy. When this field is not specified,
|
||||||
For non-init containers or when this field is not specified,
|
|
||||||
the restart behavior is defined by the Pod's restart policy and the container type.
|
the restart behavior is defined by the Pod's restart policy and the container type.
|
||||||
Setting the RestartPolicy as "Always" for the init container will have the following effect:
|
Additionally, setting the RestartPolicy as "Always" for the init container will
|
||||||
|
have the following effect:
|
||||||
this init container will be continually restarted on
|
this init container will be continually restarted on
|
||||||
exit until all regular containers have terminated. Once all regular
|
exit until all regular containers have terminated. Once all regular
|
||||||
containers have completed, all init containers with restartPolicy "Always"
|
containers have completed, all init containers with restartPolicy "Always"
|
||||||
@@ -5000,6 +5239,59 @@ spec:
|
|||||||
init container is started, or after any startupProbe has successfully
|
init container is started, or after any startupProbe has successfully
|
||||||
completed.
|
completed.
|
||||||
type: string
|
type: string
|
||||||
|
restartPolicyRules:
|
||||||
|
description: |-
|
||||||
|
Represents a list of rules to be checked to determine if the
|
||||||
|
container should be restarted on exit. The rules are evaluated in
|
||||||
|
order. Once a rule matches a container exit condition, the remaining
|
||||||
|
rules are ignored. If no rule matches the container exit condition,
|
||||||
|
the Container-level restart policy determines the whether the container
|
||||||
|
is restarted or not. Constraints on the rules:
|
||||||
|
- At most 20 rules are allowed.
|
||||||
|
- Rules can have the same action.
|
||||||
|
- Identical rules are not forbidden in validations.
|
||||||
|
When rules are specified, container MUST set RestartPolicy explicitly
|
||||||
|
even it if matches the Pod's RestartPolicy.
|
||||||
|
items:
|
||||||
|
description: ContainerRestartRule describes how a container
|
||||||
|
exit is handled.
|
||||||
|
properties:
|
||||||
|
action:
|
||||||
|
description: |-
|
||||||
|
Specifies the action taken on a container exit if the requirements
|
||||||
|
are satisfied. The only possible value is "Restart" to restart the
|
||||||
|
container.
|
||||||
|
type: string
|
||||||
|
exitCodes:
|
||||||
|
description: Represents the exit codes to check on
|
||||||
|
container exits.
|
||||||
|
properties:
|
||||||
|
operator:
|
||||||
|
description: |-
|
||||||
|
Represents the relationship between the container exit code(s) and the
|
||||||
|
specified values. Possible values are:
|
||||||
|
- In: the requirement is satisfied if the container exit code is in the
|
||||||
|
set of specified values.
|
||||||
|
- NotIn: the requirement is satisfied if the container exit code is
|
||||||
|
not in the set of specified values.
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
description: |-
|
||||||
|
Specifies the set of values to check for container exit codes.
|
||||||
|
At most 255 elements are allowed.
|
||||||
|
items:
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: set
|
||||||
|
required:
|
||||||
|
- operator
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- action
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: atomic
|
||||||
securityContext:
|
securityContext:
|
||||||
description: |-
|
description: |-
|
||||||
SecurityContext defines the security options the container should be run with.
|
SecurityContext defines the security options the container should be run with.
|
||||||
@@ -5532,6 +5824,7 @@ spec:
|
|||||||
- spec.hostPID
|
- spec.hostPID
|
||||||
- spec.hostIPC
|
- spec.hostIPC
|
||||||
- spec.hostUsers
|
- spec.hostUsers
|
||||||
|
- spec.resources
|
||||||
- spec.securityContext.appArmorProfile
|
- spec.securityContext.appArmorProfile
|
||||||
- spec.securityContext.seLinuxOptions
|
- spec.securityContext.seLinuxOptions
|
||||||
- spec.securityContext.seccompProfile
|
- spec.securityContext.seccompProfile
|
||||||
@@ -5685,7 +5978,7 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
Resources is the total amount of CPU and Memory resources required by all
|
Resources is the total amount of CPU and Memory resources required by all
|
||||||
containers in the pod. It supports specifying Requests and Limits for
|
containers in the pod. It supports specifying Requests and Limits for
|
||||||
"cpu" and "memory" resource names only. ResourceClaims are not supported.
|
"cpu", "memory" and "hugepages-" resource names only. ResourceClaims are not supported.
|
||||||
|
|
||||||
This field enables fine-grained control over resource allocation for the
|
This field enables fine-grained control over resource allocation for the
|
||||||
entire pod, allowing resource sharing among containers in a pod.
|
entire pod, allowing resource sharing among containers in a pod.
|
||||||
@@ -5698,7 +5991,7 @@ spec:
|
|||||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
that are used by this container.
|
that are used by this container.
|
||||||
|
|
||||||
This is an alpha field and requires enabling the
|
This field depends on the
|
||||||
DynamicResourceAllocation feature gate.
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
This field is immutable. It can only be set for containers.
|
This field is immutable. It can only be set for containers.
|
||||||
@@ -6235,7 +6528,6 @@ spec:
|
|||||||
- Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.
|
- Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.
|
||||||
|
|
||||||
If this value is nil, the behavior is equivalent to the Honor policy.
|
If this value is nil, the behavior is equivalent to the Honor policy.
|
||||||
This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
|
|
||||||
type: string
|
type: string
|
||||||
nodeTaintsPolicy:
|
nodeTaintsPolicy:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -6246,7 +6538,6 @@ spec:
|
|||||||
- Ignore: node taints are ignored. All nodes are included.
|
- Ignore: node taints are ignored. All nodes are included.
|
||||||
|
|
||||||
If this value is nil, the behavior is equivalent to the Ignore policy.
|
If this value is nil, the behavior is equivalent to the Ignore policy.
|
||||||
This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.
|
|
||||||
type: string
|
type: string
|
||||||
topologyKey:
|
topologyKey:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -6971,15 +7262,13 @@ spec:
|
|||||||
volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
|
volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.
|
||||||
If specified, the CSI driver will create or update the volume with the attributes defined
|
If specified, the CSI driver will create or update the volume with the attributes defined
|
||||||
in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
|
in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,
|
||||||
it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass
|
it can be changed after the claim is created. An empty string or nil value indicates that no
|
||||||
will be applied to the claim but it's not allowed to reset this field to empty string once it is set.
|
VolumeAttributesClass will be applied to the claim. If the claim enters an Infeasible error state,
|
||||||
If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass
|
this field can be reset to its previous value (including nil) to cancel the modification.
|
||||||
will be set by the persistentvolume controller if it exists.
|
|
||||||
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
|
If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be
|
||||||
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
|
set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource
|
||||||
exists.
|
exists.
|
||||||
More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
|
More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/
|
||||||
(Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).
|
|
||||||
type: string
|
type: string
|
||||||
volumeMode:
|
volumeMode:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -7161,12 +7450,10 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.
|
glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.
|
||||||
Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported.
|
Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported.
|
||||||
More info: https://examples.k8s.io/volumes/glusterfs/README.md
|
|
||||||
properties:
|
properties:
|
||||||
endpoints:
|
endpoints:
|
||||||
description: |-
|
description: endpoints is the endpoint name that details
|
||||||
endpoints is the endpoint name that details Glusterfs topology.
|
Glusterfs topology.
|
||||||
More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod
|
|
||||||
type: string
|
type: string
|
||||||
path:
|
path:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -7220,7 +7507,7 @@ spec:
|
|||||||
The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field.
|
The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field.
|
||||||
The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images.
|
The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images.
|
||||||
The volume will be mounted read-only (ro) and non-executable files (noexec).
|
The volume will be mounted read-only (ro) and non-executable files (noexec).
|
||||||
Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath).
|
Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33.
|
||||||
The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.
|
The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.
|
||||||
properties:
|
properties:
|
||||||
pullPolicy:
|
pullPolicy:
|
||||||
@@ -7245,7 +7532,7 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
iscsi represents an ISCSI Disk resource that is attached to a
|
iscsi represents an ISCSI Disk resource that is attached to a
|
||||||
kubelet's host machine and then exposed to the pod.
|
kubelet's host machine and then exposed to the pod.
|
||||||
More info: https://examples.k8s.io/volumes/iscsi/README.md
|
More info: https://kubernetes.io/docs/concepts/storage/volumes/#iscsi
|
||||||
properties:
|
properties:
|
||||||
chapAuthDiscovery:
|
chapAuthDiscovery:
|
||||||
description: chapAuthDiscovery defines whether support
|
description: chapAuthDiscovery defines whether support
|
||||||
@@ -7667,6 +7954,111 @@ spec:
|
|||||||
type: array
|
type: array
|
||||||
x-kubernetes-list-type: atomic
|
x-kubernetes-list-type: atomic
|
||||||
type: object
|
type: object
|
||||||
|
podCertificate:
|
||||||
|
description: |-
|
||||||
|
Projects an auto-rotating credential bundle (private key and certificate
|
||||||
|
chain) that the pod can use either as a TLS client or server.
|
||||||
|
|
||||||
|
Kubelet generates a private key and uses it to send a
|
||||||
|
PodCertificateRequest to the named signer. Once the signer approves the
|
||||||
|
request and issues a certificate chain, Kubelet writes the key and
|
||||||
|
certificate chain to the pod filesystem. The pod does not start until
|
||||||
|
certificates have been issued for each podCertificate projected volume
|
||||||
|
source in its spec.
|
||||||
|
|
||||||
|
Kubelet will begin trying to rotate the certificate at the time indicated
|
||||||
|
by the signer using the PodCertificateRequest.Status.BeginRefreshAt
|
||||||
|
timestamp.
|
||||||
|
|
||||||
|
Kubelet can write a single file, indicated by the credentialBundlePath
|
||||||
|
field, or separate files, indicated by the keyPath and
|
||||||
|
certificateChainPath fields.
|
||||||
|
|
||||||
|
The credential bundle is a single file in PEM format. The first PEM
|
||||||
|
entry is the private key (in PKCS#8 format), and the remaining PEM
|
||||||
|
entries are the certificate chain issued by the signer (typically,
|
||||||
|
signers will return their certificate chain in leaf-to-root order).
|
||||||
|
|
||||||
|
Prefer using the credential bundle format, since your application code
|
||||||
|
can read it atomically. If you use keyPath and certificateChainPath,
|
||||||
|
your application must make two separate file reads. If these coincide
|
||||||
|
with a certificate rotation, it is possible that the private key and leaf
|
||||||
|
certificate you read may not correspond to each other. Your application
|
||||||
|
will need to check for this condition, and re-read until they are
|
||||||
|
consistent.
|
||||||
|
|
||||||
|
The named signer controls chooses the format of the certificate it
|
||||||
|
issues; consult the signer implementation's documentation to learn how to
|
||||||
|
use the certificates it issues.
|
||||||
|
properties:
|
||||||
|
certificateChainPath:
|
||||||
|
description: |-
|
||||||
|
Write the certificate chain at this path in the projected volume.
|
||||||
|
|
||||||
|
Most applications should use credentialBundlePath. When using keyPath
|
||||||
|
and certificateChainPath, your application needs to check that the key
|
||||||
|
and leaf certificate are consistent, because it is possible to read the
|
||||||
|
files mid-rotation.
|
||||||
|
type: string
|
||||||
|
credentialBundlePath:
|
||||||
|
description: |-
|
||||||
|
Write the credential bundle at this path in the projected volume.
|
||||||
|
|
||||||
|
The credential bundle is a single file that contains multiple PEM blocks.
|
||||||
|
The first PEM block is a PRIVATE KEY block, containing a PKCS#8 private
|
||||||
|
key.
|
||||||
|
|
||||||
|
The remaining blocks are CERTIFICATE blocks, containing the issued
|
||||||
|
certificate chain from the signer (leaf and any intermediates).
|
||||||
|
|
||||||
|
Using credentialBundlePath lets your Pod's application code make a single
|
||||||
|
atomic read that retrieves a consistent key and certificate chain. If you
|
||||||
|
project them to separate files, your application code will need to
|
||||||
|
additionally check that the leaf certificate was issued to the key.
|
||||||
|
type: string
|
||||||
|
keyPath:
|
||||||
|
description: |-
|
||||||
|
Write the key at this path in the projected volume.
|
||||||
|
|
||||||
|
Most applications should use credentialBundlePath. When using keyPath
|
||||||
|
and certificateChainPath, your application needs to check that the key
|
||||||
|
and leaf certificate are consistent, because it is possible to read the
|
||||||
|
files mid-rotation.
|
||||||
|
type: string
|
||||||
|
keyType:
|
||||||
|
description: |-
|
||||||
|
The type of keypair Kubelet will generate for the pod.
|
||||||
|
|
||||||
|
Valid values are "RSA3072", "RSA4096", "ECDSAP256", "ECDSAP384",
|
||||||
|
"ECDSAP521", and "ED25519".
|
||||||
|
type: string
|
||||||
|
maxExpirationSeconds:
|
||||||
|
description: |-
|
||||||
|
maxExpirationSeconds is the maximum lifetime permitted for the
|
||||||
|
certificate.
|
||||||
|
|
||||||
|
Kubelet copies this value verbatim into the PodCertificateRequests it
|
||||||
|
generates for this projection.
|
||||||
|
|
||||||
|
If omitted, kube-apiserver will set it to 86400(24 hours). kube-apiserver
|
||||||
|
will reject values shorter than 3600 (1 hour). The maximum allowable
|
||||||
|
value is 7862400 (91 days).
|
||||||
|
|
||||||
|
The signer implementation is then free to issue a certificate with any
|
||||||
|
lifetime *shorter* than MaxExpirationSeconds, but no shorter than 3600
|
||||||
|
seconds (1 hour). This constraint is enforced by kube-apiserver.
|
||||||
|
`kubernetes.io` signers will never issue certificates with a lifetime
|
||||||
|
longer than 24 hours.
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
signerName:
|
||||||
|
description: Kubelet's generated CSRs will
|
||||||
|
be addressed to this signer.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- keyType
|
||||||
|
- signerName
|
||||||
|
type: object
|
||||||
secret:
|
secret:
|
||||||
description: secret information about the secret
|
description: secret information about the secret
|
||||||
data to project
|
data to project
|
||||||
@@ -7801,7 +8193,6 @@ spec:
|
|||||||
description: |-
|
description: |-
|
||||||
rbd represents a Rados Block Device mount on the host that shares a pod's lifetime.
|
rbd represents a Rados Block Device mount on the host that shares a pod's lifetime.
|
||||||
Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported.
|
Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported.
|
||||||
More info: https://examples.k8s.io/volumes/rbd/README.md
|
|
||||||
properties:
|
properties:
|
||||||
fsType:
|
fsType:
|
||||||
description: |-
|
description: |-
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
|||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.1
|
controller-gen.kubebuilder.io/version: v0.17.2
|
||||||
name: packages.fission.io
|
name: packages.fission.io
|
||||||
spec:
|
spec:
|
||||||
group: fission.io
|
group: fission.io
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
|||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.1
|
controller-gen.kubebuilder.io/version: v0.17.2
|
||||||
name: timetriggers.fission.io
|
name: timetriggers.fission.io
|
||||||
spec:
|
spec:
|
||||||
group: fission.io
|
group: fission.io
|
||||||
|
|||||||
+12
-10
@@ -1,13 +1,15 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
commonLabels:
|
|
||||||
group: fission.io
|
|
||||||
resources:
|
resources:
|
||||||
- fission.io_canaryconfigs.yaml
|
- fission.io_canaryconfigs.yaml
|
||||||
- fission.io_environments.yaml
|
- fission.io_environments.yaml
|
||||||
- fission.io_functions.yaml
|
- fission.io_functions.yaml
|
||||||
- fission.io_httptriggers.yaml
|
- fission.io_httptriggers.yaml
|
||||||
- fission.io_kuberneteswatchtriggers.yaml
|
- fission.io_kuberneteswatchtriggers.yaml
|
||||||
- fission.io_messagequeuetriggers.yaml
|
- fission.io_messagequeuetriggers.yaml
|
||||||
- fission.io_packages.yaml
|
- fission.io_packages.yaml
|
||||||
- fission.io_timetriggers.yaml
|
- fission.io_timetriggers.yaml
|
||||||
|
labels:
|
||||||
|
- includeSelectors: true
|
||||||
|
pairs:
|
||||||
|
group: fission.io
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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 слоем с понятным жизненным циклом.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user