Compare commits
68
Commits
1.13.1
...
v1.15.0-rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50b5c74c52 | ||
|
|
23d6266335 | ||
|
|
4f8727f9d4 | ||
|
|
119d674207 | ||
|
|
1347d73b04 | ||
|
|
b55dc1fd78 | ||
|
|
1a52f3dce8 | ||
|
|
4a0bd1aa21 | ||
|
|
33473a4528 | ||
|
|
453debb6e9 | ||
|
|
81ccf6359d | ||
|
|
681e6f02fe | ||
|
|
5e226433b5 | ||
|
|
f4c56f81f3 | ||
|
|
ce85b27803 | ||
|
|
eb31381094 | ||
|
|
a1cbce810e | ||
|
|
f195975bda | ||
|
|
3636bb35ff | ||
|
|
1d5a09699b | ||
|
|
1df59316e7 | ||
|
|
d6b47c1a4e | ||
|
|
49fe2cb61f | ||
|
|
5f17b4f3c5 | ||
|
|
1b9d21b5e3 | ||
|
|
c51c6b7f7e | ||
|
|
0c8d7c26c5 | ||
|
|
c4585c8394 | ||
|
|
dfcf961f75 | ||
|
|
0cc3ecc2e9 | ||
|
|
a24934f1a0 | ||
|
|
9d54f5daac | ||
|
|
0f8b5e51a4 | ||
|
|
47295309b3 | ||
|
|
ba7ee3ed95 | ||
|
|
9b5eb069d6 | ||
|
|
672bdbba6f | ||
|
|
8271dfae07 | ||
|
|
f4702fe066 | ||
|
|
fea8dbef1a | ||
|
|
6a527d36a8 | ||
|
|
2292f472c9 | ||
|
|
2aaaeee5a7 | ||
|
|
ca161690da | ||
|
|
8bd1a71065 | ||
|
|
eb72fdc717 | ||
|
|
a7f819a78e | ||
|
|
d4d58e166b | ||
|
|
1d41a198cb | ||
|
|
6ced9d03d3 | ||
|
|
19c7616a4b | ||
|
|
a82281ad1c | ||
|
|
f3e1f9df90 | ||
|
|
c85b9e8cbc | ||
|
|
ece0475808 | ||
|
|
2e0bb9304a | ||
|
|
74c0142968 | ||
|
|
7c71d90d17 | ||
|
|
f86fde81e6 | ||
|
|
43814450e5 | ||
|
|
d5077ee816 | ||
|
|
2cf2c6979e | ||
|
|
154fe0d447 | ||
|
|
a493f0117d | ||
|
|
cc0400bdd4 | ||
|
|
8b57a035ee | ||
|
|
dc57f83d19 | ||
|
|
611f556cf9 |
@@ -6,11 +6,15 @@ on:
|
||||
- master
|
||||
paths:
|
||||
- '**.go'
|
||||
- go.mod
|
||||
- go.sum
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '**.go'
|
||||
- go.mod
|
||||
- go.sum
|
||||
schedule:
|
||||
- cron: "0 0 * * 0"
|
||||
workflow_dispatch:
|
||||
@@ -23,6 +27,13 @@ jobs:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
name: Greetings
|
||||
|
||||
on: [pull_request, issues]
|
||||
|
||||
jobs:
|
||||
greeting:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/first-interaction@v1
|
||||
if: env.month != 'Oct'
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-message: 'Thank you for your first issue! ✨😊'
|
||||
pr-message: 'Thank you for contributing to this project! ✨😊'
|
||||
- uses: actions/first-interaction@v1
|
||||
if: env.month == 'Oct'
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-message: 'Thank you for your first issue! Happy Hacktoberfest!!! ✨🎃👕✨'
|
||||
pr-message: 'Thank you for contributing to this project. Happy Hacktoberfest!!! ✨🎃👕'
|
||||
@@ -0,0 +1,71 @@
|
||||
name: Lint and Unit tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '**.go'
|
||||
- go.mod
|
||||
- go.sum
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '**.go'
|
||||
- go.mod
|
||||
- go.sum
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Verify dependencies
|
||||
run: |
|
||||
go mod verify
|
||||
go mod download
|
||||
|
||||
LINT_VERSION=1.42.0
|
||||
curl -fsSL https://github.com/golangci/golangci-lint/releases/download/v${LINT_VERSION}/golangci-lint-${LINT_VERSION}-linux-amd64.tar.gz | \
|
||||
tar xz --strip-components 1 --wildcards \*/golangci-lint
|
||||
mkdir -p bin && mv golangci-lint bin/
|
||||
|
||||
- name: Run checks
|
||||
run: |
|
||||
STATUS=0
|
||||
assert-nothing-changed() {
|
||||
local diff
|
||||
"$@" >/dev/null || return 1
|
||||
if ! diff="$(git diff -U1 --color --exit-code)"; then
|
||||
printf '\e[31mError: running `\e[1m%s\e[22m` results in modifications that you must check into version control:\e[0m\n%s\n\n' "$*" "$diff" >&2
|
||||
git checkout -- .
|
||||
STATUS=1
|
||||
fi
|
||||
}
|
||||
|
||||
assert-nothing-changed go fmt ./...
|
||||
assert-nothing-changed go mod tidy
|
||||
|
||||
bin/golangci-lint run --out-format=github-actions --timeout=5m || STATUS=$?
|
||||
|
||||
exit $STATUS
|
||||
|
||||
- name: Run unit tests
|
||||
run: ./hack/runtests.sh
|
||||
@@ -8,6 +8,8 @@ on:
|
||||
- '**.go'
|
||||
- 'charts/**'
|
||||
- 'test/**'
|
||||
- go.mod
|
||||
- go.sum
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
@@ -15,13 +17,25 @@ on:
|
||||
- '**.go'
|
||||
- 'charts/**'
|
||||
- 'test/**'
|
||||
- go.mod
|
||||
- go.sum
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
# Job to run change detection
|
||||
integration-test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
kindimage : [ 'kindest/node:v1.19.11','kindest/node:v1.20.7', 'kindest/node:v1.21.1' ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2.3.4
|
||||
|
||||
@@ -31,10 +45,12 @@ jobs:
|
||||
repository: fission/examples
|
||||
path: examples
|
||||
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v2.1.3
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
go-version: "1.15.12"
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Helm installation
|
||||
uses: Azure/setup-helm@v1
|
||||
@@ -44,24 +60,20 @@ jobs:
|
||||
- name: Kind Clutser
|
||||
uses: engineerd/setup-kind@v0.5.0
|
||||
with:
|
||||
image: ${{ matrix.kindimage }}
|
||||
version: v0.11.1
|
||||
config: kind.yaml
|
||||
|
||||
- name: Configuring and testing the Installation
|
||||
run: |
|
||||
kubectl cluster-info --context kind-kind
|
||||
kind get kubeconfig --internal >$HOME/.kube/config
|
||||
kubectl get nodes
|
||||
sudo apt-get install -y apache2-utils
|
||||
|
||||
- name: Static code analysis
|
||||
- name: Helm chart lint
|
||||
run: |
|
||||
./hack/verify-gofmt.sh
|
||||
./hack/verify-govet.sh
|
||||
helm lint charts/fission-all/ charts/fission-core/
|
||||
|
||||
- name: Run unit tests
|
||||
run: ./hack/runtests.sh
|
||||
|
||||
- name: Helm update
|
||||
run: helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
|
||||
|
||||
@@ -71,17 +83,22 @@ jobs:
|
||||
sudo install skaffold /usr/local/bin/
|
||||
skaffold version
|
||||
|
||||
- name: Install GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
install-only: true
|
||||
|
||||
- name: Build and Install Fission
|
||||
run: |
|
||||
kubectl create ns fission
|
||||
kubectl create -k crds/v1
|
||||
skaffold run -p kind-ci
|
||||
make create-crds
|
||||
SKAFFOLD_PROFILE=kind-ci make skaffold-deploy
|
||||
|
||||
- name: Build and Install Fission CLI
|
||||
run: |
|
||||
go build -o fission cmd/fission-cli/main.go
|
||||
sudo mv fission /usr/local/bin
|
||||
fission version
|
||||
make build-fission-cli
|
||||
sudo make install-fission-cli
|
||||
sudo chmod +x /usr/local/bin/fission
|
||||
|
||||
- name: Port-forward fission components
|
||||
run: |
|
||||
@@ -89,18 +106,22 @@ jobs:
|
||||
kubectl port-forward svc/controller 8889:80 -nfission &
|
||||
kubectl port-forward svc/nats-streaming 8890:4222 -nfission &
|
||||
|
||||
- name: Get fission version
|
||||
run: |
|
||||
fission version
|
||||
|
||||
- name: Integration tests
|
||||
run: ./test/kind_CI.sh
|
||||
|
||||
- name: Collect Fission Dump
|
||||
if: ${{ failure() }}
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
fission support dump
|
||||
command -v fission && fission support dump
|
||||
|
||||
- name: Archive fission dump
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: fission-support-dump
|
||||
name: fission-dump
|
||||
path: fission-dump/*.zip
|
||||
retention-days: 5
|
||||
retention-days: 5
|
||||
@@ -8,6 +8,8 @@ on:
|
||||
- '**.go'
|
||||
- 'charts/**'
|
||||
- 'test/**'
|
||||
- go.mod
|
||||
- go.sum
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
@@ -15,19 +17,33 @@ on:
|
||||
- '**.go'
|
||||
- 'charts/**'
|
||||
- 'test/**'
|
||||
- go.mod
|
||||
- go.sum
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
upgrade-test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
kindimage : [ 'kindest/node:v1.19.11' ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
|
||||
- name: Checkout action sources
|
||||
uses: actions/checkout@v2.3.4
|
||||
|
||||
- name: Setup go
|
||||
uses: actions/setup-go@v2.1.3
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
go-version: '1.15.12'
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Setup Helm
|
||||
uses: Azure/setup-helm@v1
|
||||
@@ -37,13 +53,19 @@ jobs:
|
||||
- name: Setup Kind Clutser
|
||||
uses: engineerd/setup-kind@v0.5.0
|
||||
with:
|
||||
config: kind.yaml
|
||||
image: ${{ matrix.kindimage }}
|
||||
version: v0.11.1
|
||||
|
||||
- name: Install GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
install-only: true
|
||||
|
||||
- name: Setup kubectl & fetch node information
|
||||
run: |
|
||||
kubectl cluster-info --context kind-kind
|
||||
kind get kubeconfig --internal >$HOME/.kube/config
|
||||
kubectl get nodes
|
||||
kubectl get storageclasses.storage.k8s.io
|
||||
|
||||
- name: Dump system info
|
||||
run: |
|
||||
@@ -64,4 +86,17 @@ jobs:
|
||||
|
||||
- name: Test previously created fission objects with new release
|
||||
run: |
|
||||
source ./test/upgrade_test/fission_objects.sh test_fission_objects
|
||||
source ./test/upgrade_test/fission_objects.sh test_fission_objects
|
||||
|
||||
- name: Collect Fission Dump
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
command -v fission && fission support dump
|
||||
|
||||
- name: Archive fission dump
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: fission-dump
|
||||
path: fission-dump/*.zip
|
||||
retention-days: 5
|
||||
@@ -31,3 +31,5 @@ vendor/
|
||||
local/
|
||||
|
||||
build/
|
||||
dist/
|
||||
manifest/
|
||||
|
||||
+32
-1
@@ -1,7 +1,38 @@
|
||||
linters:
|
||||
enable:
|
||||
# Default linter
|
||||
- deadcode
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
- unused
|
||||
- varcheck
|
||||
# Additional linters
|
||||
- gofmt
|
||||
- goimports
|
||||
- misspell
|
||||
- nakedret
|
||||
- unconvert
|
||||
# Enable in future
|
||||
# - bodyclose
|
||||
# - dogsled
|
||||
# - dupl
|
||||
# - gosec
|
||||
# - ifshort
|
||||
# - nilerr
|
||||
# - prealloc
|
||||
# - revive
|
||||
# - unparam
|
||||
# - wrapcheck
|
||||
# - gocritic
|
||||
linters-settings:
|
||||
errcheck:
|
||||
ignore: go.uber.org/zap:Sync
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: github.com/trussworks/my-cli-tool
|
||||
local-prefixes: github.com/fission/fission
|
||||
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
project_name: fission
|
||||
release:
|
||||
github:
|
||||
owner: fission
|
||||
name: fission
|
||||
prerelease: true
|
||||
draft: true
|
||||
header: |
|
||||
Release Highlights: https://docs.fission.io/docs/releases/{{ .Tag }}/
|
||||
Install Guide: https://docs.fission.io/installation/
|
||||
Full Changelog: https://github.com/fission/fission/blob/master/CHANGELOG.md
|
||||
extra_files:
|
||||
- glob: ./manifest/charts/*
|
||||
- glob: ./manifest/yamls/*
|
||||
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
snapshot:
|
||||
name_template: "{{ .Tag }}"
|
||||
builds:
|
||||
- &build-linux
|
||||
id: builder
|
||||
ldflags:
|
||||
- -s -w
|
||||
- -X github.com/fission/fission/pkg/info.GitCommit={{.ShortCommit}}
|
||||
- -X github.com/fission/fission/pkg/info.BuildDate={{.Date}}
|
||||
- -X github.com/fission/fission/pkg/info.Version={{.Tag}}
|
||||
gcflags:
|
||||
- all=-trimpath={{.Env.PWD}}
|
||||
asmflags:
|
||||
- all=-trimpath={{.Env.PWD}}
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
- arm
|
||||
goarm:
|
||||
- 7
|
||||
binary: builder
|
||||
dir: ./cmd/builder
|
||||
- <<: *build-linux
|
||||
id: fetcher
|
||||
binary: fetcher
|
||||
dir: ./cmd/fetcher
|
||||
- <<: *build-linux
|
||||
id: fission-bundle
|
||||
binary: fission-bundle
|
||||
dir: ./cmd/fission-bundle
|
||||
- <<: *build-linux
|
||||
id: fission-cli
|
||||
goos:
|
||||
- linux
|
||||
- windows
|
||||
- darwin
|
||||
binary: fission
|
||||
dir: ./cmd/fission-cli
|
||||
ignore:
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
- goos: darwin
|
||||
goarch: arm
|
||||
goarm: 7
|
||||
- goos: windows
|
||||
goarch: arm
|
||||
goarm: 7
|
||||
- <<: *build-linux
|
||||
id: pre-upgrade-checks
|
||||
binary: pre-upgrade-checks
|
||||
dir: ./cmd/preupgradechecks
|
||||
- <<: *build-linux
|
||||
id: reporter
|
||||
binary: reporter
|
||||
dir: ./cmd/reporter
|
||||
dockers:
|
||||
- &docker-amd64
|
||||
use: buildx
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
ids:
|
||||
- builder
|
||||
image_templates:
|
||||
- "fission/builder:latest-amd64"
|
||||
- "fission/builder:{{ .Tag }}-amd64"
|
||||
dockerfile: cmd/builder/Dockerfile.fission-builder
|
||||
build_flag_templates:
|
||||
- "--platform=linux/amd64"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Tag}}"
|
||||
- <<: *docker-amd64
|
||||
ids:
|
||||
- fetcher
|
||||
image_templates:
|
||||
- "fission/fetcher:latest-amd64"
|
||||
- "fission/fetcher:{{ .Tag }}-amd64"
|
||||
dockerfile: cmd/fetcher/Dockerfile.fission-fetcher
|
||||
- <<: *docker-amd64
|
||||
ids:
|
||||
- fission-bundle
|
||||
image_templates:
|
||||
- "fission/fission-bundle:latest-amd64"
|
||||
- "fission/fission-bundle:{{ .Tag }}-amd64"
|
||||
dockerfile: cmd/fission-bundle/Dockerfile.fission-bundle
|
||||
- <<: *docker-amd64
|
||||
ids:
|
||||
- pre-upgrade-checks
|
||||
image_templates:
|
||||
- "fission/pre-upgrade-checks:latest-amd64"
|
||||
- "fission/pre-upgrade-checks:{{ .Tag }}-amd64"
|
||||
dockerfile: cmd/preupgradechecks/Dockerfile.fission-preupgradechecks
|
||||
- <<: *docker-amd64
|
||||
ids:
|
||||
- reporter
|
||||
image_templates:
|
||||
- "fission/reporter:latest-amd64"
|
||||
- "fission/reporter:{{ .Tag }}-amd64"
|
||||
dockerfile: cmd/reporter/Dockerfile.reporter
|
||||
- &docker-arm64
|
||||
use: buildx
|
||||
goos: linux
|
||||
goarch: arm64
|
||||
ids:
|
||||
- builder
|
||||
image_templates:
|
||||
- "fission/builder:latest-arm64"
|
||||
- "fission/builder:{{ .Tag }}-arm64"
|
||||
dockerfile: cmd/builder/Dockerfile.fission-builder
|
||||
build_flag_templates:
|
||||
- "--platform=linux/arm64"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Tag}}"
|
||||
- <<: *docker-arm64
|
||||
ids:
|
||||
- fetcher
|
||||
image_templates:
|
||||
- "fission/fetcher:latest-arm64"
|
||||
- "fission/fetcher:{{ .Tag }}-arm64"
|
||||
dockerfile: cmd/fetcher/Dockerfile.fission-fetcher
|
||||
- <<: *docker-arm64
|
||||
ids:
|
||||
- fission-bundle
|
||||
image_templates:
|
||||
- "fission/fission-bundle:latest-arm64"
|
||||
- "fission/fission-bundle:{{ .Tag }}-arm64"
|
||||
dockerfile: cmd/fission-bundle/Dockerfile.fission-bundle
|
||||
- <<: *docker-arm64
|
||||
ids:
|
||||
- pre-upgrade-checks
|
||||
image_templates:
|
||||
- "fission/pre-upgrade-checks:latest-arm64"
|
||||
- "fission/pre-upgrade-checks:{{ .Tag }}-arm64"
|
||||
dockerfile: cmd/preupgradechecks/Dockerfile.fission-preupgradechecks
|
||||
- <<: *docker-arm64
|
||||
ids:
|
||||
- reporter
|
||||
image_templates:
|
||||
- "fission/reporter:latest-arm64"
|
||||
- "fission/reporter:{{ .Tag }}-arm64"
|
||||
dockerfile: cmd/reporter/Dockerfile.reporter
|
||||
- &docker-armv7
|
||||
use: buildx
|
||||
goos: linux
|
||||
goarch: arm
|
||||
goarm: 7
|
||||
ids:
|
||||
- builder
|
||||
image_templates:
|
||||
- "fission/builder:latest-armv7"
|
||||
- "fission/builder:{{ .Tag }}-armv7"
|
||||
dockerfile: cmd/builder/Dockerfile.fission-builder
|
||||
build_flag_templates:
|
||||
- "--platform=linux/arm/v7"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Tag}}"
|
||||
- <<: *docker-armv7
|
||||
ids:
|
||||
- fetcher
|
||||
image_templates:
|
||||
- "fission/fetcher:latest-armv7"
|
||||
- "fission/fetcher:{{ .Tag }}-armv7"
|
||||
dockerfile: cmd/fetcher/Dockerfile.fission-fetcher
|
||||
- <<: *docker-armv7
|
||||
ids:
|
||||
- fission-bundle
|
||||
image_templates:
|
||||
- "fission/fission-bundle:latest-armv7"
|
||||
- "fission/fission-bundle:{{ .Tag }}-armv7"
|
||||
dockerfile: cmd/fission-bundle/Dockerfile.fission-bundle
|
||||
- <<: *docker-armv7
|
||||
ids:
|
||||
- pre-upgrade-checks
|
||||
image_templates:
|
||||
- "fission/pre-upgrade-checks:latest-armv7"
|
||||
- "fission/pre-upgrade-checks:{{ .Tag }}-armv7"
|
||||
dockerfile: cmd/preupgradechecks/Dockerfile.fission-preupgradechecks
|
||||
- <<: *docker-armv7
|
||||
ids:
|
||||
- reporter
|
||||
image_templates:
|
||||
- "fission/reporter:latest-armv7"
|
||||
- "fission/reporter:{{ .Tag }}-armv7"
|
||||
dockerfile: cmd/reporter/Dockerfile.reporter
|
||||
docker_manifests:
|
||||
- name_template: fission/builder:{{ .Tag }}
|
||||
image_templates:
|
||||
- fission/builder:{{ .Tag }}-amd64
|
||||
- fission/builder:{{ .Tag }}-arm64
|
||||
- fission/builder:{{ .Tag }}-armv7
|
||||
- name_template: fission/fetcher:{{ .Tag }}
|
||||
image_templates:
|
||||
- fission/fetcher:{{ .Tag }}-amd64
|
||||
- fission/fetcher:{{ .Tag }}-arm64
|
||||
- fission/fetcher:{{ .Tag }}-armv7
|
||||
- name_template: fission/fission-bundle:{{ .Tag }}
|
||||
image_templates:
|
||||
- fission/fission-bundle:{{ .Tag }}-amd64
|
||||
- fission/fission-bundle:{{ .Tag }}-arm64
|
||||
- fission/fission-bundle:{{ .Tag }}-armv7
|
||||
- name_template: fission/pre-upgrade-checks:{{ .Tag }}
|
||||
image_templates:
|
||||
- fission/pre-upgrade-checks:{{ .Tag }}-amd64
|
||||
- fission/pre-upgrade-checks:{{ .Tag }}-arm64
|
||||
- fission/pre-upgrade-checks:{{ .Tag }}-armv7
|
||||
- name_template: fission/reporter:{{ .Tag }}
|
||||
image_templates:
|
||||
- fission/reporter:{{ .Tag }}-amd64
|
||||
- fission/reporter:{{ .Tag }}-arm64
|
||||
- fission/reporter:{{ .Tag }}-armv7
|
||||
changelog:
|
||||
skip: true
|
||||
archives:
|
||||
- id: fission
|
||||
builds:
|
||||
- fission-cli
|
||||
name_template: "{{ .ProjectName }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}"
|
||||
format: binary
|
||||
checksum:
|
||||
name_template: "checksums.txt"
|
||||
algorithm: sha256
|
||||
@@ -0,0 +1,13 @@
|
||||
pull_request_rules:
|
||||
- name: Automatic merge on approval
|
||||
conditions:
|
||||
- base=master
|
||||
- "#approved-reviews-by>=1"
|
||||
- label=ready-to-merge
|
||||
- label!=hold-off-merging
|
||||
- status-success=build
|
||||
actions:
|
||||
merge:
|
||||
method: squash
|
||||
commit_message: title+body
|
||||
strict: smart
|
||||
+345
-425
File diff suppressed because it is too large
Load Diff
+2
-231
@@ -5,235 +5,6 @@ There are many areas we can use contributions - ranging from code, documentation
|
||||
|
||||
First, please read the [code of conduct](CODE_OF_CONDUCT.md). By participating, you're expected to uphold this code.
|
||||
|
||||
Table of Contents
|
||||
=================
|
||||
Please refer contributing docs for detailed guide.
|
||||
|
||||
* [Choose something to work on](#choose-something-to-work-on)
|
||||
* [Get Help.](#get-help)
|
||||
* [Contributing - building & deploying](#contributing---building--deploying)
|
||||
* [Prerequisite](#prerequisite)
|
||||
* [Getting Started](#getting-started)
|
||||
* [Use Skaffold with Kind/K8S Cluster to build and deploy](#use-skaffold-with-kindk8s-cluster-to-build-and-deploy)
|
||||
* [Validating Installation](#validating-installation)
|
||||
* [Understanding code structure](#understanding-code-structure)
|
||||
* [cmd](#cmd)
|
||||
* [pkg](#pkg)
|
||||
* [Charts](#charts)
|
||||
* [Environments](#environments)
|
||||
|
||||
# Choose something to work on
|
||||
|
||||
* The easiest way to start is to look at existing [issues](https://github.com/fission/fission/issues) and see if there's something there that you'd like to work on. You can filter issues with label "[Good first issue](https://github.com/fission/fission/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)" which are relatively self sufficient issues and great for first time contributors.
|
||||
- If you are going to pick up an issue, it would be good to add a comment stating the intention.
|
||||
- If the contribution is a big change/new feature, please raise an issue and discuss the needs, design in the issue in detail.
|
||||
|
||||
* For contributing a new Fission environment, please check the [environments repo](https://github.com/fission/environments)
|
||||
|
||||
* For contributing a new Keda Connector, please check the [Keda Connectors repo](https://github.com/fission/keda-connectors)
|
||||
|
||||
|
||||
### Get Help.
|
||||
|
||||
Do reach out on Slack or Twitter and we are happy to help.
|
||||
|
||||
* Drop by the [slack channel](http://slack.fission.io).
|
||||
* Say hi on [twitter](https://twitter.com/fissionio).
|
||||
|
||||
|
||||
# Contributing - building & deploying
|
||||
|
||||
## Prerequisite
|
||||
|
||||
- You'll need the `go` compiler and tools installed. Currently version 1.12.x of Go is needed.
|
||||
|
||||
- You'll also need [docker](https://docs.docker.com/install) for building images locally.
|
||||
|
||||
- You will need a Kubernetes cluster and you can use one of options from below.
|
||||
- [Minikube](https://github.com/kubernetes/minikube)
|
||||
- [Kind](https://kind.sigs.k8s.io/)
|
||||
- Cluster in cloud such as GKE (Google Kubernetes Engine cluster)/ EKS (Elastic Kubernetes Service)/ AKS (Azure Kubernetes Service)
|
||||
|
||||
- Kubectl and Helm installed.
|
||||
|
||||
- [Skaffold](https://skaffold.dev/docs/install/) for local development workflow to make it easier to build and deploy Fission.
|
||||
|
||||
- And of course some basic concepts of Fission such as environment, function are good to be aware of!
|
||||
|
||||
## Getting Started
|
||||
|
||||
Get the code locally and after you have made changes - you can verify formatting and other basic checks.
|
||||
|
||||
```sh
|
||||
# Clone the repo
|
||||
$ git clone https://github.com/fission/fission.git $GOPATH/src/github.com/fission/fission
|
||||
$ cd $GOPATH/src/github.com/fission/fission
|
||||
|
||||
$ go mod vendor
|
||||
|
||||
# Run checks on your changes
|
||||
$ ./hack/verify-gofmt.sh
|
||||
$ ./hack/verify-govet.sh
|
||||
```
|
||||
|
||||
### Use Skaffold with Kind/K8S Cluster to build and deploy
|
||||
|
||||
You should bring up Kind/Minikube cluster or if using a cloud provider cluster then Kubecontext should be pointing to appropriate cluster.
|
||||
|
||||
* For building & deploying to Cloud Provider K8S cluster such as GKE/EKS/AKS:
|
||||
|
||||
```
|
||||
$ skaffold config set default-repo vishalbiyani // (vishalbiyani - should be your registry/Docker Hub handle)
|
||||
$ skaffold run
|
||||
```
|
||||
|
||||
* For building & deploying to Kind cluster use Kind profile
|
||||
```
|
||||
$ kind create cluster
|
||||
$ kubectl create ns fission
|
||||
$ skaffold run -p kind
|
||||
```
|
||||
|
||||
## Validating Installation
|
||||
|
||||
If you are using Helm, you should see release installed:
|
||||
|
||||
```
|
||||
helm list
|
||||
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
|
||||
fission fission 1 2020-05-19 16:31:46.947562 +0530 IST success fission-all-1.11.0 1.11.0
|
||||
```
|
||||
|
||||
Also you should see the Fission services deployed and running:
|
||||
|
||||
```
|
||||
$ kubectl get pods -n fission
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
buildermgr-6f778d4ff9-dqnq5 1/1 Running 0 6h9m
|
||||
controller-d44bd4f4d-5q4z5 1/1 Running 0 6h9m
|
||||
executor-557c68c6fd-dg8ld 1/1 Running 0 6h9m
|
||||
influxdb-845548c959-2954p 1/1 Running 0 6h9m
|
||||
kubewatcher-5784c454b8-5mqsk 1/1 Running 0 6h9m
|
||||
logger-bncqn 2/2 Running 0 6h9m
|
||||
mqtrigger-kafka-765b674ff-jk5x9 1/1 Running 0 6h9m
|
||||
mqtrigger-nats-streaming-797498966c-xgxmk 1/1 Running 3 6h9m
|
||||
nats-streaming-6bf48bccb6-fmmr9 1/1 Running 0 6h9m
|
||||
router-db76576bd-xxh7r 1/1 Running 0 6h9m
|
||||
storagesvc-799dcb5bdf-f69k9 1/1 Running 0 6h9m
|
||||
timer-7d85d9c9fb-knctw 1/1 Running 0 6h9m
|
||||
```
|
||||
|
||||
|
||||
## Understanding code structure
|
||||
|
||||
### cmd
|
||||
|
||||
`cmd` package is entry point for all runtime components and also has Dockerfile for each component. The actual logic here will be pretty light and most of logic of each component is in `pkg` (Discussed later)
|
||||
|
||||
| Component | Runtime Component |Used in|
|
||||
| :------------- |:------------- |:-|
|
||||
| fetcher | Docker Image |Environments|
|
||||
| fission-bundle | Docker Image |Binary for all components|
|
||||
| fission-cli | CLI Binary |CLI by user|
|
||||
| preupgradechecks | Docker Image |Pre-install upgrade|
|
||||
|
||||
```
|
||||
.
|
||||
cmd
|
||||
├── fetcher
|
||||
│ ├── Dockerfile.fission-fetcher
|
||||
│ ├── app
|
||||
│ └── main.go
|
||||
├── fission-bundle
|
||||
│ ├── Dockerfile.fission-bundle
|
||||
│ ├── main.go
|
||||
│ └── mqtrigger
|
||||
├── fission-cli
|
||||
│ ├── app
|
||||
│ ├── fission-cli
|
||||
│ └── main.go
|
||||
└── preupgradechecks
|
||||
├── Dockerfile.fission-preupgradechecks
|
||||
├── main.go
|
||||
└── preupgradechecks.go
|
||||
```
|
||||
|
||||
**fetcher** : is a very lightweight component and all of related logic is in fetcher package itself. Fetcher helps in fetching and uploading code and in specializing environments.
|
||||
|
||||
**fission-bundle** : is a component which is a single binary for all components. Based on arguments you pass to fission-bundle - it becomes that component. For ex.
|
||||
|
||||
```
|
||||
/fission-bundle --controllerPort "8888" # Runs Controller
|
||||
|
||||
/fission-bundle --kubewatcher --routerUrl http://router.fission # Runs Kubewatcher
|
||||
```
|
||||
|
||||
So most server side components running on server side are fission-bundle binary wrapped in container and used with different arguments. Various arguments and environment variables are passed from manifests/helm chart
|
||||
|
||||
**fission-cli** : is the cli used by end user to interact Fission
|
||||
|
||||
**preupgradechecks** : is again a small independent component to do pre-install upgrade tasks.
|
||||
|
||||
|
||||
### pkg
|
||||
|
||||
Pkg is where most of core components and logic reside. The structure is fairly self-explanatory for example all of executor related functionality will be in executor package and so on.
|
||||
|
||||
```
|
||||
.
|
||||
├── pkg
|
||||
│ ├── apis
|
||||
│ ├── builder
|
||||
│ ├── buildermgr
|
||||
│ ├── cache
|
||||
│ ├── canaryconfigmgr
|
||||
│ ├── controller
|
||||
│ ├── crd
|
||||
│ ├── error
|
||||
│ ├── executor
|
||||
│ ├── fetcher
|
||||
│ ├── fission-cli
|
||||
│ ├── generator
|
||||
│ ├── info
|
||||
│ ├── kubewatcher
|
||||
│ ├── logger
|
||||
│ ├── mqtrigger
|
||||
│ ├── plugin
|
||||
│ ├── publisher
|
||||
│ ├── router
|
||||
│ ├── storagesvc
|
||||
│ ├── throttler
|
||||
│ ├── timer
|
||||
│ └── utils
|
||||
```
|
||||
|
||||
### Charts
|
||||
|
||||
Fission currently has two charts - and we recommend using fission-all for development.
|
||||
|
||||
```
|
||||
.
|
||||
├── charts
|
||||
│ ├── README.md
|
||||
│ ├── fission-all
|
||||
│ └── fission-core
|
||||
```
|
||||
|
||||
### Environments
|
||||
|
||||
Each of runtime environments is in fission/environments repo and fairly independent. If you are enhancing or creating a new environment - most likely you will end up making changes in that repo.
|
||||
|
||||
```
|
||||
.
|
||||
├── environments
|
||||
│ ├── binary
|
||||
│ ├── dotnet
|
||||
│ ├── dotnet20
|
||||
│ ├── go
|
||||
│ ├── jvm
|
||||
│ ├── nodejs
|
||||
│ ├── perl
|
||||
│ ├── php7
|
||||
│ ├── python
|
||||
│ ├── ruby
|
||||
│ └── tensorflow-serving
|
||||
```
|
||||
[https://docs.fission.io/docs/contributing/](https://docs.fission.io/docs/contributing/)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# Profiling Fission with Pprof
|
||||
|
||||
Fission uses [net/pprof](https://pkg.go.dev/net/http/pprof) for profiling the code across Fission components.
|
||||
It would be helpful in identifying performance bottlenecks.
|
||||
|
||||
To enable profiling, just set `pprof.enabled` to `true` while installing Fission helm chart.
|
||||
|
||||
## Pprof data of component pod
|
||||
|
||||
Do port forwarding to port 6060 of the pod,
|
||||
|
||||
```sh
|
||||
kubectl port-forward pod/executor-668dfd7c89-2b2ff 6060:6060
|
||||
```
|
||||
|
||||
Run different commands to get or analyze pprof data,
|
||||
|
||||
```sh
|
||||
go tool pprof http://localhost:6060/debug/pprof/flamegraph
|
||||
|
||||
go tool pprof http://localhost:6060/debug/pprof/profile\?seconds\=60
|
||||
```
|
||||
|
||||
You can also analyze with binary to get correct references of source,
|
||||
|
||||
```sh
|
||||
# Download binary from pod
|
||||
kubectl cp fission/executor-668dfd7c89-2b2ff:/fission-bundle fission-bundle
|
||||
|
||||
go tool pprof -http ":49816" fission-bundle http://localhost:49513/debug/pprof
|
||||
```
|
||||
|
||||
You can also download pprof data and visualize/analyze with different compatible tools.
|
||||
@@ -14,33 +14,23 @@
|
||||
|
||||
.DEFAULT_GOAL := check
|
||||
|
||||
# Platforms to build in multi-architecture images.
|
||||
PLATFORMS ?= linux/amd64,linux/arm64,linux/arm/v7
|
||||
SKAFFOLD_PROFILE ?= kind
|
||||
|
||||
# Repository prefix and tag to push multi-architecture images to.
|
||||
REPO ?= fission
|
||||
TAG ?= dev
|
||||
DOCKER_FLAGS ?= --push --progress plain
|
||||
|
||||
VERSION ?= master
|
||||
VERSION ?= v0.0.0
|
||||
TIMESTAMP ?= $(shell date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
COMMITSHA ?= $(shell git rev-parse HEAD)
|
||||
|
||||
GOOS ?= $(shell go env GOOS)
|
||||
GOARCH ?= $(shell go env GOARCH)
|
||||
|
||||
BINDIR ?= build/bin
|
||||
FISSION-CLI-SUFFIX :=
|
||||
ifeq ($(GOOS), windows)
|
||||
FISSION-CLI-SUFFIX := .exe
|
||||
endif
|
||||
|
||||
GO ?= go
|
||||
GO_LDFLAGS := -X github.com/fission/fission/pkg/info.GitCommit=$(COMMITSHA) $(GO_LDFLAGS)
|
||||
GO_LDFLAGS := -X github.com/fission/fission/pkg/info.BuildDate=$(TIMESTAMP) $(GO_LDFLAGS)
|
||||
GO_LDFLAGS := -X github.com/fission/fission/pkg/info.Version=$(VERSION) $(GO_LDFLAGS)
|
||||
GCFLAGS ?= all=-trimpath=$(CURDIR)
|
||||
ASMFLAGS ?= all=-trimpath=$(CURDIR)
|
||||
# Show this help.
|
||||
help:
|
||||
@awk '/^#/{c=substr($$0,3);next}c&&/^[[:alpha:]][[:alnum:]_-]+:/{print substr($$1,1,index($$1,":")),c}1{c=0}' $(MAKEFILE_LIST) | column -s: -t
|
||||
|
||||
### Static checks
|
||||
check: test-run build-fission-cli clean
|
||||
@@ -56,52 +46,15 @@ test-run: code-checks
|
||||
@rm -f coverage.txt
|
||||
|
||||
### Binaries
|
||||
fission-cli:
|
||||
@mkdir -p $(BINDIR)
|
||||
GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO) build \
|
||||
-gcflags '$(GCFLAGS)' \
|
||||
-asmflags '$(ASMFLAGS)' \
|
||||
-ldflags "$(GO_LDFLAGS)" \
|
||||
-o $(BINDIR)/fission-$(VERSION)-$(GOOS)-$(GOARCH)$(FISSION-CLI-SUFFIX) ./cmd/fission-cli
|
||||
build-fission-cli:
|
||||
@GOOS=$(GOOS) GOARCH=$(GOARCH) GORELEASER_CURRENT_TAG=$(VERSION) goreleaser build --snapshot --rm-dist --single-target --id fission-cli
|
||||
|
||||
all-fission-cli:
|
||||
$(MAKE) fission-cli GOOS=windows GOARCH=amd64
|
||||
$(MAKE) fission-cli GOOS=linux GOARCH=amd64
|
||||
$(MAKE) fission-cli GOOS=linux GOARCH=arm
|
||||
$(MAKE) fission-cli GOOS=linux GOARCH=arm64
|
||||
$(MAKE) fission-cli GOOS=darwin GOARCH=amd64
|
||||
install-fission-cli:
|
||||
mv dist/fission-cli_$(GOOS)_$(GOARCH)/fission$(FISSION-CLI-SUFFIX) /usr/local/bin/fission
|
||||
|
||||
install-fission-cli: fission-cli
|
||||
mv $(BINDIR)/fission-$(VERSION)-$(GOOS)-$(GOARCH)$(FISSION-CLI-SUFFIX) /usr/local/bin/
|
||||
|
||||
### Container images
|
||||
FISSION_IMGS := fission-bundle-multiarch-img \
|
||||
fetcher-multiarch-img \
|
||||
builder-multiarch-img\
|
||||
pre-upgrade-checks-multiarch-img \
|
||||
reporter-multiarch-img
|
||||
|
||||
verify-builder:
|
||||
@./hack/buildx.sh $(PLATFORMS)
|
||||
|
||||
local-images:
|
||||
PLATFORMS=linux/amd64 $(MAKE) all-images
|
||||
|
||||
all-images: verify-builder $(FISSION_IMGS)
|
||||
|
||||
fission-bundle-multiarch-img: cmd/fission-bundle/Dockerfile.fission-bundle
|
||||
fetcher-multiarch-img: cmd/fetcher/Dockerfile.fission-fetcher
|
||||
builder-multiarch-img: cmd/builder/Dockerfile.fission-builder
|
||||
pre-upgrade-checks-multiarch-img: cmd/preupgradechecks/Dockerfile.fission-preupgradechecks
|
||||
reporter-multiarch-img: cmd/reporter/Dockerfile.reporter
|
||||
|
||||
%-multiarch-img:
|
||||
@echo === Building image $(REPO)/$(subst -multiarch-img,,$@):$(TAG) using context $(CURDIR) and dockerfile $<
|
||||
docker buildx build --platform=$(PLATFORMS) -t $(REPO)/$(subst -multiarch-img,,$@):$(TAG) \
|
||||
--build-arg GITCOMMIT=$(COMMITSHA) \
|
||||
--build-arg BUILDDATE=$(TIMESTAMP) \
|
||||
--build-arg BUILDVERSION=$(VERSION) \
|
||||
$(DOCKER_FLAGS) -f $< .
|
||||
### Codegen
|
||||
codegen:
|
||||
@./hack/update-codegen.sh
|
||||
|
||||
### CRDs
|
||||
generate-crds:
|
||||
@@ -120,17 +73,28 @@ delete-crds:
|
||||
|
||||
### Cleanup
|
||||
clean:
|
||||
@rm -f cmd/fission-bundle/fission-bundle
|
||||
@rm -f cmd/fission-cli/fission
|
||||
@rm -f cmd/fetcher/fetcher
|
||||
@rm -f cmd/fetcher/builder
|
||||
@rm -f cmd/reporter/reporter
|
||||
@rm -f pkg/apis/core/v1/types_swagger_doc_generated.go
|
||||
@rm -f dist/
|
||||
|
||||
### Misc
|
||||
generate-swagger-doc:
|
||||
@cd pkg/apis/core/v1/tool && ./update-generated-swagger-docs.sh
|
||||
@./hack/update-swagger-docs.sh
|
||||
|
||||
make release:
|
||||
all-generators: codegen generate-crds generate-swagger-doc
|
||||
|
||||
skaffold-prebuild:
|
||||
@GOOS=linux GOARCH=amd64 GORELEASER_CURRENT_TAG=$(VERSION) goreleaser build --snapshot --rm-dist --single-target
|
||||
@cp -v cmd/builder/Dockerfile.fission-builder dist/builder_linux_amd64/Dockerfile
|
||||
@cp -v cmd/fetcher/Dockerfile.fission-fetcher dist/fetcher_linux_amd64/Dockerfile
|
||||
@cp -v cmd/fission-bundle/Dockerfile.fission-bundle dist/fission-bundle_linux_amd64/Dockerfile
|
||||
@cp -v cmd/reporter/Dockerfile.reporter dist/reporter_linux_amd64/Dockerfile
|
||||
@cp -v cmd/preupgradechecks/Dockerfile.fission-preupgradechecks dist/pre-upgrade-checks_linux_amd64/Dockerfile
|
||||
|
||||
skaffold-deploy: skaffold-prebuild
|
||||
skaffold run -p $(SKAFFOLD_PROFILE)
|
||||
|
||||
### Release
|
||||
release:
|
||||
@./hack/generate-helm-manifest.sh $(VERSION)
|
||||
@./hack/release.sh $(VERSION)
|
||||
@./hack/releas-tag.sh $(VERSION)
|
||||
@./hack/release-tag.sh $(VERSION)
|
||||
@./hack/changelog.sh
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<img src="https://docs.fission.io/images/logo.png" width="300" />
|
||||
<img src="https://docs.fission.io/images/logo-gh.svg" width="300" />
|
||||
<br>
|
||||
<h1 align="center">Fission: Serverless Functions for Kubernetes</h1>
|
||||
</p>
|
||||
|
||||
@@ -79,6 +79,10 @@ Parameter | Description | Default
|
||||
`router.roundTrip.timeout` | HTTP transport request timeout | `50ms`
|
||||
`router.roundTrip.timeoutExponent` | The length of request timeout will multiply with timeoutExponent after each retry | `2`
|
||||
`router.roundTrip.maxRetries` | Max retries times of a failed request | `10`
|
||||
`openTracing.enabled` | If true, OpenTracing is enabled | `false`
|
||||
`openTracing.collectorEndpoint` | Jaeger collector endpoint | ``
|
||||
`openTracing.samplingRate` | Probabilistic sampling rate | `0.5`
|
||||
`otelCollectorEndpoint` | OpenTelemetry collector endpoint | None
|
||||
|
||||
### Extra configuration for `fission-all`
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: fission-all
|
||||
version: 1.13.1
|
||||
version: v1.15.0-rc1
|
||||
description: Fission is a fast serverless framework for Kubernetes.
|
||||
keywords:
|
||||
- fission
|
||||
@@ -12,7 +12,7 @@ maintainers:
|
||||
- name: Sanket Sudake
|
||||
email: sanket@infracloud.io
|
||||
engine: gotpl
|
||||
appVersion: 1.13.1
|
||||
appVersion: v1.15.0-rc1
|
||||
type: application
|
||||
dependencies:
|
||||
- name: prometheus
|
||||
|
||||
@@ -51,3 +51,29 @@ This template generates the image name for the deployment depending on the value
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "opentelemtry.envs" }}
|
||||
- name: OTEL_EXPORTER_OTLP_ENDPOINT
|
||||
value: "{{ .Values.openTelemetry.otlpCollectorEndpoint }}"
|
||||
- name: OTEL_EXPORTER_OTLP_INSECURE
|
||||
value: "{{ .Values.openTelemetry.otlpInsecure }}"
|
||||
{{- if .Values.openTelemetry.otlpHeaders }}
|
||||
- name: OTEL_EXPORTER_OTLP_HEADERS
|
||||
value: "{{ .Values.openTelemetry.otlpHeaders }}"
|
||||
{{- end }}
|
||||
- name: OTEL_TRACES_SAMPLER
|
||||
value: "{{ .Values.openTelemetry.tracesSampler }}"
|
||||
- name: OTEL_TRACES_SAMPLER_ARG
|
||||
value: "{{ .Values.openTelemetry.tracesSamplingRate }}"
|
||||
- name: OTEL_PROPAGATORS
|
||||
value: "{{ .Values.openTelemetry.propagators }}"
|
||||
{{- end }}
|
||||
|
||||
{{- define "opentracing.envs" }}
|
||||
- name: OPENTRACING_ENABLED
|
||||
value: {{ .Values.openTracing.enabled | default false | quote }}
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.openTracing.collectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.openTracing.samplingRate | default "0.5" | quote }}
|
||||
{{- end }}
|
||||
@@ -85,6 +85,7 @@ rules:
|
||||
resources:
|
||||
- deployments
|
||||
- deployments/scale
|
||||
- replicasets
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
@@ -334,16 +335,16 @@ spec:
|
||||
env:
|
||||
- name: FISSION_FUNCTION_NAMESPACE
|
||||
value: "{{ .Values.functionNamespace }}"
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: PPROF_ENABLED
|
||||
value: {{ .Values.pprof.enabled | quote }}
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: "/healthz"
|
||||
@@ -364,6 +365,10 @@ spec:
|
||||
ports:
|
||||
- containerPort: 8888
|
||||
name: http
|
||||
{{- if .Values.pprof.enabled }}
|
||||
- containerPort: 6060
|
||||
name: pprof
|
||||
{{- end }}
|
||||
serviceAccountName: fission-svc
|
||||
volumes:
|
||||
- name: config-volume
|
||||
@@ -418,10 +423,6 @@ spec:
|
||||
value: {{ .Values.executor.podReadyTimeout | default false | quote }}
|
||||
- name: ENABLE_ISTIO
|
||||
value: "{{ .Values.enableIstio }}"
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: FETCHER_MINCPU
|
||||
value: {{ .Values.fetcher.resource.cpu.requests | quote }}
|
||||
- name: FETCHER_MINMEM
|
||||
@@ -432,6 +433,10 @@ spec:
|
||||
value: {{ .Values.fetcher.resource.mem.limits | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: PPROF_ENABLED
|
||||
value: {{ .Values.pprof.enabled | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: "/healthz"
|
||||
@@ -450,6 +455,10 @@ spec:
|
||||
name: metrics
|
||||
- containerPort: 8888
|
||||
name: http
|
||||
{{- if .Values.pprof.enabled }}
|
||||
- containerPort: 6060
|
||||
name: pprof
|
||||
{{- end }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
@@ -492,10 +501,6 @@ spec:
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
- name: ENABLE_ISTIO
|
||||
value: "{{ .Values.enableIstio }}"
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: FETCHER_MINCPU
|
||||
value: {{ .Values.fetcher.resource.cpu.requests | quote }}
|
||||
- name: FETCHER_MINMEM
|
||||
@@ -506,6 +511,10 @@ spec:
|
||||
value: {{ .Values.fetcher.resource.mem.limits | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: PPROF_ENABLED
|
||||
value: {{ .Values.pprof.enabled | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
@@ -536,12 +545,12 @@ spec:
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--kubewatcher", "--routerUrl", "http://router.{{ .Release.Namespace }}"]
|
||||
env:
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: PPROF_ENABLED
|
||||
value: {{ .Values.pprof.enabled | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
@@ -615,7 +624,7 @@ metadata:
|
||||
kubernetes.io/cluster-service: 'true'
|
||||
kubernetes.io/name: heapster
|
||||
spec:
|
||||
type: ClusterIP
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8082
|
||||
@@ -644,7 +653,7 @@ spec:
|
||||
- name: heapster
|
||||
image: gcr.io/google_containers/heapster-amd64:v1.5.0
|
||||
imagePullPolicy: {{ .Values.pullPolicy }}
|
||||
command:
|
||||
command:
|
||||
- /heapster
|
||||
- --source=kubernetes:https://kubernetes.default
|
||||
serviceAccountName: {{ .Release.Namespace }}/fission-svc
|
||||
@@ -676,6 +685,10 @@ spec:
|
||||
env:
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: PPROF_ENABLED
|
||||
value: {{ .Values.pprof.enabled | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
@@ -809,12 +822,12 @@ spec:
|
||||
{{- else }}
|
||||
value: nats://{{ .Values.nats.hostaddress }}
|
||||
{{- end }}
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: PPROF_ENABLED
|
||||
value: {{ .Values.pprof.enabled | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
@@ -860,12 +873,12 @@ spec:
|
||||
value: "{{.Values.kafka.brokers}}"
|
||||
- name: MESSAGE_QUEUE_KAFKA_VERSION
|
||||
value: "{{.Values.kafka.version}}"
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: PPROF_ENABLED
|
||||
value: {{ .Values.pprof.enabled | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
# TLS authentication is TLS with authentication (2 way)
|
||||
# More info: https://docs.confluent.io/current/kafka/authentication_ssl.html#ssl-overview
|
||||
{{- if .Values.kafka.authentication.tls.enabled }}
|
||||
@@ -878,7 +891,7 @@ spec:
|
||||
volumeMounts:
|
||||
- name: kafka-secrets
|
||||
mountPath: /etc/fission/secrets
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.kafka.authentication.tls.enabled }}
|
||||
volumes:
|
||||
@@ -891,7 +904,7 @@ spec:
|
||||
{{- if .Values.kafka.authentication.tls.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
metadata:
|
||||
name: mqtrigger-kafka-secrets
|
||||
labels:
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
@@ -950,10 +963,6 @@ spec:
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--mqt", "--routerUrl", "http://router.{{ .Release.Namespace }}"]
|
||||
env:
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: MESSAGE_QUEUE_TYPE
|
||||
value: azure-storage-queue
|
||||
- name: AZURE_STORAGE_ACCOUNT_NAME
|
||||
@@ -965,6 +974,10 @@ spec:
|
||||
key: key
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: PPROF_ENABLED
|
||||
value: {{ .Values.pprof.enabled | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
@@ -1002,14 +1015,12 @@ spec:
|
||||
args: ["--storageServicePort", "8000", "--storageType", "local"]
|
||||
{{- end }}
|
||||
env:
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: PRUNE_INTERVAL
|
||||
value: "{{.Values.pruneInterval}}"
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: PPROF_ENABLED
|
||||
value: {{ .Values.pprof.enabled | quote }}
|
||||
{{- if and (.Values.persistence.enabled) (eq (.Values.persistence.storageType | default "local") "s3") }}
|
||||
- name: STORAGE_S3_ENDPOINT
|
||||
value: {{ .Values.persistence.s3.endPoint }}
|
||||
@@ -1024,6 +1035,8 @@ spec:
|
||||
- name: STORAGE_S3_REGION
|
||||
value: {{ .Values.persistence.s3.region }}
|
||||
{{- end }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
{{- if ne (.Values.persistence.storageType | default "local") "s3" }}
|
||||
volumeMounts:
|
||||
- name: fission-storage
|
||||
@@ -1045,6 +1058,10 @@ spec:
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
name: http
|
||||
{{- if .Values.pprof.enabled }}
|
||||
- containerPort: 6060
|
||||
name: pprof
|
||||
{{- end }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if and (.Values.persistence.enabled) (ne (.Values.persistence.storageType | default "local") "s3") }}
|
||||
volumes:
|
||||
@@ -1089,10 +1106,6 @@ spec:
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--mqt_keda", "--routerUrl", "http://router.{{ .Release.Namespace }}"]
|
||||
env:
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: CONNECTOR_IMAGE_PULL_POLICY
|
||||
@@ -1109,6 +1122,10 @@ spec:
|
||||
value: "{{ .Values.mqt_keda.connector_images.nats_steaming.image }}:{{ .Values.mqt_keda.connector_images.nats_steaming.tag }}"
|
||||
- name: GCP-PUB-SUB_IMAGE
|
||||
value: "{{ .Values.mqt_keda.connector_images.gcp_pub_sub.image }}:{{ .Values.mqt_keda.connector_images.gcp_pub_sub.tag }}"
|
||||
- name: REDIS_IMAGE
|
||||
value: "{{ .Values.mqt_keda.connector_images.redis.image }}:{{ .Values.mqt_keda.connector_images.redis.tag }}"
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
|
||||
@@ -117,6 +117,8 @@ spec:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: spec.nodeName
|
||||
- name: OPENTRACING_ENABLED
|
||||
value: {{ .Values.openTracing.enabled | default false | quote }}
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--logger"]
|
||||
volumeMounts:
|
||||
@@ -158,6 +160,8 @@ spec:
|
||||
key: password
|
||||
- name: LOG_PATH
|
||||
value: /var/log/fission/*.log
|
||||
- name: OPENTRACING_ENABLED
|
||||
value: {{ .Values.openTracing.enabled | default false | quote }}
|
||||
{{- if .Values.logger.enableSecurityContext }}
|
||||
securityContext:
|
||||
privileged: true
|
||||
|
||||
@@ -35,36 +35,36 @@ spec:
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--routerPort", "8888", "--executorUrl", "http://executor.{{ .Release.Namespace }}"]
|
||||
env:
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: ROUTER_ROUND_TRIP_TIMEOUT
|
||||
value: {{ .Values.router.roundTrip.timeout | default "50ms" | quote }}
|
||||
- name: ROUTER_ROUNDTRIP_TIMEOUT_EXPONENT
|
||||
value: {{ .Values.router.roundTrip.timeoutExponent | default 2 | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_KEEP_ALIVE_TIME
|
||||
value: {{ .Values.router.roundTrip.keepAliveTime | default "30s" | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_DISABLE_KEEP_ALIVE
|
||||
value: {{ .Values.router.roundTrip.disableKeepAlive | default true | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_MAX_RETRIES
|
||||
value: {{ .Values.router.roundTrip.maxRetries | default 10 | quote }}
|
||||
- name: ROUTER_SVC_ADDRESS_MAX_RETRIES
|
||||
value: {{ .Values.router.svcAddressMaxRetries | default 5 | quote }}
|
||||
- name: ROUTER_SVC_ADDRESS_UPDATE_TIMEOUT
|
||||
value: {{ .Values.router.svcAddressUpdateTimeout | default "30s" | quote }}
|
||||
- name: ROUTER_UNTAP_SERVICE_TIMEOUT
|
||||
value: {{ .Values.router.unTapServiceTimeout | default "3600s" | quote }}
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.router.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: USE_ENCODED_PATH
|
||||
value: {{ .Values.router.useEncodedPath | default false | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: DISPLAY_ACCESS_LOG
|
||||
value: {{ .Values.router.displayAccessLog | default false | quote }}
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: ROUTER_ROUND_TRIP_TIMEOUT
|
||||
value: {{ .Values.router.roundTrip.timeout | default "50ms" | quote }}
|
||||
- name: ROUTER_ROUNDTRIP_TIMEOUT_EXPONENT
|
||||
value: {{ .Values.router.roundTrip.timeoutExponent | default 2 | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_KEEP_ALIVE_TIME
|
||||
value: {{ .Values.router.roundTrip.keepAliveTime | default "30s" | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_DISABLE_KEEP_ALIVE
|
||||
value: {{ .Values.router.roundTrip.disableKeepAlive | default true | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_MAX_RETRIES
|
||||
value: {{ .Values.router.roundTrip.maxRetries | default 10 | quote }}
|
||||
- name: ROUTER_SVC_ADDRESS_MAX_RETRIES
|
||||
value: {{ .Values.router.svcAddressMaxRetries | default 5 | quote }}
|
||||
- name: ROUTER_SVC_ADDRESS_UPDATE_TIMEOUT
|
||||
value: {{ .Values.router.svcAddressUpdateTimeout | default "30s" | quote }}
|
||||
- name: ROUTER_UNTAP_SERVICE_TIMEOUT
|
||||
value: {{ .Values.router.unTapServiceTimeout | default "3600s" | quote }}
|
||||
- name: USE_ENCODED_PATH
|
||||
value: {{ .Values.router.useEncodedPath | default false | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: PPROF_ENABLED
|
||||
value: {{ .Values.pprof.enabled | quote }}
|
||||
- name: DISPLAY_ACCESS_LOG
|
||||
value: {{ .Values.router.displayAccessLog | default false | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
resources:
|
||||
{{- toYaml .Values.router.resources | indent 10 }}
|
||||
readinessProbe:
|
||||
@@ -85,6 +85,10 @@ spec:
|
||||
name: metrics
|
||||
- containerPort: 8888
|
||||
name: http
|
||||
{{- if .Values.pprof.enabled }}
|
||||
- containerPort: 6060
|
||||
name: pprof
|
||||
{{- end }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.router.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.router.extraCoreComponentPodConfig | indent 6 -}}
|
||||
|
||||
@@ -20,7 +20,7 @@ image: fission/fission-bundle
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
## Fission image version
|
||||
imageTag: 1.13.1
|
||||
imageTag: v1.15.0-rc1
|
||||
|
||||
## Port at which Fission controller service should be exposed
|
||||
controllerPort: 31313
|
||||
@@ -50,7 +50,7 @@ fetcher:
|
||||
## Fetcher repository
|
||||
image: fission/fetcher
|
||||
## Fetcher image version
|
||||
imageTag: 1.13.1
|
||||
imageTag: v1.15.0-rc1
|
||||
|
||||
## Fetcher is only for to downloading or uploading archive.
|
||||
## Normally, you don't need to change the value here, unless necessary.
|
||||
@@ -140,7 +140,7 @@ router:
|
||||
|
||||
## Sample with a rate per time window (traces/second)
|
||||
traceSamplingRate: 0.5
|
||||
|
||||
|
||||
## Extend the container specs for the core fission pods.
|
||||
## Can be used to add things like affinty/tolerations/nodeSelectors/etc.
|
||||
## For example:
|
||||
@@ -219,7 +219,6 @@ kafka:
|
||||
userCert: "" # path to certificate containing public key of the user signed by CA authority
|
||||
userKey: "" # path to private key of the user
|
||||
|
||||
|
||||
# brokers: 'my-broker.kafka:9092' # or my-bootstrap-server.kafka:9092/9093
|
||||
# Sample config for authentication
|
||||
# authentication:
|
||||
@@ -340,9 +339,54 @@ prometheus:
|
||||
canaryDeployment:
|
||||
enabled: true
|
||||
|
||||
# Use these flags to enable opentracing, the variable is endpoint of Jaeger collector in the format shown below
|
||||
#traceCollectorEndpoint: "http://jaeger-collector.jaeger.svc:14268/api/traces?format=jaeger.thrift"
|
||||
#traceSamplingRate: 0.75
|
||||
# Use the following flags to enable OpenTracing.
|
||||
# Note: OpenTracing support will be removed in an upcoming release.
|
||||
# Please prefer using OpenTelemetry instead.
|
||||
openTracing:
|
||||
## set this flag to true if you wish to enable OpenTracing
|
||||
enabled: false
|
||||
|
||||
## if enabled is true, the variable is endpoint of Jaeger collector in the format shown below
|
||||
#collectorEndpoint: "http://jaeger-collector.jaeger.svc:14268/api/traces?format=jaeger.thrift"
|
||||
|
||||
## uniformly sample traces with the given probabilistic sampling rate
|
||||
#samplingRate: 0.75
|
||||
|
||||
# It is an alternate to OpenTracing.
|
||||
openTelemetry:
|
||||
# Use this flag to set the collector endpoint for OpenTelemetry.
|
||||
# The variable is endpoint of the collector in the format shown below.
|
||||
# otlpCollectorEndpoint: "otel-collector.observability.svc:4317"
|
||||
otlpCollectorEndpoint: ""
|
||||
# Set this flag to false if you are using secure endpoint for the collector.
|
||||
otlpInsecure: true
|
||||
# Key-value pairs to be used as headers associated with gRPC or HTTP requests
|
||||
# to the collector.
|
||||
# Eg. otlpHeaders: "key1=value1,key2=value2"
|
||||
otlpHeaders: ""
|
||||
# Supported samplers:
|
||||
# always_on - Sampler that always samples spans, regardless of the parent span's sampling decision.
|
||||
# always_off - Sampler that never samples spans, regardless of the parent span's sampling decision.
|
||||
# traceidratio - Sampler that samples probabalistically based on rate.
|
||||
# parentbased_always_on - (default if empty) Sampler that respects its parent span's sampling decision, but otherwise always samples.
|
||||
# parentbased_always_off - Sampler that respects its parent span's sampling decision, but otherwise never samples.
|
||||
# parentbased_traceidratio - Sampler that respects its parent span's sampling decision, but otherwise samples probabalistically based on rate.
|
||||
tracesSampler: "parentbased_traceidratio"
|
||||
# Each Sampler type defines its own expected input, if any.
|
||||
# Currently we get trace ratio for the case of,
|
||||
# 1. traceidratio
|
||||
# 2. parentbased_traceidratio
|
||||
# Sampling probability, a number in the [0..1] range, e.g. "0.1". Default is 0.1.
|
||||
tracesSamplingRate: "0.1"
|
||||
# Supported providers:
|
||||
# tracecontext - W3C Trace Context
|
||||
# baggage - W3C Baggage
|
||||
# b3 - B3 Single
|
||||
# b3multi - B3 Multi
|
||||
# jaeger - Jaeger uber-trace-id header
|
||||
# xray - AWS X-Ray (third party)
|
||||
# ottrace - OpenTracing Trace (third party)
|
||||
propagators: "tracecontext,baggage"
|
||||
|
||||
## Message Queue Trigger Kind, KEDA: enable and configuration
|
||||
mqt_keda:
|
||||
@@ -350,19 +394,26 @@ mqt_keda:
|
||||
connector_images:
|
||||
kafka:
|
||||
image: fission/keda-kafka-http-connector
|
||||
tag: v0.6
|
||||
tag: v0.8
|
||||
rabbitmq:
|
||||
image: fission/keda-rabbitmq-http-connector
|
||||
tag: v0.6
|
||||
tag: v0.8
|
||||
awskinesis:
|
||||
image: fission/keda-aws-kinesis-http-connector
|
||||
tag: v0.6
|
||||
tag: v0.8
|
||||
aws_sqs:
|
||||
image: fission/keda-aws-sqs-http-connector
|
||||
tag: v0.6
|
||||
tag: v0.8
|
||||
nats_steaming:
|
||||
image: fission/keda-nats-streaming-http-connector
|
||||
tag: v0.6
|
||||
tag: v0.9
|
||||
gcp_pub_sub:
|
||||
image: fission/keda-gcp-pubsub-http-connector
|
||||
tag: v0.3
|
||||
redis:
|
||||
image: fission/keda-redis-http-connector
|
||||
tag: v0.1
|
||||
|
||||
## Enable Pprof based profiling
|
||||
pprof:
|
||||
enabled: false
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: fission-core
|
||||
version: 1.13.1
|
||||
version: v1.15.0-rc1
|
||||
description: Fission is a fast serverless framework for Kubernetes.
|
||||
keywords:
|
||||
- fission
|
||||
@@ -12,7 +12,7 @@ maintainers:
|
||||
- name: Sanket Sudake
|
||||
email: sanket@infracloud.io
|
||||
engine: gotpl
|
||||
appVersion: 1.13.1
|
||||
appVersion: v1.15.0-rc1
|
||||
type: application
|
||||
dependencies:
|
||||
- name: prometheus
|
||||
|
||||
@@ -42,3 +42,29 @@ This template generates the image name for the deployment depending on the value
|
||||
{{ .Values.image }}:{{ .Values.imageTag }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "opentelemtry.envs" }}
|
||||
- name: OTEL_EXPORTER_OTLP_ENDPOINT
|
||||
value: "{{ .Values.openTelemetry.otlpCollectorEndpoint }}"
|
||||
- name: OTEL_EXPORTER_OTLP_INSECURE
|
||||
value: "{{ .Values.openTelemetry.otlpInsecure }}"
|
||||
{{- if .Values.openTelemetry.otlpHeaders }}
|
||||
- name: OTEL_EXPORTER_OTLP_HEADERS
|
||||
value: "{{ .Values.openTelemetry.otlpHeaders }}"
|
||||
{{- end }}
|
||||
- name: OTEL_TRACES_SAMPLER
|
||||
value: "{{ .Values.openTelemetry.tracesSampler }}"
|
||||
- name: OTEL_TRACES_SAMPLER_ARG
|
||||
value: "{{ .Values.openTelemetry.tracesSamplingRate }}"
|
||||
- name: OTEL_PROPAGATORS
|
||||
value: "{{ .Values.openTelemetry.propagators }}"
|
||||
{{- end }}
|
||||
|
||||
{{- define "opentracing.envs" }}
|
||||
- name: OPENTRACING_ENABLED
|
||||
value: {{ .Values.openTracing.enabled | default false | quote }}
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.openTracing.collectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.openTracing.samplingRate | default "0.5" | quote }}
|
||||
{{- end }}
|
||||
|
||||
@@ -140,16 +140,14 @@ spec:
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--controllerPort", "8888"]
|
||||
env:
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: FISSION_FUNCTION_NAMESPACE
|
||||
value: "{{ .Values.functionNamespace }}"
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: FISSION_FUNCTION_NAMESPACE
|
||||
value: "{{ .Values.functionNamespace }}"
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: "/healthz"
|
||||
@@ -215,10 +213,6 @@ spec:
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
- name: FETCHER_IMAGE_PULL_POLICY
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: ADOPT_EXISTING_RESOURCES
|
||||
value: {{ .Values.executor.adoptExistingResources | default false | quote }}
|
||||
- name: POD_READY_TIMEOUT
|
||||
@@ -233,6 +227,8 @@ spec:
|
||||
value: {{ .Values.fetcher.resource.cpu.limits | quote }}
|
||||
- name: FETCHER_MAXMEM
|
||||
value: {{ .Values.fetcher.resource.mem.limits | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: "/healthz"
|
||||
@@ -286,11 +282,7 @@ spec:
|
||||
- name: FETCHER_IMAGE_PULL_POLICY
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
- name: BUILDER_IMAGE_PULL_POLICY
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
- name: ENABLE_ISTIO
|
||||
value: "{{ .Values.enableIstio }}"
|
||||
- name: FETCHER_MINCPU
|
||||
@@ -301,6 +293,8 @@ spec:
|
||||
value: {{ .Values.fetcher.resource.cpu.limits | quote }}
|
||||
- name: FETCHER_MAXMEM
|
||||
value: {{ .Values.fetcher.resource.mem.limits | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
@@ -331,10 +325,8 @@ spec:
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--kubewatcher", "--routerUrl", "http://router.{{ .Release.Namespace }}"]
|
||||
env:
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
@@ -365,10 +357,8 @@ spec:
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--timer", "--routerUrl", "http://router.{{ .Release.Namespace }}"]
|
||||
env:
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
@@ -408,10 +398,6 @@ spec:
|
||||
env:
|
||||
- name: PRUNE_INTERVAL
|
||||
value: "{{.Values.pruneInterval}}"
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
{{- if and (.Values.persistence.enabled) (eq (.Values.persistence.storageType | default "local") "s3") }}
|
||||
- name: STORAGE_S3_ENDPOINT
|
||||
value: {{ .Values.persistence.s3.endPoint }}
|
||||
@@ -426,6 +412,8 @@ spec:
|
||||
- name: STORAGE_S3_REGION
|
||||
value: {{ .Values.persistence.s3.region }}
|
||||
{{- end }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
{{- if ne (.Values.persistence.storageType | default "local") "s3" }}
|
||||
volumeMounts:
|
||||
- name: fission-storage
|
||||
@@ -478,10 +466,6 @@ spec:
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--mqt_keda", "--routerUrl", "http://router.{{ .Release.Namespace }}"]
|
||||
env:
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: CONNECTOR_IMAGE_PULL_POLICY
|
||||
@@ -498,6 +482,10 @@ spec:
|
||||
value: "{{ .Values.mqt_keda.connector_images.nats_steaming.image }}:{{ .Values.mqt_keda.connector_images.nats_steaming.tag }}"
|
||||
- name: GCP-PUB-SUB_IMAGE
|
||||
value: "{{ .Values.mqt_keda.connector_images.gcp_pub_sub.image }}:{{ .Values.mqt_keda.connector_images.gcp_pub_sub.tag }}"
|
||||
- name: REDIS_IMAGE
|
||||
value: "{{ .Values.mqt_keda.connector_images.redis.image }}:{{ .Values.mqt_keda.connector_images.redis.tag }}"
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
serviceAccountName: fission-svc
|
||||
{{- if .Values.extraCoreComponentPodConfig }}
|
||||
{{ toYaml .Values.extraCoreComponentPodConfig | indent 6 -}}
|
||||
|
||||
@@ -35,36 +35,34 @@ spec:
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--routerPort", "8888", "--executorUrl", "http://executor.{{ .Release.Namespace }}"]
|
||||
env:
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: ROUTER_ROUND_TRIP_TIMEOUT
|
||||
value: {{ .Values.router.roundTrip.timeout | default "50ms" | quote }}
|
||||
- name: ROUTER_ROUNDTRIP_TIMEOUT_EXPONENT
|
||||
value: {{ .Values.router.roundTrip.timeoutExponent | default 2 | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_KEEP_ALIVE_TIME
|
||||
value: {{ .Values.router.roundTrip.keepAliveTime | default "30s" | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_DISABLE_KEEP_ALIVE
|
||||
value: {{ .Values.router.roundTrip.disableKeepAlive | default true | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_MAX_RETRIES
|
||||
value: {{ .Values.router.roundTrip.maxRetries | default 10 | quote }}
|
||||
- name: ROUTER_SVC_ADDRESS_MAX_RETRIES
|
||||
value: {{ .Values.router.svcAddressMaxRetries | default 5 | quote }}
|
||||
- name: ROUTER_SVC_ADDRESS_UPDATE_TIMEOUT
|
||||
value: {{ .Values.router.svcAddressUpdateTimeout | default "30s" | quote }}
|
||||
- name: ROUTER_UNTAP_SERVICE_TIMEOUT
|
||||
value: {{ .Values.router.unTapServiceTimeout | default "3600s" | quote }}
|
||||
- name: TRACE_JAEGER_COLLECTOR_ENDPOINT
|
||||
value: "{{ .Values.traceCollectorEndpoint }}"
|
||||
- name: TRACING_SAMPLING_RATE
|
||||
value: {{ .Values.router.traceSamplingRate | default "0.5" | quote }}
|
||||
- name: USE_ENCODED_PATH
|
||||
value: {{ .Values.router.useEncodedPath | default false | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: DISPLAY_ACCESS_LOG
|
||||
value: {{ .Values.router.displayAccessLog | default false | quote }}
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: ROUTER_ROUND_TRIP_TIMEOUT
|
||||
value: {{ .Values.router.roundTrip.timeout | default "50ms" | quote }}
|
||||
- name: ROUTER_ROUNDTRIP_TIMEOUT_EXPONENT
|
||||
value: {{ .Values.router.roundTrip.timeoutExponent | default 2 | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_KEEP_ALIVE_TIME
|
||||
value: {{ .Values.router.roundTrip.keepAliveTime | default "30s" | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_DISABLE_KEEP_ALIVE
|
||||
value: {{ .Values.router.roundTrip.disableKeepAlive | default true | quote }}
|
||||
- name: ROUTER_ROUND_TRIP_MAX_RETRIES
|
||||
value: {{ .Values.router.roundTrip.maxRetries | default 10 | quote }}
|
||||
- name: ROUTER_SVC_ADDRESS_MAX_RETRIES
|
||||
value: {{ .Values.router.svcAddressMaxRetries | default 5 | quote }}
|
||||
- name: ROUTER_SVC_ADDRESS_UPDATE_TIMEOUT
|
||||
value: {{ .Values.router.svcAddressUpdateTimeout | default "30s" | quote }}
|
||||
- name: ROUTER_UNTAP_SERVICE_TIMEOUT
|
||||
value: {{ .Values.router.unTapServiceTimeout | default "3600s" | quote }}
|
||||
- name: USE_ENCODED_PATH
|
||||
value: {{ .Values.router.useEncodedPath | default false | quote }}
|
||||
- name: DEBUG_ENV
|
||||
value: {{ .Values.debugEnv | quote }}
|
||||
- name: DISPLAY_ACCESS_LOG
|
||||
value: {{ .Values.router.displayAccessLog | default false | quote }}
|
||||
{{- include "opentracing.envs" . | indent 8 }}
|
||||
{{- include "opentelemtry.envs" . | indent 8 }}
|
||||
resources:
|
||||
{{- toYaml .Values.router.resources | indent 10 }}
|
||||
readinessProbe:
|
||||
|
||||
@@ -17,7 +17,7 @@ repository: index.docker.io
|
||||
image: fission/fission-bundle
|
||||
|
||||
## Fission image version
|
||||
imageTag: 1.13.1
|
||||
imageTag: v1.15.0-rc1
|
||||
|
||||
## Image pull policy
|
||||
pullPolicy: IfNotPresent
|
||||
@@ -43,7 +43,7 @@ fetcher:
|
||||
## Fetcher repository
|
||||
image: fission/fetcher
|
||||
## Fetcher image version
|
||||
imageTag: 1.13.1
|
||||
imageTag: v1.15.0-rc1
|
||||
|
||||
## Fetcher is only for to downloading or uploading archive.
|
||||
## Normally, you don't need to change the value here, unless necessary.
|
||||
@@ -108,7 +108,7 @@ router:
|
||||
|
||||
## Sample with a rate per time window (traces/second)
|
||||
traceSamplingRate: 0.5
|
||||
|
||||
|
||||
## Extend the container specs for the router fission pods.
|
||||
## Can be used to add things like affinty/tolerations/nodeSelectors/etc.
|
||||
## For example:
|
||||
@@ -229,9 +229,54 @@ prometheus:
|
||||
canaryDeployment:
|
||||
enabled: false
|
||||
|
||||
# Use these flags to enable opentracing, the variable is endpoint of Jaeger collector in the format shown below
|
||||
#traceCollectorEndpoint: "http://jaeger-collector.jaeger.svc:14268/api/traces?format=jaeger.thrift"
|
||||
#traceSamplingRate: 0.75
|
||||
# Use the following flags to enable OpenTracing.
|
||||
# Note: OpenTracing support will be removed in an upcoming release.
|
||||
# Please prefer using OpenTelemetry instead.
|
||||
openTracing:
|
||||
## set this flag to true if you wish to enable OpenTracing
|
||||
enabled: false
|
||||
|
||||
## if enabled is true, the variable is endpoint of Jaeger collector in the format shown below
|
||||
#collectorEndpoint: "http://jaeger-collector.jaeger.svc:14268/api/traces?format=jaeger.thrift"
|
||||
|
||||
## uniformly sample traces with the given probabilistic sampling rate
|
||||
#samplingRate: 0.75
|
||||
|
||||
# It is an alternate to OpenTracing.
|
||||
openTelemetry:
|
||||
# Use this flag to set the collector endpoint for OpenTelemetry.
|
||||
# The variable is endpoint of the collector in the format shown below.
|
||||
# otlpCollectorEndpoint: "otel-collector.observability.svc:4317"
|
||||
otlpCollectorEndpoint: ""
|
||||
# Set this flag to false if you are using secure endpoint for the collector.
|
||||
otlpInsecure: true
|
||||
# Key-value pairs to be used as headers associated with gRPC or HTTP requests
|
||||
# to the collector.
|
||||
# Eg. otlpHeaders: "key1=value1,key2=value2"
|
||||
otlpHeaders: ""
|
||||
# Supported samplers:
|
||||
# always_on - Sampler that always samples spans, regardless of the parent span's sampling decision.
|
||||
# always_off - Sampler that never samples spans, regardless of the parent span's sampling decision.
|
||||
# traceidratio - Sampler that samples probabalistically based on rate.
|
||||
# parentbased_always_on - (default if empty) Sampler that respects its parent span's sampling decision, but otherwise always samples.
|
||||
# parentbased_always_off - Sampler that respects its parent span's sampling decision, but otherwise never samples.
|
||||
# parentbased_traceidratio - Sampler that respects its parent span's sampling decision, but otherwise samples probabalistically based on rate.
|
||||
tracesSampler: "parentbased_traceidratio"
|
||||
# Each Sampler type defines its own expected input, if any.
|
||||
# Currently we get trace ratio for the case of,
|
||||
# 1. traceidratio
|
||||
# 2. parentbased_traceidratio
|
||||
# Sampling probability, a number in the [0..1] range, e.g. "0.1". Default is 0.1.
|
||||
tracesSamplingRate: "0.1"
|
||||
# Supported providers:
|
||||
# tracecontext - W3C Trace Context
|
||||
# baggage - W3C Baggage
|
||||
# b3 - B3 Single
|
||||
# b3multi - B3 Multi
|
||||
# jaeger - Jaeger uber-trace-id header
|
||||
# xray - AWS X-Ray (third party)
|
||||
# ottrace - OpenTracing Trace (third party)
|
||||
propagators: "tracecontext,baggage"
|
||||
|
||||
## Message Queue Trigger Kind, KEDA: enable and configuration
|
||||
mqt_keda:
|
||||
@@ -239,19 +284,22 @@ mqt_keda:
|
||||
connector_images:
|
||||
kafka:
|
||||
image: fission/keda-kafka-http-connector
|
||||
tag: v0.6
|
||||
tag: v0.8
|
||||
rabbitmq:
|
||||
image: fission/keda-rabbitmq-http-connector
|
||||
tag: v0.6
|
||||
tag: v0.8
|
||||
awskinesis:
|
||||
image: fission/keda-aws-kinesis-http-connector
|
||||
tag: v0.6
|
||||
tag: v0.8
|
||||
aws_sqs:
|
||||
image: fission/keda-aws-sqs-http-connector
|
||||
tag: v0.6
|
||||
tag: v0.8
|
||||
nats_steaming:
|
||||
image: fission/keda-nats-streaming-http-connector
|
||||
tag: v0.6
|
||||
tag: v0.9
|
||||
gcp_pub_sub:
|
||||
image: fission/keda-gcp-pubsub-http-connector
|
||||
tag: v0.3
|
||||
redis:
|
||||
image: fission/keda-redis-http-connector
|
||||
tag: v0.1
|
||||
|
||||
@@ -1,45 +1,4 @@
|
||||
FROM golang:1.15-alpine as godep
|
||||
RUN apk add bash ca-certificates git gcc g++ libc-dev
|
||||
|
||||
ARG GOPKG=github.com/fission/fission
|
||||
|
||||
ENV GO111MODULE=on
|
||||
|
||||
WORKDIR /go/src/${GOPKG}
|
||||
|
||||
# To reuse build cache, copy go.mod & go.sum and download dependencies first.
|
||||
COPY go.* ./
|
||||
|
||||
RUN go mod download
|
||||
|
||||
FROM godep as builder
|
||||
|
||||
ARG GOPKG
|
||||
WORKDIR /go/src/${GOPKG}
|
||||
|
||||
# Copy whole fission directory to work dir
|
||||
COPY ./ ./
|
||||
|
||||
WORKDIR /go/src/${GOPKG}/cmd/builder
|
||||
|
||||
ARG GITCOMMIT=unknown
|
||||
# E.g. GITCOMMIT=$(git rev-parse HEAD)
|
||||
|
||||
ARG BUILDVERSION=unknown
|
||||
# E.g. BUILDVERSION=$(git rev-parse HEAD)
|
||||
|
||||
ARG BUILDDATE=unknown
|
||||
# E.g. BUILDDATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
|
||||
RUN CGO_ENABLED=0 go build \
|
||||
-o /go/bin/builder \
|
||||
-gcflags=-trimpath=$GOPATH \
|
||||
-asmflags=-trimpath=$GOPATH \
|
||||
-ldflags "-X github.com/fission/fission/pkg/info.GitCommit=${GITCOMMIT} -X github.com/fission/fission/pkg/info.BuildDate=${BUILDDATE} -X github.com/fission/fission/pkg/info.Version=${BUILDVERSION}"
|
||||
|
||||
FROM alpine:3.13 as base
|
||||
FROM alpine:3.14
|
||||
RUN apk add --update ca-certificates
|
||||
COPY --from=builder /go/bin/builder /
|
||||
EXPOSE 8001
|
||||
|
||||
COPY builder /builder
|
||||
ENTRYPOINT ["/builder"]
|
||||
|
||||
+6
-9
@@ -17,25 +17,22 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"github.com/fission/fission/cmd/builder/app"
|
||||
"github.com/fission/fission/pkg/utils/loggerfactory"
|
||||
"github.com/fission/fission/pkg/utils/profile"
|
||||
)
|
||||
|
||||
// Usage: builder <shared volume path>
|
||||
func main() {
|
||||
config := zap.NewProductionConfig()
|
||||
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
logger, err := config.Build()
|
||||
if err != nil {
|
||||
log.Fatalf("can't initialize zap logger: %v", err)
|
||||
}
|
||||
logger := loggerfactory.GetLogger()
|
||||
defer logger.Sync()
|
||||
|
||||
profile.ProfileIfEnabled(logger)
|
||||
|
||||
shareVolume := os.Args[1]
|
||||
if _, err := os.Stat(shareVolume); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
@@ -46,6 +43,6 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
err = app.Run(logger, shareVolume)
|
||||
err := app.Run(logger, shareVolume)
|
||||
logger.Error("error running builder", zap.Error(err))
|
||||
}
|
||||
|
||||
@@ -1,45 +1,4 @@
|
||||
FROM golang:1.15-alpine as godep
|
||||
RUN apk add bash ca-certificates git gcc g++ libc-dev
|
||||
|
||||
ARG GOPKG=github.com/fission/fission
|
||||
|
||||
ENV GO111MODULE=on
|
||||
|
||||
WORKDIR /go/src/${GOPKG}
|
||||
|
||||
# To reuse build cache, copy go.mod & go.sum and download dependencies first.
|
||||
COPY go.* ./
|
||||
|
||||
RUN go mod download
|
||||
|
||||
FROM godep as builder
|
||||
|
||||
ARG GOPKG
|
||||
WORKDIR /go/src/${GOPKG}
|
||||
|
||||
# Copy whole fission directory to work dir
|
||||
COPY ./ ./
|
||||
|
||||
WORKDIR /go/src/${GOPKG}/cmd/fetcher
|
||||
|
||||
ARG GITCOMMIT=unknown
|
||||
# E.g. GITCOMMIT=$(git rev-parse HEAD)
|
||||
|
||||
ARG BUILDVERSION=unknown
|
||||
# E.g. BUILDVERSION=$(git rev-parse HEAD)
|
||||
|
||||
ARG BUILDDATE=unknown
|
||||
# E.g. BUILDDATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
|
||||
RUN CGO_ENABLED=0 go build \
|
||||
-o /go/bin/fetcher \
|
||||
-gcflags=-trimpath=$GOPATH \
|
||||
-asmflags=-trimpath=$GOPATH \
|
||||
-ldflags "-X github.com/fission/fission/pkg/info.GitCommit=${GITCOMMIT} -X github.com/fission/fission/pkg/info.BuildDate=${BUILDDATE} -X github.com/fission/fission/pkg/info.Version=${BUILDVERSION}"
|
||||
|
||||
FROM alpine:3.13 as base
|
||||
FROM alpine:3.14
|
||||
RUN apk add --update ca-certificates
|
||||
COPY --from=builder /go/bin/fetcher /
|
||||
EXPOSE 8000
|
||||
|
||||
COPY fetcher /
|
||||
ENTRYPOINT ["/fetcher"]
|
||||
|
||||
+37
-40
@@ -24,37 +24,20 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
|
||||
"contrib.go.opencensus.io/exporter/jaeger"
|
||||
"go.opencensus.io/plugin/ochttp"
|
||||
"go.opencensus.io/trace"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/fission/fission/pkg/fetcher"
|
||||
otelUtils "github.com/fission/fission/pkg/utils/otel"
|
||||
"github.com/fission/fission/pkg/utils/tracing"
|
||||
)
|
||||
|
||||
func registerTraceExporter(collectorEndpoint string) error {
|
||||
if collectorEndpoint == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
serviceName := "Fission-Fetcher"
|
||||
exporter, err := jaeger.NewExporter(jaeger.Options{
|
||||
CollectorEndpoint: collectorEndpoint,
|
||||
Process: jaeger.Process{
|
||||
ServiceName: serviceName,
|
||||
Tags: []jaeger.Tag{
|
||||
jaeger.BoolTag("fission", true),
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trace.RegisterExporter(exporter)
|
||||
trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
readyToServe uint32
|
||||
)
|
||||
|
||||
func Run(logger *zap.Logger) {
|
||||
flag.Usage = fetcherUsage
|
||||
@@ -80,17 +63,33 @@ func Run(logger *zap.Logger) {
|
||||
}
|
||||
}
|
||||
|
||||
if err := registerTraceExporter(*collectorEndpoint); err != nil {
|
||||
logger.Fatal("could not register trace exporter", zap.Error(err), zap.String("collector_endpoint", *collectorEndpoint))
|
||||
ctx := context.Background()
|
||||
openTracingEnabled := tracing.TracingEnabled(logger)
|
||||
if openTracingEnabled {
|
||||
go func() {
|
||||
if err := tracing.RegisterTraceExporter(logger, *collectorEndpoint, "Fission-Fetcher"); err != nil {
|
||||
logger.Fatal("could not register trace exporter", zap.Error(err), zap.String("collector_endpoint", *collectorEndpoint))
|
||||
}
|
||||
}()
|
||||
} else {
|
||||
shutdown, err := otelUtils.InitProvider(ctx, logger, "Fission-Fetcher")
|
||||
if err != nil {
|
||||
logger.Fatal("error initializing provider for OTLP", zap.Error(err))
|
||||
}
|
||||
if shutdown != nil {
|
||||
defer shutdown(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
tracer := otel.Tracer("fetcher")
|
||||
ctx, span := tracer.Start(ctx, "fetcher/Run")
|
||||
defer span.End()
|
||||
|
||||
f, err := fetcher.MakeFetcher(logger, dir, *secretDir, *configDir)
|
||||
if err != nil {
|
||||
logger.Fatal("error making fetcher", zap.Error(err))
|
||||
}
|
||||
|
||||
readyToServe := false
|
||||
|
||||
// do specialization in other goroutine to prevent blocking in newdeploy
|
||||
go func() {
|
||||
if *specializeOnStart {
|
||||
@@ -101,14 +100,12 @@ func Run(logger *zap.Logger) {
|
||||
logger.Fatal("error decoding specialize request", zap.Error(err))
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
err = f.SpecializePod(ctx, specializeReq.FetchReq, specializeReq.LoadReq)
|
||||
if err != nil {
|
||||
logger.Fatal("error specializing function pod", zap.Error(err))
|
||||
}
|
||||
|
||||
readyToServe = true
|
||||
}
|
||||
atomic.StoreUint32(&readyToServe, 1)
|
||||
}()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
@@ -120,7 +117,7 @@ func Run(logger *zap.Logger) {
|
||||
mux.HandleFunc("/wsevent/end", f.WsEndHandler)
|
||||
|
||||
readinessHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
if !*specializeOnStart || readyToServe {
|
||||
if atomic.LoadUint32(&readyToServe) == 1 {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
@@ -132,15 +129,15 @@ func Run(logger *zap.Logger) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
// For backward compatibility
|
||||
// TODO: remove this path in future
|
||||
mux.HandleFunc("/readniess-healthz", readinessHandler)
|
||||
|
||||
logger.Info("fetcher ready to receive requests")
|
||||
err = http.ListenAndServe(":8000", &ochttp.Handler{
|
||||
Handler: mux,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
var handler http.Handler
|
||||
if openTracingEnabled {
|
||||
handler = &ochttp.Handler{Handler: mux}
|
||||
} else {
|
||||
handler = otelUtils.GetHandlerWithOTEL(mux, "fission-fetcher", otelUtils.UrlsToIgnore("/healthz", "/readiness-healthz"))
|
||||
}
|
||||
if err = http.ListenAndServe(":8000", handler); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
+6
-11
@@ -17,22 +17,17 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"github.com/fission/fission/cmd/fetcher/app"
|
||||
"github.com/fission/fission/pkg/utils/loggerfactory"
|
||||
"github.com/fission/fission/pkg/utils/profile"
|
||||
)
|
||||
|
||||
// Usage: fetcher <shared volume path>
|
||||
func main() {
|
||||
config := zap.NewProductionConfig()
|
||||
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
logger, err := config.Build()
|
||||
if err != nil {
|
||||
log.Fatalf("can't initialize zap logger: %v", err)
|
||||
}
|
||||
logger := loggerfactory.GetLogger()
|
||||
defer logger.Sync()
|
||||
|
||||
profile.ProfileIfEnabled(logger)
|
||||
|
||||
app.Run(logger)
|
||||
}
|
||||
|
||||
@@ -1,44 +1,4 @@
|
||||
FROM golang:1.15-alpine as godep
|
||||
RUN apk add bash ca-certificates git gcc g++ libc-dev
|
||||
|
||||
ARG GOPKG=github.com/fission/fission
|
||||
|
||||
ENV GO111MODULE=on
|
||||
|
||||
WORKDIR /go/src/${GOPKG}
|
||||
|
||||
# To reuse build cache, copy go.mod & go.sum and download dependencies first.
|
||||
COPY go.* ./
|
||||
|
||||
RUN go mod download
|
||||
|
||||
FROM godep as builder
|
||||
|
||||
ARG GOPKG
|
||||
WORKDIR /go/src/${GOPKG}
|
||||
|
||||
# Copy whole fission directory to work dir
|
||||
COPY ./ ./
|
||||
|
||||
WORKDIR /go/src/${GOPKG}/cmd/fission-bundle
|
||||
|
||||
ARG GITCOMMIT=unknown
|
||||
# E.g. GITCOMMIT=$(git rev-parse HEAD)
|
||||
|
||||
ARG BUILDVERSION=unknown
|
||||
# E.g. BUILDVERSION=$(git rev-parse HEAD)
|
||||
|
||||
ARG BUILDDATE=unknown
|
||||
# E.g. BUILDDATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
|
||||
RUN CGO_ENABLED=0 go build \
|
||||
-o /go/bin/fission-bundle \
|
||||
-gcflags=-trimpath=$GOPATH \
|
||||
-asmflags=-trimpath=$GOPATH \
|
||||
-ldflags "-X github.com/fission/fission/pkg/info.GitCommit=${GITCOMMIT} -X github.com/fission/fission/pkg/info.BuildDate=${BUILDDATE} -X github.com/fission/fission/pkg/info.Version=${BUILDVERSION}"
|
||||
|
||||
FROM alpine:3.13 as base
|
||||
FROM alpine:3.14
|
||||
RUN apk add --update ca-certificates
|
||||
COPY --from=builder /go/bin/fission-bundle /
|
||||
|
||||
COPY fission-bundle /
|
||||
ENTRYPOINT ["/fission-bundle"]
|
||||
|
||||
+39
-63
@@ -17,17 +17,16 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"contrib.go.opencensus.io/exporter/jaeger"
|
||||
docopt "github.com/docopt/docopt-go"
|
||||
"go.opencensus.io/trace"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"github.com/fission/fission/cmd/fission-bundle/mqtrigger"
|
||||
"github.com/fission/fission/pkg/buildermgr"
|
||||
@@ -40,20 +39,24 @@ import (
|
||||
"github.com/fission/fission/pkg/router"
|
||||
"github.com/fission/fission/pkg/storagesvc"
|
||||
"github.com/fission/fission/pkg/timer"
|
||||
"github.com/fission/fission/pkg/utils/loggerfactory"
|
||||
"github.com/fission/fission/pkg/utils/otel"
|
||||
"github.com/fission/fission/pkg/utils/profile"
|
||||
"github.com/fission/fission/pkg/utils/tracing"
|
||||
)
|
||||
|
||||
func runController(logger *zap.Logger, port int) {
|
||||
controller.Start(logger, port, false)
|
||||
func runController(logger *zap.Logger, port int, openTracingEnabled bool) {
|
||||
controller.Start(logger, port, false, openTracingEnabled)
|
||||
logger.Fatal("controller exited")
|
||||
}
|
||||
|
||||
func runRouter(logger *zap.Logger, port int, executorUrl string) {
|
||||
router.Start(logger, port, executorUrl)
|
||||
func runRouter(logger *zap.Logger, port int, executorUrl string, openTracingEnabled bool) {
|
||||
router.Start(logger, port, executorUrl, openTracingEnabled)
|
||||
logger.Fatal("router exited")
|
||||
}
|
||||
|
||||
func runExecutor(logger *zap.Logger, port int, functionNamespace, envBuilderNamespace string) {
|
||||
err := executor.StartExecutor(logger, functionNamespace, envBuilderNamespace, port)
|
||||
func runExecutor(logger *zap.Logger, port int, functionNamespace, envBuilderNamespace string, openTracingEnabled bool) {
|
||||
err := executor.StartExecutor(logger, functionNamespace, envBuilderNamespace, port, openTracingEnabled)
|
||||
if err != nil {
|
||||
logger.Fatal("error starting executor", zap.Error(err))
|
||||
}
|
||||
@@ -88,8 +91,8 @@ func runMQManager(logger *zap.Logger, routerURL string) {
|
||||
}
|
||||
}
|
||||
|
||||
func runStorageSvc(logger *zap.Logger, port int, storage storagesvc.Storage) {
|
||||
err := storagesvc.Start(logger, storage, port)
|
||||
func runStorageSvc(logger *zap.Logger, port int, storage storagesvc.Storage, openTracingEnabled bool) {
|
||||
err := storagesvc.Start(logger, storage, port, openTracingEnabled)
|
||||
if err != nil {
|
||||
logger.Fatal("error starting storage service", zap.Error(err))
|
||||
}
|
||||
@@ -124,13 +127,7 @@ func getStringArgWithDefault(arg interface{}, defaultValue string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func registerTraceExporter(logger *zap.Logger, arguments map[string]interface{}) error {
|
||||
collectorEndpoint := os.Getenv("TRACE_JAEGER_COLLECTOR_ENDPOINT")
|
||||
if len(collectorEndpoint) == 0 {
|
||||
logger.Info("skipping trace exporter registration")
|
||||
return nil
|
||||
}
|
||||
|
||||
func getServiceName(arguments map[string]interface{}) string {
|
||||
serviceName := "Fission-Unknown"
|
||||
|
||||
if arguments["--controllerPort"] != nil {
|
||||
@@ -153,26 +150,7 @@ func registerTraceExporter(logger *zap.Logger, arguments map[string]interface{})
|
||||
serviceName = "Fission-Keda-MQTrigger"
|
||||
}
|
||||
|
||||
exporter, err := jaeger.NewExporter(jaeger.Options{
|
||||
CollectorEndpoint: collectorEndpoint,
|
||||
Process: jaeger.Process{
|
||||
ServiceName: serviceName,
|
||||
Tags: []jaeger.Tag{
|
||||
jaeger.BoolTag("fission", true),
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
samplingRate, err := strconv.ParseFloat(os.Getenv("TRACING_SAMPLING_RATE"), 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trace.RegisterExporter(exporter)
|
||||
trace.ApplyConfig(trace.Config{DefaultSampler: trace.ProbabilitySampler(samplingRate)})
|
||||
return nil
|
||||
return serviceName
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -237,34 +215,32 @@ Options:
|
||||
--builderMgr Start builder manager.
|
||||
--version Print version information
|
||||
`
|
||||
|
||||
var logger *zap.Logger
|
||||
var config zap.Config
|
||||
|
||||
isDebugEnv, _ := strconv.ParseBool(os.Getenv("DEBUG_ENV"))
|
||||
if isDebugEnv {
|
||||
config = zap.NewDevelopmentConfig()
|
||||
config.DisableStacktrace = true
|
||||
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
} else {
|
||||
config = zap.NewProductionConfig()
|
||||
config.DisableStacktrace = true
|
||||
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
}
|
||||
logger, err = config.Build()
|
||||
if err != nil {
|
||||
log.Fatalf("I can't initialize zap logger: %v", err)
|
||||
}
|
||||
logger := loggerfactory.GetLogger()
|
||||
defer logger.Sync()
|
||||
|
||||
profile.ProfileIfEnabled(logger)
|
||||
|
||||
version := fmt.Sprintf("Fission Bundle Version: %v", info.BuildInfo().String())
|
||||
arguments, err := docopt.ParseArgs(usage, nil, version)
|
||||
if err != nil {
|
||||
logger.Fatal("Could not parse command line arguments", zap.Error(err))
|
||||
}
|
||||
|
||||
err = registerTraceExporter(logger, arguments)
|
||||
if err != nil {
|
||||
logger.Fatal("Could not register trace exporter", zap.Error(err), zap.Any("argument", arguments))
|
||||
ctx := context.Background()
|
||||
openTracingEnabled := tracing.TracingEnabled(logger)
|
||||
if openTracingEnabled {
|
||||
err = tracing.RegisterTraceExporter(logger, os.Getenv("TRACE_JAEGER_COLLECTOR_ENDPOINT"), getServiceName(arguments))
|
||||
if err != nil {
|
||||
logger.Fatal("Could not register trace exporter", zap.Error(err), zap.Any("argument", arguments))
|
||||
}
|
||||
} else {
|
||||
shutdown, err := otel.InitProvider(ctx, logger, getServiceName(arguments))
|
||||
if err != nil {
|
||||
logger.Fatal("error initializing provider for OTLP", zap.Error(err), zap.Any("argument", arguments))
|
||||
}
|
||||
if shutdown != nil {
|
||||
defer shutdown(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
functionNs := getStringArgWithDefault(arguments["--namespace"], "fission-function")
|
||||
@@ -276,17 +252,17 @@ Options:
|
||||
|
||||
if arguments["--controllerPort"] != nil {
|
||||
port := getPort(logger, arguments["--controllerPort"])
|
||||
runController(logger, port)
|
||||
runController(logger, port, openTracingEnabled)
|
||||
}
|
||||
|
||||
if arguments["--routerPort"] != nil {
|
||||
port := getPort(logger, arguments["--routerPort"])
|
||||
runRouter(logger, port, executorUrl)
|
||||
runRouter(logger, port, executorUrl, openTracingEnabled)
|
||||
}
|
||||
|
||||
if arguments["--executorPort"] != nil {
|
||||
port := getPort(logger, arguments["--executorPort"])
|
||||
runExecutor(logger, port, functionNs, envBuilderNs)
|
||||
runExecutor(logger, port, functionNs, envBuilderNs, openTracingEnabled)
|
||||
}
|
||||
|
||||
if arguments["--kubewatcher"] == true {
|
||||
@@ -323,7 +299,7 @@ Options:
|
||||
} else if arguments["--storageType"] == string(storagesvc.StorageTypeLocal) {
|
||||
storage = storagesvc.NewLocalStorage("/fission")
|
||||
}
|
||||
runStorageSvc(logger, port, storage)
|
||||
runStorageSvc(logger, port, storage, openTracingEnabled)
|
||||
}
|
||||
|
||||
select {}
|
||||
|
||||
@@ -1,45 +1,4 @@
|
||||
FROM golang:1.15-alpine as godep
|
||||
RUN apk add bash ca-certificates git gcc g++ libc-dev
|
||||
|
||||
ARG GOPKG=github.com/fission/fission
|
||||
|
||||
ENV GO111MODULE=on
|
||||
|
||||
WORKDIR /go/src/${GOPKG}
|
||||
|
||||
# To reuse build cache, copy go.mod & go.sum and download dependencies first.
|
||||
COPY go.* ./
|
||||
|
||||
RUN go mod download
|
||||
|
||||
FROM godep as builder
|
||||
|
||||
ARG GOPKG
|
||||
WORKDIR /go/src/${GOPKG}
|
||||
|
||||
# Copy whole fission directory to work dir
|
||||
COPY ./ ./
|
||||
|
||||
WORKDIR /go/src/${GOPKG}/cmd/preupgradechecks
|
||||
|
||||
ARG GITCOMMIT=unknown
|
||||
# E.g. GITCOMMIT=$(git rev-parse HEAD)
|
||||
|
||||
ARG BUILDVERSION=unknown
|
||||
# E.g. BUILDVERSION=$(git rev-parse HEAD)
|
||||
|
||||
ARG BUILDDATE=unknown
|
||||
# E.g. BUILDDATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
|
||||
RUN CGO_ENABLED=0 go build \
|
||||
-o /go/bin/pre-upgrade-checks \
|
||||
-gcflags=-trimpath=$GOPATH \
|
||||
-asmflags=-trimpath=$GOPATH \
|
||||
-ldflags "-X github.com/fission/fission/pkg/info.GitCommit=${GITCOMMIT} -X github.com/fission/fission/pkg/info.BuildDate=${BUILDDATE} -X github.com/fission/fission/pkg/info.Version=${BUILDVERSION}"
|
||||
|
||||
FROM alpine:3.13 as base
|
||||
FROM alpine:3.14
|
||||
RUN apk add --update ca-certificates
|
||||
COPY --from=builder /go/bin/pre-upgrade-checks /
|
||||
|
||||
COPY pre-upgrade-checks /
|
||||
ENTRYPOINT ["/pre-upgrade-checks"]
|
||||
EXPOSE 8001
|
||||
|
||||
@@ -17,13 +17,11 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/docopt/docopt-go"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"github.com/fission/fission/pkg/info"
|
||||
"github.com/fission/fission/pkg/utils/loggerfactory"
|
||||
)
|
||||
|
||||
func getStringArgWithDefault(arg interface{}, defaultValue string) string {
|
||||
@@ -35,13 +33,7 @@ func getStringArgWithDefault(arg interface{}, defaultValue string) string {
|
||||
}
|
||||
|
||||
func main() {
|
||||
config := zap.NewProductionConfig()
|
||||
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
logger, err := config.Build()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("can't initialize zap logger: %v", err)
|
||||
}
|
||||
logger := loggerfactory.GetLogger()
|
||||
defer logger.Sync()
|
||||
|
||||
usage := `Package to perform operations needed prior to fission installation
|
||||
|
||||
@@ -99,7 +99,7 @@ func (client *PreUpgradeTaskClient) LatestSchemaApplied() error {
|
||||
return errors.New("Could not get the Function CRD")
|
||||
}
|
||||
// Any new field added in Function spec can be checked here provided the substring matches the description in CRD Validation of the field
|
||||
if !strings.Contains(funcCRD.Spec.String(), "RequestsPerPod") || !strings.Contains(funcCRD.Spec.String(), "OnceOnly") {
|
||||
if !strings.Contains(funcCRD.Spec.String(), "RequestsPerPod") || !strings.Contains(funcCRD.Spec.String(), "OnceOnly") || !strings.Contains(funcCRD.Spec.String(), "PodSpec") {
|
||||
return errors.New("Apply the newer CRDs before upgrading")
|
||||
}
|
||||
|
||||
@@ -112,6 +112,7 @@ func (client *PreUpgradeTaskClient) LatestSchemaApplied() error {
|
||||
if !strings.Contains(mqtCRD.Spec.String(), "PodSpec") {
|
||||
return errors.New("Apply the newer CRDs before upgrading")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +1,4 @@
|
||||
FROM golang:1.15-alpine as godep
|
||||
RUN apk add bash ca-certificates git gcc g++ libc-dev
|
||||
|
||||
ARG GOPKG=github.com/fission/fission
|
||||
|
||||
ENV GO111MODULE=on
|
||||
|
||||
WORKDIR /go/src/${GOPKG}
|
||||
|
||||
# To reuse build cache, copy go.mod & go.sum and download dependencies first.
|
||||
COPY go.* ./
|
||||
|
||||
RUN go mod download
|
||||
|
||||
FROM godep as builder
|
||||
|
||||
ARG GOPKG
|
||||
WORKDIR /go/src/${GOPKG}
|
||||
|
||||
# Copy whole fission directory to work dir
|
||||
COPY ./ ./
|
||||
|
||||
WORKDIR /go/src/${GOPKG}/cmd/reporter
|
||||
|
||||
ARG GITCOMMIT=unknown
|
||||
# E.g. GITCOMMIT=$(git rev-parse HEAD)
|
||||
|
||||
ARG BUILDVERSION=unknown
|
||||
# E.g. BUILDVERSION=$(git rev-parse HEAD)
|
||||
|
||||
ARG BUILDDATE=unknown
|
||||
# E.g. BUILDDATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
|
||||
RUN CGO_ENABLED=0 go build \
|
||||
-o /go/bin/reporter \
|
||||
-gcflags=-trimpath=$GOPATH \
|
||||
-asmflags=-trimpath=$GOPATH \
|
||||
-ldflags "-X github.com/fission/fission/pkg/info.GitCommit=${GITCOMMIT} -X github.com/fission/fission/pkg/info.BuildDate=${BUILDDATE} -X github.com/fission/fission/pkg/info.Version=${BUILDVERSION}"
|
||||
|
||||
FROM alpine:3.13 as base
|
||||
FROM alpine:3.14
|
||||
RUN apk add --update ca-certificates
|
||||
COPY --from=builder /go/bin/reporter /
|
||||
COPY reporter /
|
||||
ENTRYPOINT ["/reporter"]
|
||||
@@ -18,8 +18,9 @@ package app
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/fission/fission/pkg/tracker"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/fission/fission/pkg/tracker"
|
||||
)
|
||||
|
||||
func eventCommandHandler(cmd *cobra.Command, args []string) error {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
# Custom Resource Definitions Reference
|
||||
|
||||
- [CanaryConfig](https://doc.crds.dev/github.com/fission/fission/fission.io/CanaryConfig/v1)
|
||||
- [Environment](https://doc.crds.dev/github.com/fission/fission/fission.io/Environment/v1)
|
||||
- [Function](https://doc.crds.dev/github.com/fission/fission/fission.io/Function/v1)
|
||||
- [HTTPTrigger](https://doc.crds.dev/github.com/fission/fission/fission.io/HTTPTrigger/v1)
|
||||
- [KubernetesWatchTrigger](https://doc.crds.dev/github.com/fission/fission/fission.io/KubernetesWatchTrigger/v1)
|
||||
- [MessageQueueTrigger](https://doc.crds.dev/github.com/fission/fission/fission.io/MessageQueueTrigger/v1)
|
||||
- [Package](https://doc.crds.dev/github.com/fission/fission/fission.io/Package/v1)
|
||||
- [TimeTrigger](https://doc.crds.dev/github.com/fission/fission/fission.io/TimeTrigger/v1)
|
||||
@@ -387,6 +387,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -506,13 +510,17 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
resources:
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
properties:
|
||||
limits:
|
||||
additionalProperties:
|
||||
@@ -521,7 +529,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -530,7 +538,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -618,7 +626,7 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
startupProbe:
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
properties:
|
||||
exec:
|
||||
description: One and only one of the following should be specified. Exec specifies the action to take.
|
||||
@@ -697,6 +705,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -940,8 +952,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -995,8 +1037,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -1049,8 +1121,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -1104,8 +1206,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -1466,6 +1598,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -1585,13 +1721,17 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
resources:
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
properties:
|
||||
limits:
|
||||
additionalProperties:
|
||||
@@ -1600,7 +1740,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -1609,7 +1749,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -1697,7 +1837,7 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
startupProbe:
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
properties:
|
||||
exec:
|
||||
description: One and only one of the following should be specified. Exec specifies the action to take.
|
||||
@@ -1776,6 +1916,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -2224,6 +2368,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -2339,6 +2487,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -2354,7 +2506,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -2363,7 +2515,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -2530,6 +2682,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -2986,6 +3142,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -3105,13 +3265,17 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
resources:
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
properties:
|
||||
limits:
|
||||
additionalProperties:
|
||||
@@ -3120,7 +3284,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -3129,7 +3293,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -3217,7 +3381,7 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
startupProbe:
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
properties:
|
||||
exec:
|
||||
description: One and only one of the following should be specified. Exec specifies the action to take.
|
||||
@@ -3296,6 +3460,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -3423,7 +3591,7 @@ spec:
|
||||
format: int64
|
||||
type: integer
|
||||
fsGroupChangePolicy:
|
||||
description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified defaults to "Always".'
|
||||
description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used.'
|
||||
type: string
|
||||
runAsGroup:
|
||||
description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container.
|
||||
@@ -3516,7 +3684,7 @@ spec:
|
||||
description: If specified, the fully qualified Pod hostname will be "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>". If not specified, the pod will not have a domainname at all.
|
||||
type: string
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.
|
||||
format: int64
|
||||
type: integer
|
||||
tolerations:
|
||||
@@ -3845,11 +4013,8 @@ spec:
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
ephemeral:
|
||||
description: "Ephemeral represents a volume that is handled by a cluster storage driver (Alpha feature). The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time."
|
||||
description: "Ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time. \n This is a beta feature and only available when the GenericEphemeralVolume feature gate is enabled."
|
||||
properties:
|
||||
readOnly:
|
||||
description: Specifies a read-only configuration for the volume. Defaults to false (read/write).
|
||||
type: boolean
|
||||
volumeClaimTemplate:
|
||||
description: "Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be `<pod name>-<volume name>` where `<volume name>` is the name from the `PodSpec.Volumes` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long). \n An existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. \n This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. \n Required, must not be nil."
|
||||
properties:
|
||||
@@ -3865,7 +4030,7 @@ spec:
|
||||
type: string
|
||||
type: array
|
||||
dataSource:
|
||||
description: 'This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot - Beta) * An existing PVC (PersistentVolumeClaim) * An existing custom resource/object that implements data population (Alpha) In order to use VolumeSnapshot object types, the appropriate feature gate must be enabled (VolumeSnapshotDataSource or AnyVolumeDataSource) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the specified data source is not supported, the volume will not be created and the failure will be reported as an event. In the future, we plan to support more data source types and the behavior of the provisioner may change.'
|
||||
description: 'This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) * An existing custom resource that implements data population (Alpha) In order to use custom resource types that implement data population, the AnyVolumeDataSource feature gate must be enabled. If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source.'
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.
|
||||
@@ -3890,7 +4055,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -3899,7 +4064,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
selector:
|
||||
@@ -4316,8 +4481,6 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- sources
|
||||
type: object
|
||||
quobyte:
|
||||
description: Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
|
||||
@@ -4525,7 +4688,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -4534,7 +4697,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
runtime:
|
||||
@@ -4883,6 +5046,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -5002,13 +5169,17 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
resources:
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
properties:
|
||||
limits:
|
||||
additionalProperties:
|
||||
@@ -5017,7 +5188,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -5026,7 +5197,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -5114,7 +5285,7 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
startupProbe:
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
properties:
|
||||
exec:
|
||||
description: One and only one of the following should be specified. Exec specifies the action to take.
|
||||
@@ -5193,6 +5364,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -5436,8 +5611,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -5491,8 +5696,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -5545,8 +5780,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -5600,8 +5865,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -5962,6 +6257,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -6081,13 +6380,17 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
resources:
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
properties:
|
||||
limits:
|
||||
additionalProperties:
|
||||
@@ -6096,7 +6399,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -6105,7 +6408,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -6193,7 +6496,7 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
startupProbe:
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
properties:
|
||||
exec:
|
||||
description: One and only one of the following should be specified. Exec specifies the action to take.
|
||||
@@ -6272,6 +6575,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -6720,6 +7027,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -6835,6 +7146,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -6850,7 +7165,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -6859,7 +7174,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -7026,6 +7341,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -7482,6 +7801,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -7601,13 +7924,17 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
resources:
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
properties:
|
||||
limits:
|
||||
additionalProperties:
|
||||
@@ -7616,7 +7943,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -7625,7 +7952,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -7713,7 +8040,7 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
startupProbe:
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
properties:
|
||||
exec:
|
||||
description: One and only one of the following should be specified. Exec specifies the action to take.
|
||||
@@ -7792,6 +8119,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -7919,7 +8250,7 @@ spec:
|
||||
format: int64
|
||||
type: integer
|
||||
fsGroupChangePolicy:
|
||||
description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified defaults to "Always".'
|
||||
description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used.'
|
||||
type: string
|
||||
runAsGroup:
|
||||
description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container.
|
||||
@@ -8012,7 +8343,7 @@ spec:
|
||||
description: If specified, the fully qualified Pod hostname will be "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>". If not specified, the pod will not have a domainname at all.
|
||||
type: string
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.
|
||||
format: int64
|
||||
type: integer
|
||||
tolerations:
|
||||
@@ -8341,11 +8672,8 @@ spec:
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
ephemeral:
|
||||
description: "Ephemeral represents a volume that is handled by a cluster storage driver (Alpha feature). The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time."
|
||||
description: "Ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time. \n This is a beta feature and only available when the GenericEphemeralVolume feature gate is enabled."
|
||||
properties:
|
||||
readOnly:
|
||||
description: Specifies a read-only configuration for the volume. Defaults to false (read/write).
|
||||
type: boolean
|
||||
volumeClaimTemplate:
|
||||
description: "Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be `<pod name>-<volume name>` where `<volume name>` is the name from the `PodSpec.Volumes` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long). \n An existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. \n This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. \n Required, must not be nil."
|
||||
properties:
|
||||
@@ -8361,7 +8689,7 @@ spec:
|
||||
type: string
|
||||
type: array
|
||||
dataSource:
|
||||
description: 'This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot - Beta) * An existing PVC (PersistentVolumeClaim) * An existing custom resource/object that implements data population (Alpha) In order to use VolumeSnapshot object types, the appropriate feature gate must be enabled (VolumeSnapshotDataSource or AnyVolumeDataSource) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the specified data source is not supported, the volume will not be created and the failure will be reported as an event. In the future, we plan to support more data source types and the behavior of the provisioner may change.'
|
||||
description: 'This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) * An existing custom resource that implements data population (Alpha) In order to use custom resource types that implement data population, the AnyVolumeDataSource feature gate must be enabled. If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source.'
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.
|
||||
@@ -8386,7 +8714,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -8395,7 +8723,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
selector:
|
||||
@@ -8812,8 +9140,6 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- sources
|
||||
type: object
|
||||
quobyte:
|
||||
description: Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -76,6 +76,9 @@ spec:
|
||||
description: TLS is for user to specify a Secret that contains TLS key and certificate. The domain name in the key and crt must match the value of Host field.
|
||||
type: string
|
||||
type: object
|
||||
keepPrefix:
|
||||
description: When function is exposed with Prefix based path, keepPrefix decides whether to keep or trim prefix in URL while invoking function.
|
||||
type: boolean
|
||||
method:
|
||||
description: Use Methods instead of Method. This field is going to be deprecated in a future release HTTP method to access a function.
|
||||
type: string
|
||||
|
||||
@@ -253,8 +253,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -308,8 +338,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -362,8 +422,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -417,8 +507,38 @@ spec:
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaceSelector:
|
||||
description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
namespaces:
|
||||
description: namespaces specifies which namespaces the labelSelector applies to (matches against); null or empty list means "this pod's namespace"
|
||||
description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace"
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
@@ -779,6 +899,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -898,13 +1022,17 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
resources:
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
properties:
|
||||
limits:
|
||||
additionalProperties:
|
||||
@@ -913,7 +1041,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -922,7 +1050,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -1010,7 +1138,7 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
startupProbe:
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
properties:
|
||||
exec:
|
||||
description: One and only one of the following should be specified. Exec specifies the action to take.
|
||||
@@ -1089,6 +1217,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -1537,6 +1669,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -1652,6 +1788,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -1667,7 +1807,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -1676,7 +1816,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -1843,6 +1983,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -2299,6 +2443,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -2418,13 +2566,17 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
resources:
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
properties:
|
||||
limits:
|
||||
additionalProperties:
|
||||
@@ -2433,7 +2585,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -2442,7 +2594,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
securityContext:
|
||||
@@ -2530,7 +2682,7 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
startupProbe:
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. This is a beta feature enabled by the StartupProbe feature flag. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
properties:
|
||||
exec:
|
||||
description: One and only one of the following should be specified. Exec specifies the action to take.
|
||||
@@ -2609,6 +2761,10 @@ spec:
|
||||
required:
|
||||
- port
|
||||
type: object
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
format: int64
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes'
|
||||
format: int32
|
||||
@@ -2736,7 +2892,7 @@ spec:
|
||||
format: int64
|
||||
type: integer
|
||||
fsGroupChangePolicy:
|
||||
description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified defaults to "Always".'
|
||||
description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used.'
|
||||
type: string
|
||||
runAsGroup:
|
||||
description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container.
|
||||
@@ -2829,7 +2985,7 @@ spec:
|
||||
description: If specified, the fully qualified Pod hostname will be "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>". If not specified, the pod will not have a domainname at all.
|
||||
type: string
|
||||
terminationGracePeriodSeconds:
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.
|
||||
description: Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.
|
||||
format: int64
|
||||
type: integer
|
||||
tolerations:
|
||||
@@ -3158,11 +3314,8 @@ spec:
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
ephemeral:
|
||||
description: "Ephemeral represents a volume that is handled by a cluster storage driver (Alpha feature). The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time."
|
||||
description: "Ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time. \n This is a beta feature and only available when the GenericEphemeralVolume feature gate is enabled."
|
||||
properties:
|
||||
readOnly:
|
||||
description: Specifies a read-only configuration for the volume. Defaults to false (read/write).
|
||||
type: boolean
|
||||
volumeClaimTemplate:
|
||||
description: "Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be `<pod name>-<volume name>` where `<volume name>` is the name from the `PodSpec.Volumes` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long). \n An existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. \n This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. \n Required, must not be nil."
|
||||
properties:
|
||||
@@ -3178,7 +3331,7 @@ spec:
|
||||
type: string
|
||||
type: array
|
||||
dataSource:
|
||||
description: 'This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot - Beta) * An existing PVC (PersistentVolumeClaim) * An existing custom resource/object that implements data population (Alpha) In order to use VolumeSnapshot object types, the appropriate feature gate must be enabled (VolumeSnapshotDataSource or AnyVolumeDataSource) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the specified data source is not supported, the volume will not be created and the failure will be reported as an event. In the future, we plan to support more data source types and the behavior of the provisioner may change.'
|
||||
description: 'This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) * An existing custom resource that implements data population (Alpha) In order to use custom resource types that implement data population, the AnyVolumeDataSource feature gate must be enabled. If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source.'
|
||||
properties:
|
||||
apiGroup:
|
||||
description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.
|
||||
@@ -3203,7 +3356,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
@@ -3212,7 +3365,7 @@ spec:
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
|
||||
description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
|
||||
type: object
|
||||
type: object
|
||||
selector:
|
||||
@@ -3629,8 +3782,6 @@ spec:
|
||||
type: object
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- sources
|
||||
type: object
|
||||
quobyte:
|
||||
description: Quobyte represents a Quobyte mount on the host that shares a pod's lifetime
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Git hooks
|
||||
|
||||
* pre-push: Check, build and test the changes.
|
||||
|
||||
```bash
|
||||
$ cp githooks/* .git/hooks/
|
||||
```
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
ROOT=`realpath $(dirname $0)/../..`
|
||||
pushd $ROOT
|
||||
make
|
||||
popd
|
||||
@@ -1,70 +1,78 @@
|
||||
module github.com/fission/fission
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.1.0
|
||||
github.com/Azure/azure-sdk-for-go v12.4.0-beta+incompatible
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.2.1
|
||||
github.com/Azure/azure-sdk-for-go v32.5.0+incompatible
|
||||
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/Shopify/sarama v1.23.1
|
||||
github.com/Shopify/sarama v1.29.1
|
||||
github.com/aws/aws-sdk-go v1.36.33 // indirect
|
||||
github.com/blend/go-sdk v1.20210116.5 // indirect
|
||||
github.com/bsm/sarama-cluster v2.1.15+incompatible
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 // indirect
|
||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7 // indirect
|
||||
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9
|
||||
github.com/dnaeon/go-vcr v1.1.0 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
||||
github.com/dsnet/compress v0.0.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/emicklei/go-restful v2.9.6+incompatible
|
||||
github.com/emicklei/go-restful-openapi v1.2.0
|
||||
github.com/fatih/color v1.12.0
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/go-git/go-git/v5 v5.2.0
|
||||
github.com/go-ini/ini v1.62.0 // indirect
|
||||
github.com/go-openapi/spec v0.19.3
|
||||
github.com/go-openapi/spec v0.19.5
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/gorilla/mux v1.7.0
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
|
||||
github.com/graymeta/stow v0.0.0-20180719215413-7b5498c561bb
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/imdario/mergo v0.3.9
|
||||
github.com/graymeta/stow v0.2.7
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/imdario/mergo v0.3.12
|
||||
github.com/influxdata/influxdb v1.2.0
|
||||
github.com/life1347/color v1.7.0
|
||||
github.com/marstr/guid v1.1.0 // indirect
|
||||
github.com/mholt/archiver v0.0.0-20180417220235-e4ef56d48eb0
|
||||
github.com/minio/minio-go v6.0.14+incompatible
|
||||
github.com/nats-io/nats-streaming-server v0.17.0
|
||||
github.com/nats-io/nats.go v1.9.1
|
||||
github.com/nats-io/stan.go v0.6.0
|
||||
github.com/nats-io/nats-streaming-server v0.22.0
|
||||
github.com/nats-io/nats.go v1.11.0
|
||||
github.com/nats-io/stan.go v0.9.0
|
||||
github.com/nwaples/rardecode v1.1.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/opencontainers/runc v0.1.1 // indirect
|
||||
github.com/opencontainers/runc v1.0.1 // indirect
|
||||
github.com/ory/dockertest v3.3.5+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/prometheus/common v0.10.0
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/prometheus/common v0.26.0
|
||||
github.com/robfig/cron v0.0.0-20180505203441-b41be1df6967
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/spf13/cobra v1.1.1
|
||||
github.com/spf13/cobra v1.2.1
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/ulikunitz/xz v0.5.9 // indirect
|
||||
github.com/wcharczuk/go-chart v2.0.1+incompatible
|
||||
go.opencensus.io v0.22.4
|
||||
go.uber.org/zap v1.10.0
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect
|
||||
k8s.io/api v0.19.2
|
||||
k8s.io/apiextensions-apiserver v0.19.2
|
||||
k8s.io/apimachinery v0.19.2
|
||||
k8s.io/client-go v0.19.2
|
||||
go.opencensus.io v0.23.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.23.0
|
||||
go.opentelemetry.io/contrib/propagators/aws v0.23.0
|
||||
go.opentelemetry.io/contrib/propagators/b3 v0.23.0
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v0.23.0
|
||||
go.opentelemetry.io/contrib/propagators/ot v0.23.0
|
||||
go.opentelemetry.io/otel v1.0.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0
|
||||
go.opentelemetry.io/otel/sdk v1.0.0
|
||||
go.opentelemetry.io/otel/trace v1.0.0
|
||||
go.uber.org/zap v1.19.1
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e
|
||||
google.golang.org/grpc v1.40.0
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
k8s.io/api v0.21.4
|
||||
k8s.io/apiextensions-apiserver v0.21.4
|
||||
k8s.io/apimachinery v0.21.4
|
||||
k8s.io/client-go v0.21.4
|
||||
k8s.io/klog v1.0.0
|
||||
k8s.io/metrics v0.19.2
|
||||
k8s.io/metrics v0.21.4
|
||||
sigs.k8s.io/controller-runtime v0.9.7
|
||||
)
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
FROM golang:1.16.3
|
||||
ENV GO111MODULE on
|
||||
RUN mkdir -p /go/src/github.com/fission
|
||||
RUN wget -qO- https://download.docker.com/linux/static/stable/x86_64/docker-17.03.0-ce.tgz | tar xvz -C /usr/local/bin/ --strip 1
|
||||
RUN wget -qO- https://get.helm.sh/helm-v3.3.0-linux-amd64.tar.gz | tar xvz -C /usr/local/bin/ --strip 1
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
#set -x
|
||||
|
||||
DIR=$(realpath $(dirname "$0"))/../
|
||||
export GITHUB_TOKEN=$(cat ~/.github-token)
|
||||
# ignore_tags lists tags which we dont want to include in the changelog
|
||||
# and non standard releases
|
||||
exclude_tags=$(tr '\n' ',' < hack/ignore_tags | sed 's/,$/\n/')
|
||||
github_changelog_generator -u fission -p fission -t "${GITHUB_TOKEN}" \
|
||||
--no-issues --exclude-labels "no-changelog" -o tmp_CHANGELOG.md \
|
||||
--exclude-tags $exclude_tags
|
||||
mv tmp_CHANGELOG.md "${DIR}"/CHANGELOG.md
|
||||
@@ -1 +0,0 @@
|
||||
kubectl get crds -o custom-columns=:metadata.name | grep 'fission.io' | xargs kubectl delete crds
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
DIR=$(realpath $(dirname "$0"))/../
|
||||
MANIFESTDIR=$(realpath "$DIR")/manifest
|
||||
|
||||
source $(realpath "${DIR}"/test/init_tools.sh)
|
||||
doit() {
|
||||
echo "! $*"
|
||||
"$@"
|
||||
}
|
||||
|
||||
check_charts_repo() {
|
||||
local chartsrepo=$1
|
||||
|
||||
if [ ! -d "$chartsrepo" ]; then
|
||||
echo "Error finding chart repo at $chartsrepo"
|
||||
exit 1
|
||||
fi
|
||||
echo "check_charts_repo == PASSED"
|
||||
}
|
||||
|
||||
update_chart_version() {
|
||||
local version=$1
|
||||
sed -i "s/^version.*/version\: ${version}/" charts/fission-core/Chart.yaml
|
||||
sed -i "s/^version.*/version\: ${version}/" charts/fission-all/Chart.yaml
|
||||
sed -i "s/appVersion.*/appVersion\: ${version}/" charts/fission-core/Chart.yaml
|
||||
sed -i "s/appVersion.*/appVersion\: ${version}/" charts/fission-all/Chart.yaml
|
||||
sed -i "s/\bimageTag:.*/imageTag\: ${version}/" charts/fission-core/values.yaml
|
||||
sed -i "s/\bimageTag:.*/imageTag\: ${version}/" charts/fission-all/values.yaml
|
||||
}
|
||||
|
||||
lint_charts() {
|
||||
helm lint charts/fission-all charts/fission-core
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "helm lint failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
build_charts() {
|
||||
mkdir -p "$MANIFESTDIR"/charts
|
||||
pushd "$DIR"/charts
|
||||
find . -iname *.~?~ | xargs -r rm
|
||||
for c in fission-all fission-core; do
|
||||
doit helm package -u $c/
|
||||
mv ./*.tgz "$MANIFESTDIR"/charts/
|
||||
done
|
||||
popd
|
||||
}
|
||||
|
||||
build_yamls() {
|
||||
local version=$1
|
||||
|
||||
mkdir -p "${MANIFESTDIR}"/yamls
|
||||
pushd "${DIR}"/charts
|
||||
find . -iname *.~?~ | xargs -r rm
|
||||
|
||||
releaseName=fission-$(echo "${version}" | sed 's/\./-/g')
|
||||
|
||||
for c in fission-all fission-core; do
|
||||
# fetch dependencies
|
||||
pushd ${c}
|
||||
doit helm dependency update
|
||||
popd
|
||||
|
||||
echo "Release name", "$releaseName"
|
||||
cmdprefix="helm template ${releaseName} ${c} --namespace fission --validate"
|
||||
|
||||
# for minikube and other environments that don't support LoadBalancer
|
||||
command="$cmdprefix --set analytics=false,analyticsNonHelmInstall=true,serviceType=NodePort,routerServiceType=NodePort"
|
||||
echo "$command"
|
||||
$command >${c}-"${version}"-minikube.yaml
|
||||
|
||||
# for environments that support LoadBalancer
|
||||
command="$cmdprefix --set analytics=false,analyticsNonHelmInstall=true"
|
||||
echo "$command"
|
||||
$command >${c}-"${version}".yaml
|
||||
|
||||
# for OpenShift
|
||||
command="$cmdprefix --set analytics=false,analyticsNonHelmInstall=true,logger.enableSecurityContext=true,prometheus.enabled=false"
|
||||
echo "$command"
|
||||
$command >${c}-"${version}"-openshift.yaml
|
||||
|
||||
# copy yaml files to build directory
|
||||
mv ./*.yaml "${MANIFESTDIR}"/yamls/
|
||||
done
|
||||
|
||||
popd
|
||||
}
|
||||
|
||||
update_github_charts_repo() {
|
||||
local version=$1
|
||||
local chartsrepo=$2
|
||||
|
||||
pushd "$chartsrepo"
|
||||
cp "$MANIFESTDIR"/charts/fission-all-"${version}".tgz .
|
||||
cp "$MANIFESTDIR"/charts/fission-core-"${version}".tgz .
|
||||
./index.sh
|
||||
popd
|
||||
}
|
||||
|
||||
version=$1
|
||||
if [ -z "$version" ]; then
|
||||
echo "Release version not mentioned"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Current version for release: $version"
|
||||
|
||||
chartsrepo="$DIR../fission-charts"
|
||||
check_charts_repo "$chartsrepo"
|
||||
|
||||
# Build manifests and charts
|
||||
lint_charts
|
||||
update_chart_version "$version"
|
||||
lint_charts
|
||||
build_yamls "$version"
|
||||
build_charts
|
||||
update_github_charts_repo "$version" "$chartsrepo"
|
||||
@@ -0,0 +1,33 @@
|
||||
v1.14.1
|
||||
v1.14.0
|
||||
v1.13.1
|
||||
v1.13.0
|
||||
v1.12.0
|
||||
v1.11.2
|
||||
v1.11.1
|
||||
v1.11.0
|
||||
v1.10.0
|
||||
v1.9.0
|
||||
v1.8.0
|
||||
v1.7.1
|
||||
v1.7.0
|
||||
1.7.0-rc.2
|
||||
v1.7.0-rc.2
|
||||
1.7.0-rc.1
|
||||
v1.7.0-rc.1
|
||||
v1.6.0
|
||||
1.0-rc2
|
||||
1.0-rc1
|
||||
latest
|
||||
0.4.0rc
|
||||
0.3.0-rc
|
||||
buildmgr-preview-20170922
|
||||
buildmgr-preview-20170921
|
||||
v0.2.1
|
||||
v0.2.1-rc2
|
||||
v0.2.1-rc
|
||||
v0.2.0-20170901
|
||||
nightly20170705
|
||||
nightly20170621
|
||||
alpha20170124
|
||||
kubecon
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
API_GROUP_VERSIONS="
|
||||
core/v1
|
||||
"
|
||||
API_PACKAGES="
|
||||
"
|
||||
Regular → Executable
+2
-13
@@ -9,18 +9,7 @@ if [ -z $version ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gittag=$version
|
||||
prefix="v"
|
||||
gopkgtag=${version/#/${prefix}}
|
||||
|
||||
if [[ ${version} == v* ]]; then # if version starts with "v", don't append prefix.
|
||||
gopkgtag=${version}
|
||||
fi
|
||||
|
||||
# tag the release
|
||||
doit git tag $gittag
|
||||
doit git tag -a $gopkgtag -m "Fission $gopkgtag"
|
||||
|
||||
doit git tag $version
|
||||
# push tag
|
||||
doit git push origin $gittag
|
||||
doit git push origin $gopkgtag
|
||||
doit git push origin $version
|
||||
+27
-249
@@ -4,24 +4,29 @@ set -e
|
||||
#set -x
|
||||
|
||||
DIR=$(realpath $(dirname "$0"))/../
|
||||
BUILDDIR=$(realpath "$DIR")/build
|
||||
|
||||
artifacts=()
|
||||
source $(realpath "${DIR}"/test/init_tools.sh)
|
||||
MANIFESTDIR=$(realpath "$DIR")/manifest
|
||||
|
||||
doit() {
|
||||
echo "! $*"
|
||||
"$@"
|
||||
}
|
||||
|
||||
# Ensure we're on the master branch
|
||||
check_branch() {
|
||||
local version=$1
|
||||
curr_branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [ "$curr_branch" != "release-${version}" ]; then
|
||||
echo "Not on release-${version} branch."
|
||||
check_commands() {
|
||||
if ! command -v goreleaser >/dev/null; then
|
||||
echo "Goreleaser CLI not found. Please get from https://goreleaser.com/install/"
|
||||
exit 1
|
||||
fi
|
||||
echo "check_commands == PASSED"
|
||||
}
|
||||
|
||||
# Ensure we're on the master branch
|
||||
check_branch() {
|
||||
curr_branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [ "$curr_branch" != "master" ]; then
|
||||
echo "Not on master branch."
|
||||
exit 1
|
||||
fi
|
||||
echo "check_branch == PASSED"
|
||||
}
|
||||
|
||||
# Ensure working dir is clean
|
||||
@@ -30,232 +35,15 @@ check_clean() {
|
||||
echo "Unclean tree"
|
||||
exit 1
|
||||
fi
|
||||
echo "check_clean == PASSED"
|
||||
}
|
||||
|
||||
attach_github_release_cli() {
|
||||
# cli
|
||||
echo "Artifact for osx amd64 cli"
|
||||
artifacts+=("$BUILDDIR/bin/fission-$version-darwin-amd64")
|
||||
echo "Artifact for windows amd64 cli"
|
||||
artifacts+=("$BUILDDIR/bin/fission-$version-windows-amd64.exe")
|
||||
echo "Artifact for linux amd64 cli"
|
||||
artifacts+=("$BUILDDIR/bin/fission-$version-linux-amd64")
|
||||
echo "Artifact for linux arm cli"
|
||||
artifacts+=("$BUILDDIR/bin/fission-$version-linux-arm")
|
||||
echo "Artifact for linux arm64 cli"
|
||||
artifacts+=("$BUILDDIR/bin/fission-$version-linux-arm64")
|
||||
}
|
||||
|
||||
attach_github_release_charts() {
|
||||
local version=$1
|
||||
echo "fission-all chart"
|
||||
artifacts+=("$BUILDDIR/charts/fission-all-$version.tgz")
|
||||
echo "Fission-core chart"
|
||||
artifacts+=("$BUILDDIR/charts/fission-core-$version.tgz")
|
||||
}
|
||||
|
||||
attach_github_release_yamls() {
|
||||
local version=$1
|
||||
|
||||
for c in fission-all fission-core; do
|
||||
# YAML
|
||||
artifacts+=("$BUILDDIR/yamls/${c}-${version}-minikube.yaml")
|
||||
artifacts+=("$BUILDDIR/yamls/${c}-${version}.yaml")
|
||||
artifacts+=("$BUILDDIR/yamls/${c}-${version}-openshift.yaml")
|
||||
done
|
||||
}
|
||||
|
||||
update_github_charts_repo() {
|
||||
local version=$1
|
||||
local chartsrepo=$2
|
||||
|
||||
pushd "$chartsrepo"
|
||||
cp "$BUILDDIR"/charts/fission-all-"${version}".tgz .
|
||||
cp "$BUILDDIR"/charts/fission-core-"${version}".tgz .
|
||||
./index.sh
|
||||
popd
|
||||
}
|
||||
|
||||
gh_release() {
|
||||
local version=$1
|
||||
cp "${DIR}"/hack/notes.md relnotes.md
|
||||
create_downloads_table ${version} >> relnotes.md
|
||||
doit gh release create "$version" --draft --prerelease --title "$version" --notes-file $(realpath "${DIR}"/relnotes.md) --target "$gitcommit" "${artifacts[@]}"
|
||||
}
|
||||
|
||||
generate_changelog() {
|
||||
local version=$1
|
||||
|
||||
echo "# ${version}" >new_CHANGELOG.md
|
||||
echo
|
||||
echo "[Documentation](https://docs.fission.io/)" >>new_CHANGELOG.md
|
||||
echo
|
||||
|
||||
# generate changelog from github
|
||||
github_changelog_generator -u fission -p fission -t "${GITHUB_TOKEN}" --future-release "${version}" --no-issues -o tmp_CHANGELOG.md
|
||||
sed -i '$ d' tmp_CHANGELOG.md
|
||||
|
||||
# concatenate two files
|
||||
cat tmp_CHANGELOG.md >>new_CHANGELOG.md
|
||||
mv new_CHANGELOG.md "${DIR}"/CHANGELOG.md
|
||||
|
||||
rm tmp_CHANGELOG.md
|
||||
}
|
||||
|
||||
create_downloads_table() {
|
||||
local release_tag=$1
|
||||
local url_prefix="https://github.com/fission/fission/releases/download"
|
||||
|
||||
echo
|
||||
echo
|
||||
echo "#### Downloads for ${version}"
|
||||
echo
|
||||
|
||||
echo
|
||||
echo "filename | sha256 hash"
|
||||
echo "-------- | -----------"
|
||||
for file in ${artifacts[@]}; do
|
||||
filename=${file##*/}
|
||||
echo "[${filename}]($url_prefix/$release_tag/${filename}) | \`$(shasum -a 256 ${file} | cut -d' ' -f 1)\`"
|
||||
done
|
||||
echo
|
||||
}
|
||||
export -f create_downloads_table
|
||||
|
||||
release_environment_check() {
|
||||
local version=$1
|
||||
local chartsrepo=$2
|
||||
|
||||
check_branch "$version"
|
||||
check_clean
|
||||
|
||||
check_github_token() {
|
||||
if [ ! -f "$HOME"/.github-token ]; then
|
||||
echo "Error finding github access token at ${HOME}/.github-token"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$chartsrepo" ]; then
|
||||
echo "Error finding chart repo at $chartsrepo"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
build_charts() {
|
||||
local version=$1
|
||||
mkdir -p "$BUILDDIR"/charts
|
||||
pushd "$DIR"/charts
|
||||
find . -iname *.~?~ | xargs -r rm
|
||||
for c in fission-all fission-core; do
|
||||
doit helm package -u $c/
|
||||
mv ./*.tgz "$BUILDDIR"/charts/
|
||||
done
|
||||
popd
|
||||
}
|
||||
|
||||
build_yamls() {
|
||||
local version=$1
|
||||
|
||||
mkdir -p "${BUILDDIR}"/yamls
|
||||
pushd "${DIR}"/charts
|
||||
find . -iname *.~?~ | xargs -r rm
|
||||
|
||||
releaseName=fission-$(echo "${version}" | sed 's/\./-/g')
|
||||
|
||||
for c in fission-all fission-core; do
|
||||
# fetch dependencies
|
||||
pushd ${c}
|
||||
doit helm dependency update
|
||||
popd
|
||||
|
||||
echo "Release name", "$releaseName"
|
||||
cmdprefix="helm template ${releaseName} ${c} --namespace fission --validate"
|
||||
|
||||
# for minikube and other environments that don't support LoadBalancer
|
||||
command="$cmdprefix --set analytics=false,analyticsNonHelmInstall=true,serviceType=NodePort,routerServiceType=NodePort"
|
||||
echo "$command"
|
||||
$command >${c}-"${version}"-minikube.yaml
|
||||
|
||||
# for environments that support LoadBalancer
|
||||
command="$cmdprefix --set analytics=false,analyticsNonHelmInstall=true"
|
||||
echo "$command"
|
||||
$command >${c}-"${version}".yaml
|
||||
|
||||
# for OpenShift
|
||||
command="$cmdprefix --set analytics=false,analyticsNonHelmInstall=true,logger.enableSecurityContext=true,prometheus.enabled=false"
|
||||
echo "$command"
|
||||
$command >${c}-"${version}"-openshift.yaml
|
||||
|
||||
# copy yaml files to build directory
|
||||
mv ./*.yaml "${BUILDDIR}"/yamls/
|
||||
done
|
||||
|
||||
popd
|
||||
}
|
||||
|
||||
build_all() {
|
||||
local version=$1
|
||||
|
||||
if [ -z "$version" ]; then
|
||||
echo "Version unspecified"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local date=$2
|
||||
|
||||
if [ -z "$date" ]; then
|
||||
echo "Build date unspecified"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local gitcommit=$3
|
||||
|
||||
if [ -z "$gitcommit" ]; then
|
||||
echo "Git commit unspecified"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -e "$BUILDDIR" ]; then
|
||||
echo "Removing existing build dir ($BUILDDIR)."
|
||||
rm -rf "$BUILDDIR"
|
||||
fi
|
||||
|
||||
mkdir -p "$BUILDDIR"
|
||||
|
||||
# generate swagger (OpenApi 2.0) doc before building bundle image
|
||||
VERSION=$version TIMESTAMP=$date COMMITSHA=$gitcommit make generate-swagger-doc
|
||||
|
||||
# Build CLI for all platforms
|
||||
VERSION=$version TIMESTAMP=$date COMMITSHA=$gitcommit make all-fission-cli
|
||||
}
|
||||
|
||||
build_images() {
|
||||
local version=$1
|
||||
if [ -z "$version" ]; then
|
||||
echo "Version unspecified"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local date=$2
|
||||
if [ -z "$date" ]; then
|
||||
echo "Build date unspecified"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local gitcommit=$3
|
||||
if [ -z "$gitcommit" ]; then
|
||||
echo "Git commit unspecified"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build and push all images
|
||||
REPO=fission VERSION=$version TAG=latest TIMESTAMP=$date COMMITSHA=$gitcommit make all-images
|
||||
REPO=fission VERSION=$version TAG=$version TIMESTAMP=$date COMMITSHA=$gitcommit make all-images
|
||||
}
|
||||
|
||||
check_commands() {
|
||||
if ! command -v hub >/dev/null; then
|
||||
echo "Github CLI hub not found. Please get from https://cli.github.com/"
|
||||
fi
|
||||
echo "check_github_token == PASSED"
|
||||
}
|
||||
|
||||
export GITHUB_TOKEN=$(cat ~/.github-token)
|
||||
@@ -266,29 +54,19 @@ if [ -z "$version" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
gitcommit=$(git rev-parse HEAD)
|
||||
echo "Current version for release: $version"
|
||||
|
||||
chartsrepo=$2
|
||||
if [ -z "$chartsrepo" ]; then
|
||||
chartsrepo="$DIR../fission-charts"
|
||||
fi
|
||||
chartsrepo="$DIR../fission-charts"
|
||||
|
||||
# Prechecks
|
||||
check_clean
|
||||
check_commands
|
||||
release_environment_check "$version" "$chartsrepo"
|
||||
build_all "$version" "$date" "$gitcommit"
|
||||
build_charts "$version"
|
||||
build_yamls "$version"
|
||||
check_branch
|
||||
check_github_token
|
||||
|
||||
attach_github_release_cli "$version"
|
||||
attach_github_release_charts "$version"
|
||||
attach_github_release_yamls "$version"
|
||||
update_github_charts_repo "$version" "$chartsrepo"
|
||||
gh_release "$version"
|
||||
|
||||
generate_changelog "$version"
|
||||
|
||||
build_images "$version" "$date" "$gitcommit"
|
||||
export GORELEASER_CURRENT_TAG=$version
|
||||
echo "Release version $GORELEASER_CURRENT_TAG "
|
||||
goreleaser release
|
||||
|
||||
echo "############ DONE #############"
|
||||
echo "Congratulation, ${version} is ready to ship !!"
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ echo "" > coverage.txt
|
||||
# The executor unit test only works with NodePort-type services for
|
||||
# now. So disable it for our travis ci tests except some partial tests.
|
||||
for d in $(go list ./... | grep -v '/vendor/' | grep -v 'examples/go' | grep -v executor | grep -v 'benchmark') github.com/fission/fission/pkg/executor/util; do
|
||||
go test -v -coverprofile=profile.out -covermode=atomic $d
|
||||
go test -race -v -coverprofile=profile.out -covermode=atomic $d
|
||||
if [ -f profile.out ]; then
|
||||
cat profile.out >> coverage.txt
|
||||
rm profile.out
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Download kubectl, save kubeconfig, and ensure we can access the test cluster
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
TOOL_DIR=$HOME/tool
|
||||
|
||||
if [ ! -d $TOOL_DIR ]
|
||||
then
|
||||
mkdir -p $TOOL_DIR
|
||||
fi
|
||||
|
||||
# Get staticcheck
|
||||
STATICCHECK_VERSION=2019.2.3
|
||||
if [ ! -f $TOOL_DIR/staticcheck ] || (staticcheck -version | grep -v $STATICCHECK_VERSION)
|
||||
then
|
||||
curl -LO https://github.com/dominikh/go-tools/releases/download/${STATICCHECK_VERSION}/staticcheck_linux_amd64.tar.gz
|
||||
tar xzvf staticcheck_linux_amd64.tar.gz
|
||||
mv staticcheck/staticcheck $TOOL_DIR/staticcheck
|
||||
fi
|
||||
|
||||
K8SCLI_DIR=$HOME/k8scli
|
||||
|
||||
if [ ! -d $K8SCLI_DIR ]
|
||||
then
|
||||
mkdir -p $K8SCLI_DIR
|
||||
fi
|
||||
|
||||
# Get helm
|
||||
HELM_VERSION=3.3.0
|
||||
if [ ! -f $K8SCLI_DIR/helm ] || (helm version --client | grep -v $HELM_VERSION)
|
||||
then
|
||||
curl -LO https://get.helm.sh/helm-v3.3.0-linux-amd64.tar.gz
|
||||
tar xzvf helm-*.tar.gz
|
||||
mv linux-amd64/helm $K8SCLI_DIR/helm
|
||||
fi
|
||||
|
||||
# If we don't have gcloud credentials, bail out of these tests.
|
||||
if [ -z "$FISSION_CI_SERVICE_ACCOUNT" ]
|
||||
then
|
||||
echo "Skipping tests, no cluster credentials"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get kubectl
|
||||
if [ ! -f $K8SCLI_DIR/kubectl ]
|
||||
then
|
||||
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
|
||||
chmod +x ./kubectl
|
||||
mv kubectl $K8SCLI_DIR/kubectl
|
||||
fi
|
||||
|
||||
mkdir ${HOME}/.kube
|
||||
|
||||
# echo $KUBECONFIG_CONTENTS | base64 -D - > ${HOME}/.kube/config
|
||||
# kubectl version
|
||||
|
||||
# gcloud stuff
|
||||
# https://stackoverflow.com/questions/38762590/how-to-install-google-cloud-sdk-on-travis
|
||||
|
||||
if [ ! -d "${HOME}/google-cloud-sdk/bin" ]
|
||||
then
|
||||
rm -rf $HOME/google-cloud-sdk
|
||||
export CLOUDSDK_CORE_DISABLE_PROMPTS=1
|
||||
curl https://sdk.cloud.google.com | bash
|
||||
fi
|
||||
|
||||
# ensure we have the gcloud binary
|
||||
gcloud version
|
||||
|
||||
# get gcloud credentials
|
||||
echo $FISSION_CI_SERVICE_ACCOUNT | base64 -d - > ${HOME}/gcloud-service-key.json
|
||||
gcloud auth activate-service-account --key-file ${HOME}/gcloud-service-key.json
|
||||
|
||||
# get kube config
|
||||
gcloud container clusters get-credentials fission-ci --zone us-central1-a --project $GKE_PROJECT_NAME
|
||||
|
||||
# remove gcloud creds
|
||||
unset FISSION_CI_SERVICE_ACCOUNT
|
||||
rm ${HOME}/gcloud-service-key.json
|
||||
|
||||
# does it work?
|
||||
|
||||
if [ ! -f ${HOME}/.kube/config ]
|
||||
then
|
||||
echo "Missing kubeconfig"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kubectl get node
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
if [ ! -d "../code-generator" ]; then
|
||||
echo "Please get code-generator from fission org"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||
CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)}
|
||||
|
||||
bash "${CODEGEN_PKG}"/generate-groups.sh "deepcopy,client,informer,lister" \
|
||||
github.com/fission/fission/pkg/generated \
|
||||
github.com/fission/fission/pkg/apis \
|
||||
"core:v1" \
|
||||
--output-base "$(dirname "${BASH_SOURCE[0]}")/../../../.." \
|
||||
--go-header-file "$(dirname "${BASH_SOURCE[0]}")/boilerplate.txt"
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
source "$(dirname "${BASH_SOURCE}")/lib/init.sh"
|
||||
|
||||
SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||
|
||||
# Generates types_swagger_doc_generated file for the given group version.
|
||||
# $1: Name of the group version
|
||||
# $2: Path to the directory where types.go for that group version exists. This
|
||||
# is the directory where the file will be generated.
|
||||
kube::swagger::gen_types_swagger_doc() {
|
||||
local group_version=$1
|
||||
local gv_dir=$2
|
||||
local TMPFILE="${TMPDIR:-/tmp}/zz_generated.swagger_doc_generated.$(date +%s).go"
|
||||
|
||||
echo "Generating swagger type docs for ${group_version} at ${gv_dir}"
|
||||
|
||||
sed 's/YEAR/2017/' hack/boilerplate.txt > "$TMPFILE"
|
||||
echo "package ${group_version##*/}" >> "$TMPFILE"
|
||||
cat >> "$TMPFILE" <<EOF
|
||||
// This file contains a collection of methods that can be used from go-restful to
|
||||
// generate Swagger API documentation for its models. Please read this PR for more
|
||||
// information on the implementation: https://github.com/emicklei/go-restful/pull/215
|
||||
//
|
||||
// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if
|
||||
// they are on one line! For multiple line or blocks that you want to ignore use ---.
|
||||
// Any context after a --- is ignored.
|
||||
//
|
||||
// Those methods can be generated by using hack/update-swagger-docs.sh
|
||||
// AUTO-GENERATED FUNCTIONS START HERE
|
||||
EOF
|
||||
|
||||
go run tools/genswaggertypedocs/swagger_type_docs.go -s \
|
||||
${gv_dir}/types*.go \
|
||||
-f - \
|
||||
>> "$TMPFILE"
|
||||
|
||||
echo "// AUTO-GENERATED FUNCTIONS END HERE" >> "$TMPFILE"
|
||||
|
||||
gofmt -w -s "$TMPFILE"
|
||||
mv "$TMPFILE" ""${gv_dir}"/zz_generated.swagger_doc_generated.go"
|
||||
}
|
||||
|
||||
util::group-version-to-pkg-path() {
|
||||
local group_version="$1"
|
||||
echo "pkg/apis/${group_version}"
|
||||
}
|
||||
|
||||
for gv in ${API_GROUP_VERSIONS}; do
|
||||
rm -f "${SCRIPT_ROOT}/${gv}/zz_generated.swagger_doc_generated.go"
|
||||
util::group-version-to-pkg-path "${gv}"
|
||||
kube::swagger::gen_types_swagger_doc "${gv}" "$(util::group-version-to-pkg-path "${gv}")"
|
||||
done
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
find_files() {
|
||||
find . -not \( \
|
||||
\( \
|
||||
-wholename '*/vendor/*' \
|
||||
\) -prune \
|
||||
\) -name '*.go'
|
||||
}
|
||||
|
||||
GOFMT="gofmt -s"
|
||||
bad_files=$(find_files | xargs $GOFMT -l)
|
||||
if [[ -n "${bad_files}" ]]; then
|
||||
echo "!!! '$GOFMT' needs to be run on the following files: "
|
||||
echo "${bad_files}"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
go vet -v $(go list ./...| grep -v "vendor" | grep -v "examples" | grep -v "genclient" | grep -v "demos" | grep -v "test")
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
go list ./...| grep -v vendor | grep -v "examples" | grep -v "demos" | grep -v "genclient" | grep -v "test" | xargs -I@ staticcheck @
|
||||
@@ -8,7 +8,6 @@ kind: Cluster
|
||||
apiVersion: kind.x-k8s.io/v1alpha4
|
||||
nodes:
|
||||
- role: control-plane
|
||||
image: kindest/node:v1.19.11
|
||||
kubeadmConfigPatches:
|
||||
- |
|
||||
kind: InitConfiguration
|
||||
@@ -22,4 +21,4 @@ nodes:
|
||||
protocol: TCP
|
||||
- containerPort: 443
|
||||
hostPort: 443
|
||||
protocol: TCP
|
||||
protocol: TCP
|
||||
|
||||
+3
-9
@@ -1,18 +1,12 @@
|
||||
# Fission CRD generation
|
||||
|
||||
* Clone https://github.com/fission/code-generator to generate fission CRD object deepcopy and client methods.
|
||||
* Clone [code-generator](https://github.com/fission/code-generator) to generate fission CRD object deepcopy and client methods.
|
||||
* MUST run code-generator in the fission root directory.
|
||||
|
||||
``` bash
|
||||
$ cd $GOPATH/src/github.com/fission/fission/
|
||||
$ bash $GOPATH/src/k8s.io/code-generator/generate-groups.sh \
|
||||
all \
|
||||
github.com/fission/fission/pkg/apis/genclient \
|
||||
github.com/fission/fission/pkg/apis \
|
||||
"core:v1" \
|
||||
--go-header-file $GOPATH/src/github.com/fission/fission/pkg/apis/boilerplate.txt
|
||||
$ make codgen
|
||||
```
|
||||
|
||||
# Reference
|
||||
## Reference
|
||||
|
||||
* https://blog.openshift.com/kubernetes-deep-dive-code-generation-customresources/
|
||||
|
||||
@@ -55,6 +55,7 @@ const (
|
||||
const (
|
||||
ExecutorTypePoolmgr ExecutorType = "poolmgr"
|
||||
ExecutorTypeNewdeploy ExecutorType = "newdeploy"
|
||||
ExecutorTypeContainer ExecutorType = "container"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# How to update swagger (OpenAPI) struct description
|
||||
|
||||
Run `update-generated-swagger-docs.sh` and it will parse all comments in `types.go`.
|
||||
|
||||
```bash
|
||||
./update-generated-swagger-docs.sh
|
||||
```
|
||||
@@ -1,67 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2016 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
#
|
||||
# Please refer https://github.com/kubernetes/kubernetes/tree/master/hack for original file
|
||||
#
|
||||
|
||||
# Contains swagger related util functions.
|
||||
#
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# Generates types_swagger_doc_generated file for the given group version.
|
||||
# $1: Name of the group version
|
||||
# $2: Path to the directory where types.go for that group version exists. This
|
||||
# is the directory where the file will be generated.
|
||||
kube::swagger::gen_types_swagger_doc() {
|
||||
local group_version=$1
|
||||
local gv_dir=$2
|
||||
local TMPFILE
|
||||
TMPFILE="${TMPDIR:-/tmp}/types_swagger_doc_generated.$(date +%s).go"
|
||||
|
||||
echo "Generating swagger type docs for ${group_version} at ${gv_dir}"
|
||||
|
||||
{
|
||||
echo -e "$(cat boilerplate.generatego.txt)\n"
|
||||
echo "package ${group_version##*/}"
|
||||
cat <<EOF
|
||||
|
||||
// This file contains a collection of methods that can be used from go-restful to
|
||||
// generate Swagger API documentation for its models. Please read this PR for more
|
||||
// information on the implementation: https://github.com/emicklei/go-restful/pull/215
|
||||
//
|
||||
// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if
|
||||
// they are on one line! For multiple line or blocks that you want to ignore use ---.
|
||||
// Any context after a --- is ignored.
|
||||
//
|
||||
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
|
||||
EOF
|
||||
} > "${TMPFILE}"
|
||||
|
||||
go run ./swagger_type_docs.go -s \
|
||||
"${gv_dir}/types.go" \
|
||||
-f - \
|
||||
>> "${TMPFILE}"
|
||||
|
||||
echo "// AUTO-GENERATED FUNCTIONS END HERE" >> "${TMPFILE}"
|
||||
|
||||
gofmt -w -s "${TMPFILE}"
|
||||
mv "${TMPFILE}" "${gv_dir}/types_swagger_doc_generated.go"
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2015 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Generates `types_swagger_doc_generated.go` files for API group
|
||||
# versions. That file contains functions on API structs that return
|
||||
# the comments that should be surfaced for the corresponding API type
|
||||
# in our API docs.
|
||||
|
||||
|
||||
#
|
||||
# Please refer https://github.com/kubernetes/kubernetes/tree/master/hack for original file
|
||||
#
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
FISSION_CRD_VERSION=v1
|
||||
|
||||
source "swagger.sh"
|
||||
|
||||
# To avoid compile errors, remove the currently existing files.
|
||||
|
||||
for group_version in "${FISSION_CRD_VERSION}"; do
|
||||
kube::swagger::gen_types_swagger_doc "${group_version}" ../../${FISSION_CRD_VERSION}
|
||||
done
|
||||
@@ -409,6 +409,11 @@ type (
|
||||
// This is optional. If not specified default value will be taken as false
|
||||
// +optional
|
||||
OnceOnly bool `json:"onceOnly,omitempty"`
|
||||
|
||||
// Podspec specifies podspec to use for executor type container based functions
|
||||
// Different arguments mentioned for container based function are populated inside a pod.
|
||||
// +optional
|
||||
PodSpec *apiv1.PodSpec `json:"podspec,omitempty"`
|
||||
}
|
||||
|
||||
// InvokeStrategy is a set of controls over how the function executes.
|
||||
@@ -450,6 +455,7 @@ type (
|
||||
// Available value:
|
||||
// - poolmgr
|
||||
// - newdeploy
|
||||
// - container
|
||||
// +optional
|
||||
ExecutorType ExecutorType `json:"ExecutorType"`
|
||||
|
||||
@@ -658,6 +664,11 @@ type (
|
||||
// +optional
|
||||
Prefix *string `json:"prefix,omitempty"`
|
||||
|
||||
// When function is exposed with Prefix based path,
|
||||
// keepPrefix decides whether to keep or trim prefix in URL while invoking function.
|
||||
// +optional
|
||||
KeepPrefix bool `json:"keepPrefix,omitempty"`
|
||||
|
||||
// Use Methods instead of Method. This field is going to be deprecated in a future release
|
||||
// HTTP method to access a function.
|
||||
// +optional
|
||||
|
||||
@@ -274,6 +274,10 @@ func (spec FunctionSpec) Validate() error {
|
||||
result = multierror.Append(result, spec.InvokeStrategy.Validate())
|
||||
}
|
||||
|
||||
if spec.InvokeStrategy.ExecutionStrategy.ExecutorType == ExecutorTypeContainer && spec.PodSpec == nil {
|
||||
result = multierror.Append(result, MakeValidationErr(ErrorInvalidObject, "FunctionSpec.PodSpec", "", "executor type container requires a pod spec"))
|
||||
}
|
||||
|
||||
// TODO Add below validation warning
|
||||
/*if spec.FunctionTimeout <= 0 {
|
||||
result = multierror.Append(result, MakeValidationErr(ErrorInvalidValue, "FunctionTimeout value", spec.FunctionTimeout, "not a valid value. Should always be more than 0"))
|
||||
@@ -300,7 +304,7 @@ func (es ExecutionStrategy) Validate() error {
|
||||
result := &multierror.Error{}
|
||||
|
||||
switch es.ExecutorType {
|
||||
case ExecutorTypeNewdeploy, ExecutorTypePoolmgr: // no op
|
||||
case ExecutorTypeNewdeploy, ExecutorTypePoolmgr, ExecutorTypeContainer: // no op
|
||||
default:
|
||||
result = multierror.Append(result, MakeValidationErr(ErrorUnsupportedType, "ExecutionStrategy.ExecutorType", es.ExecutorType, "not a valid executor type"))
|
||||
}
|
||||
|
||||
@@ -431,6 +431,11 @@ func (in *FunctionSpec) DeepCopyInto(out *FunctionSpec) {
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.PodSpec != nil {
|
||||
in, out := &in.PodSpec, &out.PodSpec
|
||||
*out = new(corev1.PodSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2019 The Fission Authors.
|
||||
Copyright The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -13,7 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
// This file contains a collection of methods that can be used from go-restful to
|
||||
@@ -24,9 +23,8 @@ package v1
|
||||
// they are on one line! For multiple line or blocks that you want to ignore use ---.
|
||||
// Any context after a --- is ignored.
|
||||
//
|
||||
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
|
||||
// Those methods can be generated by using hack/update-swagger-docs.sh
|
||||
// AUTO-GENERATED FUNCTIONS START HERE
|
||||
var map_Archive = map[string]string{
|
||||
"": "Archive contains or references a collection of source or binary files.",
|
||||
"type": "Type defines how the package is specified: literal or URL. Available value:\n - literal\n - url",
|
||||
@@ -149,7 +147,7 @@ func (EnvironmentSpec) SwaggerDoc() map[string]string {
|
||||
|
||||
var map_ExecutionStrategy = map[string]string{
|
||||
"": "ExecutionStrategy specifies low-level parameters for function execution, such as the number of instances.\n\nMinScale affects the cold start behavior for a function. If MinScale is 0 then the deployment is created on first invocation of function and is good for requests of asynchronous nature. If MinScale is greater than 0 then MinScale number of pods are created at the time of creation of function. This ensures faster response during first invocation at the cost of consuming resources.\n\nMaxScale is the maximum number of pods that function will scale to based on TargetCPUPercent and resources allocated to the function pod.",
|
||||
"ExecutorType": "ExecutorType is the executor type of a function used. Defaults to \"poolmgr\".\n\nAvailable value:\n - poolmgr\n - newdeploy",
|
||||
"ExecutorType": "ExecutorType is the executor type of a function used. Defaults to \"poolmgr\".\n\nAvailable value:\n - poolmgr\n - newdeploy\n - container",
|
||||
"MinScale": "This is only for newdeploy to set up minimum replicas of deployment.",
|
||||
"MaxScale": "This is only for newdeploy to set up maximum replicas of deployment.",
|
||||
"TargetCPUPercent": "This is only for newdeploy to set up target CPU utilization of HPA.",
|
||||
@@ -210,6 +208,7 @@ var map_FunctionSpec = map[string]string{
|
||||
"concurrency": "Maximum number of pods to be specialized which will serve requests This is optional. If not specified default value will be taken as 500",
|
||||
"requestsPerPod": "RequestsPerPod indicates the maximum number of concurrent requests that can be served by a specialized pod This is optional. If not specified default value will be taken as 1",
|
||||
"onceOnly": "OnceOnly specifies if specialized pod will serve exactly one request in its lifetime and would be garbage collected after serving that one request This is optional. If not specified default value will be taken as false",
|
||||
"podspec": "Podspec specifies podspec to use for executor type container based functions Different arguments mentioned for container based function are populated inside a pod.",
|
||||
}
|
||||
|
||||
func (FunctionSpec) SwaggerDoc() map[string]string {
|
||||
@@ -237,6 +236,7 @@ var map_HTTPTriggerSpec = map[string]string{
|
||||
"host": "Deprecated: the original idea of this field is not for setting Ingress. Since we have IngressConfig now, remove Host after couple releases.",
|
||||
"relativeurl": "RelativeURL is the exposed URL for external client to access a function with.",
|
||||
"prefix": "Prefix with which functions are exposed. NOTE: Prefix takes precedence over URL/RelativeURL. Note that it does not treat slashes specially (\"/foobar/\" will be matched by the prefix \"/foobar\").",
|
||||
"keepPrefix": "When function is exposed with Prefix based path, keepPrefix decides whether to keep or trim prefix in URL while invoking function.",
|
||||
"method": "Use Methods instead of Method. This field is going to be deprecated in a future release HTTP method to access a function.",
|
||||
"methods": "HTTP methods to access a function",
|
||||
"functionref": "FunctionReference is a reference to the target function.",
|
||||
@@ -18,6 +18,7 @@ package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -25,27 +26,43 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"go.opencensus.io/plugin/ochttp"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/net/context/ctxhttp"
|
||||
|
||||
builder "github.com/fission/fission/pkg/builder"
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
otelUtils "github.com/fission/fission/pkg/utils/otel"
|
||||
"github.com/fission/fission/pkg/utils/tracing"
|
||||
)
|
||||
|
||||
type (
|
||||
Client struct {
|
||||
logger *zap.Logger
|
||||
url string
|
||||
logger *zap.Logger
|
||||
url string
|
||||
httpClient *http.Client
|
||||
}
|
||||
)
|
||||
|
||||
func MakeClient(logger *zap.Logger, builderUrl string) *Client {
|
||||
var hc *http.Client
|
||||
if tracing.TracingEnabled(logger) {
|
||||
hc = &http.Client{Transport: &ochttp.Transport{}}
|
||||
} else {
|
||||
hc = &http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)}
|
||||
}
|
||||
|
||||
return &Client{
|
||||
logger: logger.Named("builder_client"),
|
||||
url: strings.TrimSuffix(builderUrl, "/"),
|
||||
logger: logger.Named("builder_client"),
|
||||
url: strings.TrimSuffix(builderUrl, "/"),
|
||||
httpClient: hc,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) Build(req *builder.PackageBuildRequest) (*builder.PackageBuildResponse, error) {
|
||||
func (c *Client) Build(ctx context.Context, req *builder.PackageBuildRequest) (*builder.PackageBuildResponse, error) {
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, c.logger)
|
||||
|
||||
body, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error marshaling json")
|
||||
@@ -55,8 +72,7 @@ func (c *Client) Build(req *builder.PackageBuildRequest) (*builder.PackageBuildR
|
||||
var resp *http.Response
|
||||
|
||||
for i := 0; i < maxRetries; i++ {
|
||||
resp, err = http.Post(c.url, "application/json", bytes.NewReader(body))
|
||||
|
||||
resp, err = ctxhttp.Post(ctx, c.httpClient, c.url, "application/json", bytes.NewReader(body))
|
||||
if err == nil {
|
||||
if resp.StatusCode == 200 {
|
||||
break
|
||||
@@ -66,7 +82,7 @@ func (c *Client) Build(req *builder.PackageBuildRequest) (*builder.PackageBuildR
|
||||
|
||||
if i < maxRetries-1 {
|
||||
time.Sleep(50 * time.Duration(2*i) * time.Millisecond)
|
||||
c.logger.Error("error building package, retrying", zap.Error(err))
|
||||
logger.Error("error building package, retrying", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -77,14 +93,14 @@ func (c *Client) Build(req *builder.PackageBuildRequest) (*builder.PackageBuildR
|
||||
|
||||
rBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
c.logger.Error("error reading resp body", zap.Error(err))
|
||||
logger.Error("error reading resp body", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pkgBuildResp := builder.PackageBuildResponse{}
|
||||
err = json.Unmarshal([]byte(rBody), &pkgBuildResp)
|
||||
err = json.Unmarshal(rBody, &pkgBuildResp)
|
||||
if err != nil {
|
||||
c.logger.Error("error parsing resp body", zap.Error(err))
|
||||
logger.Error("error parsing resp body", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,15 @@ limitations under the License.
|
||||
package buildermgr
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
k8sInformers "k8s.io/client-go/informers"
|
||||
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
fetcherConfig "github.com/fission/fission/pkg/fetcher/config"
|
||||
genInformer "github.com/fission/fission/pkg/generated/informers/externalversions"
|
||||
)
|
||||
|
||||
// Start the buildermgr service.
|
||||
@@ -46,9 +50,12 @@ func Start(logger *zap.Logger, storageSvcUrl string, envBuilderNamespace string)
|
||||
envWatcher := makeEnvironmentWatcher(bmLogger, fissionClient, kubernetesClient, fetcherConfig, envBuilderNamespace)
|
||||
go envWatcher.watchEnvironments()
|
||||
|
||||
k8sInformerFactory := k8sInformers.NewSharedInformerFactory(kubernetesClient, time.Minute*30)
|
||||
informerFactory := genInformer.NewSharedInformerFactory(fissionClient, time.Minute*30)
|
||||
podInformer := k8sInformerFactory.Core().V1().Pods().Informer()
|
||||
pkgInformer := informerFactory.Core().V1().Packages().Informer()
|
||||
pkgWatcher := makePackageWatcher(bmLogger, fissionClient,
|
||||
kubernetesClient, envBuilderNamespace, storageSvcUrl)
|
||||
go pkgWatcher.watchPackages()
|
||||
|
||||
select {}
|
||||
kubernetesClient, envBuilderNamespace, storageSvcUrl, &podInformer, &pkgInformer)
|
||||
pkgWatcher.Run()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ import (
|
||||
func buildPackage(ctx context.Context, logger *zap.Logger, fissionClient *crd.FissionClient, envBuilderNamespace string,
|
||||
storageSvcUrl string, pkg *fv1.Package) (uploadResp *fetcher.ArchiveUploadResponse, buildLogs string, err error) {
|
||||
|
||||
env, err := fissionClient.CoreV1().Environments(pkg.Spec.Environment.Namespace).Get(context.TODO(), pkg.Spec.Environment.Name, metav1.GetOptions{})
|
||||
env, err := fissionClient.CoreV1().Environments(pkg.Spec.Environment.Namespace).Get(ctx, pkg.Spec.Environment.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
e := "error getting environment CRD info"
|
||||
logger.Error(e, zap.Error(err))
|
||||
@@ -88,7 +88,7 @@ func buildPackage(ctx context.Context, logger *zap.Logger, fissionClient *crd.Fi
|
||||
|
||||
logger.Info("started building with source package", zap.String("source_package", srcPkgFilename))
|
||||
// send build request to builder
|
||||
buildResp, err := builderC.Build(pkgBuildReq)
|
||||
buildResp, err := builderC.Build(ctx, pkgBuildReq)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error building deployment package: %v", err)
|
||||
var buildLogs string
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
k8sCache "k8s.io/client-go/tools/cache"
|
||||
|
||||
@@ -40,26 +39,26 @@ type (
|
||||
logger *zap.Logger
|
||||
fissionClient *crd.FissionClient
|
||||
k8sClient *kubernetes.Clientset
|
||||
podStore k8sCache.Store
|
||||
pkgStore k8sCache.Store
|
||||
podInformer *k8sCache.SharedIndexInformer
|
||||
pkgInformer *k8sCache.SharedIndexInformer
|
||||
builderNamespace string
|
||||
storageSvcUrl string
|
||||
buildCache *cache.Cache
|
||||
}
|
||||
)
|
||||
|
||||
func makePackageWatcher(logger *zap.Logger, fissionClient *crd.FissionClient, k8sClientSet *kubernetes.Clientset,
|
||||
builderNamespace string, storageSvcUrl string) *packageWatcher {
|
||||
lw := k8sCache.NewListWatchFromClient(k8sClientSet.CoreV1().RESTClient(), "pods", metav1.NamespaceAll, fields.Everything())
|
||||
store, controller := k8sCache.NewInformer(lw, &apiv1.Pod{}, 30*time.Second, k8sCache.ResourceEventHandlerFuncs{})
|
||||
go controller.Run(make(chan struct{}))
|
||||
|
||||
builderNamespace string, storageSvcUrl string, podInformer *k8sCache.SharedIndexInformer,
|
||||
pkgInformer *k8sCache.SharedIndexInformer) *packageWatcher {
|
||||
pkgw := &packageWatcher{
|
||||
logger: logger.Named("package_watcher"),
|
||||
fissionClient: fissionClient,
|
||||
k8sClient: k8sClientSet,
|
||||
podStore: store,
|
||||
podInformer: podInformer,
|
||||
pkgInformer: pkgInformer,
|
||||
builderNamespace: builderNamespace,
|
||||
storageSvcUrl: storageSvcUrl,
|
||||
buildCache: cache.MakeCache(0, 0),
|
||||
}
|
||||
return pkgw
|
||||
}
|
||||
@@ -74,15 +73,15 @@ func makePackageWatcher(logger *zap.Logger, fissionClient *crd.FissionClient, k8
|
||||
// 5. Update package resource in package ref of functions that share the same package
|
||||
// 6. Update package status to succeed state
|
||||
// *. Update package status to failed state,if any one of steps above failed/time out
|
||||
func (pkgw *packageWatcher) build(buildCache *cache.Cache, srcpkg *fv1.Package) {
|
||||
func (pkgw *packageWatcher) build(ctx context.Context, srcpkg *fv1.Package) {
|
||||
// Ignore duplicate build requests
|
||||
key := fmt.Sprintf("%v-%v", srcpkg.ObjectMeta.Name, srcpkg.ObjectMeta.ResourceVersion)
|
||||
_, err := buildCache.Set(key, srcpkg)
|
||||
_, err := pkgw.buildCache.Set(key, srcpkg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
err := buildCache.Delete(key)
|
||||
err := pkgw.buildCache.Delete(key)
|
||||
if err != nil {
|
||||
pkgw.logger.Error("error deleting key from cache", zap.String("key", key), zap.Error(err))
|
||||
}
|
||||
@@ -96,7 +95,7 @@ func (pkgw *packageWatcher) build(buildCache *cache.Cache, srcpkg *fv1.Package)
|
||||
return
|
||||
}
|
||||
|
||||
env, err := pkgw.fissionClient.CoreV1().Environments(pkg.Spec.Environment.Namespace).Get(context.TODO(), pkg.Spec.Environment.Name, metav1.GetOptions{})
|
||||
env, err := pkgw.fissionClient.CoreV1().Environments(pkg.Spec.Environment.Namespace).Get(ctx, pkg.Spec.Environment.Name, metav1.GetOptions{})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
e := "environment does not exist"
|
||||
pkgw.logger.Error(e, zap.String("environment", pkg.Spec.Environment.Name))
|
||||
@@ -122,7 +121,7 @@ func (pkgw *packageWatcher) build(buildCache *cache.Cache, srcpkg *fv1.Package)
|
||||
for healthCheckBackOff.NextExists() {
|
||||
// Informer store is not able to use label to find the pod,
|
||||
// iterate all available environment builders.
|
||||
items := pkgw.podStore.List()
|
||||
items := (*pkgw.podInformer).GetStore().List()
|
||||
if err != nil {
|
||||
pkgw.logger.Error("error retrieving pod information for environment", zap.Error(err), zap.String("environment", env.ObjectMeta.Name))
|
||||
return
|
||||
@@ -168,7 +167,7 @@ func (pkgw *packageWatcher) build(buildCache *cache.Cache, srcpkg *fv1.Package)
|
||||
// Add the package getter rolebinding to builder sa
|
||||
// we continue here if role binding was not setup successfully. this is because without this, the fetcher wont be able to fetch the source pkg into the container and
|
||||
// the build will fail eventually
|
||||
err := utils.SetupRoleBinding(pkgw.logger, pkgw.k8sClient, fv1.PackageGetterRB, pkg.ObjectMeta.Namespace, fv1.PackageGetterCR, fv1.ClusterRole, fv1.FissionBuilderSA, builderNs)
|
||||
err := utils.SetupRoleBinding(ctx, pkgw.logger, pkgw.k8sClient, fv1.PackageGetterRB, pkg.ObjectMeta.Namespace, fv1.PackageGetterCR, fv1.ClusterRole, fv1.FissionBuilderSA, builderNs)
|
||||
if err != nil {
|
||||
pkgw.logger.Error("error setting up role binding for package",
|
||||
zap.Error(err),
|
||||
@@ -182,7 +181,6 @@ func (pkgw *packageWatcher) build(buildCache *cache.Cache, srcpkg *fv1.Package)
|
||||
zap.String("package", fmt.Sprintf("%s.%s", pkg.ObjectMeta.Name, pkg.ObjectMeta.Namespace)))
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
uploadResp, buildLogs, err := buildPackage(ctx, pkgw.logger, pkgw.fissionClient, builderNs, pkgw.storageSvcUrl, pkg)
|
||||
if err != nil {
|
||||
pkgw.logger.Error("error building package", zap.Error(err), zap.String("package_name", pkg.ObjectMeta.Name))
|
||||
@@ -201,7 +199,7 @@ func (pkgw *packageWatcher) build(buildCache *cache.Cache, srcpkg *fv1.Package)
|
||||
pkgw.logger.Info("starting package info update", zap.String("package_name", pkg.ObjectMeta.Name))
|
||||
|
||||
fnList, err := pkgw.fissionClient.CoreV1().
|
||||
Functions(metav1.NamespaceAll).List(context.TODO(), metav1.ListOptions{})
|
||||
Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
e := "error getting function list"
|
||||
pkgw.logger.Error(e, zap.Error(err))
|
||||
@@ -225,7 +223,7 @@ func (pkgw *packageWatcher) build(buildCache *cache.Cache, srcpkg *fv1.Package)
|
||||
fn.Spec.Package.PackageRef.ResourceVersion != pkg.ObjectMeta.ResourceVersion {
|
||||
fn.Spec.Package.PackageRef.ResourceVersion = pkg.ObjectMeta.ResourceVersion
|
||||
// update CRD
|
||||
_, err = pkgw.fissionClient.CoreV1().Functions(fn.ObjectMeta.Namespace).Update(context.TODO(), &fn, metav1.UpdateOptions{})
|
||||
_, err = pkgw.fissionClient.CoreV1().Functions(fn.ObjectMeta.Namespace).Update(ctx, &fn, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
e := "error updating function package resource version"
|
||||
pkgw.logger.Error(e, zap.Error(err))
|
||||
@@ -281,10 +279,7 @@ func (pkgw *packageWatcher) build(buildCache *cache.Cache, srcpkg *fv1.Package)
|
||||
zap.String("package", fmt.Sprintf("%s.%s", pkg.ObjectMeta.Name, pkg.ObjectMeta.Namespace)))
|
||||
}
|
||||
|
||||
func (pkgw *packageWatcher) watchPackages() {
|
||||
buildCache := cache.MakeCache(0, 0)
|
||||
lw := k8sCache.NewListWatchFromClient(pkgw.fissionClient.CoreV1().RESTClient(), "packages", apiv1.NamespaceAll, fields.Everything())
|
||||
|
||||
func (pkgw *packageWatcher) packageInformerHandler() k8sCache.ResourceEventHandlerFuncs {
|
||||
processPkg := func(pkg *fv1.Package) {
|
||||
var err error
|
||||
|
||||
@@ -298,14 +293,13 @@ func (pkgw *packageWatcher) watchPackages() {
|
||||
// don't need to build the package at this moment.
|
||||
return
|
||||
}
|
||||
|
||||
// Only build pending state packages.
|
||||
if pkg.Status.BuildStatus == fv1.BuildStatusPending {
|
||||
go pkgw.build(buildCache, pkg)
|
||||
ctx := context.Background()
|
||||
go pkgw.build(ctx, pkg)
|
||||
}
|
||||
}
|
||||
|
||||
pkgStore, controller := k8sCache.NewInformer(lw, &fv1.Package{}, 60*time.Minute, k8sCache.ResourceEventHandlerFuncs{
|
||||
return k8sCache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
pkg := obj.(*fv1.Package)
|
||||
processPkg(pkg)
|
||||
@@ -325,10 +319,14 @@ func (pkgw *packageWatcher) watchPackages() {
|
||||
}
|
||||
processPkg(pkg)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pkgw.pkgStore = pkgStore
|
||||
controller.Run(make(chan struct{}))
|
||||
func (pkgw *packageWatcher) Run() {
|
||||
context := context.Background()
|
||||
go (*pkgw.podInformer).Run(context.Done())
|
||||
(*pkgw.pkgInformer).AddEventHandler(pkgw.packageInformerHandler())
|
||||
(*pkgw.pkgInformer).Run(context.Done())
|
||||
}
|
||||
|
||||
// setInitialBuildStatus sets initial build status to a package if it is empty.
|
||||
|
||||
@@ -28,13 +28,12 @@ import (
|
||||
"go.uber.org/zap"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
k8sCache "k8s.io/client-go/tools/cache"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
genInformer "github.com/fission/fission/pkg/generated/informers/externalversions"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -45,14 +44,12 @@ type canaryConfigMgr struct {
|
||||
logger *zap.Logger
|
||||
fissionClient *crd.FissionClient
|
||||
kubeClient *kubernetes.Clientset
|
||||
canaryConfigStore k8sCache.Store
|
||||
canaryConfigController k8sCache.Controller
|
||||
canaryConfigInformer *k8sCache.SharedIndexInformer
|
||||
promClient *PrometheusApiClient
|
||||
crdClient rest.Interface
|
||||
canaryCfgCancelFuncMap *canaryConfigCancelFuncMap
|
||||
}
|
||||
|
||||
func MakeCanaryConfigMgr(logger *zap.Logger, fissionClient *crd.FissionClient, kubeClient *kubernetes.Clientset, crdClient rest.Interface, prometheusSvc string) (*canaryConfigMgr, error) {
|
||||
func MakeCanaryConfigMgr(logger *zap.Logger, fissionClient *crd.FissionClient, kubeClient *kubernetes.Clientset, prometheusSvc string) (*canaryConfigMgr, error) {
|
||||
if prometheusSvc == "" {
|
||||
logger.Info("try to retrieve prometheus server information from environment variables")
|
||||
|
||||
@@ -92,54 +89,48 @@ func MakeCanaryConfigMgr(logger *zap.Logger, fissionClient *crd.FissionClient, k
|
||||
logger: logger.Named("canary_config_manager"),
|
||||
fissionClient: fissionClient,
|
||||
kubeClient: kubeClient,
|
||||
crdClient: crdClient,
|
||||
promClient: promClient,
|
||||
canaryCfgCancelFuncMap: makecanaryConfigCancelFuncMap(),
|
||||
}
|
||||
|
||||
store, controller := configMgr.initCanaryConfigController()
|
||||
configMgr.canaryConfigStore = store
|
||||
configMgr.canaryConfigController = controller
|
||||
|
||||
informerFactory := genInformer.NewSharedInformerFactory(fissionClient, time.Minute*30)
|
||||
informer := informerFactory.Core().V1().CanaryConfigs().Informer()
|
||||
configMgr.canaryConfigInformer = &informer
|
||||
configMgr.CanaryConfigEventHandlers()
|
||||
return configMgr, nil
|
||||
}
|
||||
|
||||
func (canaryCfgMgr *canaryConfigMgr) initCanaryConfigController() (k8sCache.Store, k8sCache.Controller) {
|
||||
resyncPeriod := 30 * time.Second
|
||||
listWatch := k8sCache.NewListWatchFromClient(canaryCfgMgr.crdClient, "canaryconfigs", metav1.NamespaceAll, fields.Everything())
|
||||
store, controller := k8sCache.NewInformer(listWatch, &fv1.CanaryConfig{}, resyncPeriod,
|
||||
k8sCache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
canaryConfig := obj.(*fv1.CanaryConfig)
|
||||
if canaryConfig.Status.Status == fv1.CanaryConfigStatusPending {
|
||||
go canaryCfgMgr.addCanaryConfig(canaryConfig)
|
||||
}
|
||||
},
|
||||
DeleteFunc: func(obj interface{}) {
|
||||
canaryConfig := obj.(*fv1.CanaryConfig)
|
||||
go canaryCfgMgr.deleteCanaryConfig(canaryConfig)
|
||||
},
|
||||
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
|
||||
oldConfig := oldObj.(*fv1.CanaryConfig)
|
||||
newConfig := newObj.(*fv1.CanaryConfig)
|
||||
if oldConfig.ObjectMeta.ResourceVersion != newConfig.ObjectMeta.ResourceVersion &&
|
||||
newConfig.Status.Status == fv1.CanaryConfigStatusPending {
|
||||
canaryCfgMgr.logger.Info("update canary config invoked",
|
||||
zap.String("name", newConfig.ObjectMeta.Name),
|
||||
zap.String("namespace", newConfig.ObjectMeta.Namespace),
|
||||
zap.String("version", newConfig.ObjectMeta.ResourceVersion))
|
||||
go canaryCfgMgr.updateCanaryConfig(oldConfig, newConfig)
|
||||
}
|
||||
go canaryCfgMgr.reSyncCanaryConfigs()
|
||||
func (canaryCfgMgr *canaryConfigMgr) CanaryConfigEventHandlers() {
|
||||
(*canaryCfgMgr.canaryConfigInformer).AddEventHandler(k8sCache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
canaryConfig := obj.(*fv1.CanaryConfig)
|
||||
if canaryConfig.Status.Status == fv1.CanaryConfigStatusPending {
|
||||
go canaryCfgMgr.addCanaryConfig(canaryConfig)
|
||||
}
|
||||
},
|
||||
DeleteFunc: func(obj interface{}) {
|
||||
canaryConfig := obj.(*fv1.CanaryConfig)
|
||||
go canaryCfgMgr.deleteCanaryConfig(canaryConfig)
|
||||
},
|
||||
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
|
||||
oldConfig := oldObj.(*fv1.CanaryConfig)
|
||||
newConfig := newObj.(*fv1.CanaryConfig)
|
||||
if oldConfig.ObjectMeta.ResourceVersion != newConfig.ObjectMeta.ResourceVersion &&
|
||||
newConfig.Status.Status == fv1.CanaryConfigStatusPending {
|
||||
canaryCfgMgr.logger.Info("update canary config invoked",
|
||||
zap.String("name", newConfig.ObjectMeta.Name),
|
||||
zap.String("namespace", newConfig.ObjectMeta.Namespace),
|
||||
zap.String("version", newConfig.ObjectMeta.ResourceVersion))
|
||||
go canaryCfgMgr.updateCanaryConfig(oldConfig, newConfig)
|
||||
}
|
||||
go canaryCfgMgr.reSyncCanaryConfigs()
|
||||
|
||||
},
|
||||
})
|
||||
|
||||
return store, controller
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (canaryCfgMgr *canaryConfigMgr) Run(ctx context.Context) {
|
||||
go canaryCfgMgr.canaryConfigController.Run(ctx.Done())
|
||||
go (*canaryCfgMgr.canaryConfigInformer).Run(ctx.Done())
|
||||
canaryCfgMgr.logger.Info("started canary configmgr controller")
|
||||
}
|
||||
|
||||
@@ -501,7 +492,7 @@ func (canaryCfgMgr *canaryConfigMgr) rollForward(canaryConfig *fv1.CanaryConfig,
|
||||
}
|
||||
|
||||
func (canaryCfgMgr *canaryConfigMgr) reSyncCanaryConfigs() {
|
||||
for _, obj := range canaryCfgMgr.canaryConfigStore.List() {
|
||||
for _, obj := range (*canaryCfgMgr.canaryConfigInformer).GetStore().List() {
|
||||
canaryConfig := obj.(*fv1.CanaryConfig)
|
||||
_, err := canaryCfgMgr.canaryCfgCancelFuncMap.lookup(&canaryConfig.ObjectMeta)
|
||||
if err != nil && canaryConfig.Status.Status == fv1.CanaryConfigStatusPending {
|
||||
|
||||
+11
-2
@@ -24,6 +24,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"go.opencensus.io/plugin/ochttp"
|
||||
"go.uber.org/zap"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -34,6 +35,7 @@ import (
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
"github.com/fission/fission/pkg/fission-cli/logdb"
|
||||
"github.com/fission/fission/pkg/info"
|
||||
"github.com/fission/fission/pkg/utils/otel"
|
||||
)
|
||||
|
||||
var podNamespace string
|
||||
@@ -263,9 +265,16 @@ func (api *API) GetHandler() http.Handler {
|
||||
return r
|
||||
}
|
||||
|
||||
func (api *API) Serve(port int) {
|
||||
func (api *API) Serve(port int, openTracingEnabled bool) {
|
||||
address := fmt.Sprintf(":%v", port)
|
||||
api.logger.Info("server started", zap.Int("port", port))
|
||||
err := http.ListenAndServe(address, api.GetHandler())
|
||||
|
||||
var handler http.Handler
|
||||
if openTracingEnabled {
|
||||
handler = &ochttp.Handler{Handler: api.GetHandler()}
|
||||
} else {
|
||||
handler = otel.GetHandlerWithOTEL(api.GetHandler(), "fission-controller", otel.UrlsToIgnore("/healthz"))
|
||||
}
|
||||
err := http.ListenAndServe(address, handler)
|
||||
api.logger.Fatal("done listening", zap.Error(err))
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ func TestMain(m *testing.M) {
|
||||
|
||||
panicIf(err)
|
||||
|
||||
go Start(logger, 8888, true)
|
||||
go Start(logger, 8888, true, true)
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
|
||||
@@ -31,8 +31,7 @@ import (
|
||||
func ConfigCanaryFeature(context context.Context, logger *zap.Logger, fissionClient *crd.FissionClient, kubeClient *kubernetes.Clientset, featureConfig *config.FeatureConfig, featureStatus map[string]string) error {
|
||||
// start the appropriate controller
|
||||
if featureConfig.CanaryConfig.IsEnabled {
|
||||
canaryCfgMgr, err := canaryconfigmgr.MakeCanaryConfigMgr(logger, fissionClient, kubeClient, fissionClient.CoreV1().RESTClient(),
|
||||
featureConfig.CanaryConfig.PrometheusSvc)
|
||||
canaryCfgMgr, err := canaryconfigmgr.MakeCanaryConfigMgr(logger, fissionClient, kubeClient, featureConfig.CanaryConfig.PrometheusSvc)
|
||||
if err != nil {
|
||||
featureStatus[config.CanaryFeature] = err.Error()
|
||||
return errors.Wrap(err, "failed to start canary config manager")
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
)
|
||||
|
||||
func Start(logger *zap.Logger, port int, unitTestFlag bool) {
|
||||
func Start(logger *zap.Logger, port int, unitTestFlag bool, openTracingEnabled bool) {
|
||||
cLogger := logger.Named("controller")
|
||||
|
||||
fc, kc, apiExtClient, _, err := crd.MakeFissionClient()
|
||||
@@ -53,5 +53,5 @@ func Start(logger *zap.Logger, port int, unitTestFlag bool) {
|
||||
if err != nil {
|
||||
cLogger.Fatal("failed to start controller", zap.Error(err))
|
||||
}
|
||||
api.Serve(port)
|
||||
api.Serve(port, openTracingEnabled)
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ func (a *API) PackageApiGet(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var resp []byte
|
||||
if raw != "" {
|
||||
resp = []byte(f.Spec.Deployment.Literal)
|
||||
resp = f.Spec.Deployment.Literal
|
||||
} else {
|
||||
resp, err = json.Marshal(f)
|
||||
if err != nil {
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ import (
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
metricsclient "k8s.io/metrics/pkg/client/clientset/versioned"
|
||||
|
||||
genClientset "github.com/fission/fission/pkg/apis/genclient/clientset/versioned"
|
||||
genClientset "github.com/fission/fission/pkg/generated/clientset/versioned"
|
||||
)
|
||||
|
||||
type (
|
||||
|
||||
@@ -31,3 +31,10 @@ import (
|
||||
func CacheKey(metadata *metav1.ObjectMeta) string {
|
||||
return fmt.Sprintf("%v_%v", metadata.UID, metadata.ResourceVersion)
|
||||
}
|
||||
|
||||
// CacheKeyForUID create a key that uniquely identifies the
|
||||
// of the object. Since resourceVersion changes on every update and
|
||||
// UIDs are unique, we don't use resource version here
|
||||
func CacheKeyUID(metadata *metav1.ObjectMeta) string {
|
||||
return fmt.Sprintf("%v", metadata.UID)
|
||||
}
|
||||
|
||||
+43
-27
@@ -17,8 +17,10 @@ limitations under the License.
|
||||
package executor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -32,9 +34,11 @@ import (
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
"github.com/fission/fission/pkg/executor/client"
|
||||
otelUtils "github.com/fission/fission/pkg/utils/otel"
|
||||
)
|
||||
|
||||
func (executor *Executor) getServiceForFunctionAPI(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to read request", http.StatusInternalServerError)
|
||||
@@ -51,9 +55,10 @@ func (executor *Executor) getServiceForFunctionAPI(w http.ResponseWriter, r *htt
|
||||
|
||||
t := fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType
|
||||
et := executor.executorTypes[t]
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, executor.logger)
|
||||
|
||||
// Check function -> svc cache
|
||||
executor.logger.Debug("checking for cached function service",
|
||||
logger.Debug("checking for cached function service",
|
||||
zap.String("function_name", fn.ObjectMeta.Name),
|
||||
zap.String("function_namespace", fn.ObjectMeta.Namespace))
|
||||
if t == fv1.ExecutorTypePoolmgr && !fn.Spec.OnceOnly {
|
||||
@@ -65,51 +70,51 @@ func (executor *Executor) getServiceForFunctionAPI(w http.ResponseWriter, r *htt
|
||||
if requestsPerpod == 0 {
|
||||
requestsPerpod = 1
|
||||
}
|
||||
fsvc, active, err := et.GetFuncSvcFromPoolCache(fn, requestsPerpod)
|
||||
fsvc, active, err := et.GetFuncSvcFromPoolCache(ctx, fn, requestsPerpod)
|
||||
// check if its a cache hit (check if there is already specialized function pod that can serve another request)
|
||||
if err == nil {
|
||||
// if a pod is already serving request then it already exists else validated
|
||||
executor.logger.Debug("from cache", zap.Int("active", active))
|
||||
if active > 1 || et.IsValid(fsvc) {
|
||||
logger.Debug("from cache", zap.Int("active", active))
|
||||
if active > 1 || et.IsValid(ctx, fsvc) {
|
||||
// Cached, return svc address
|
||||
executor.logger.Debug("served from cache", zap.String("name", fsvc.Name), zap.String("address", fsvc.Address))
|
||||
logger.Debug("served from cache", zap.String("name", fsvc.Name), zap.String("address", fsvc.Address))
|
||||
executor.writeResponse(w, fsvc.Address, fn.ObjectMeta.Name)
|
||||
return
|
||||
}
|
||||
executor.logger.Debug("deleting cache entry for invalid address",
|
||||
logger.Debug("deleting cache entry for invalid address",
|
||||
zap.String("function_name", fn.ObjectMeta.Name),
|
||||
zap.String("function_namespace", fn.ObjectMeta.Namespace),
|
||||
zap.String("address", fsvc.Address))
|
||||
et.DeleteFuncSvcFromCache(fsvc)
|
||||
et.DeleteFuncSvcFromCache(ctx, fsvc)
|
||||
active--
|
||||
}
|
||||
|
||||
if active >= concurrency {
|
||||
errMsg := fmt.Sprintf("max concurrency reached for %v. All %v instance are active", fn.ObjectMeta.Name, concurrency)
|
||||
executor.logger.Error("error occurred", zap.String("error", errMsg))
|
||||
http.Error(w, errMsg, http.StatusTooManyRequests)
|
||||
logger.Error("error occurred", zap.String("error", errMsg))
|
||||
http.Error(w, html.EscapeString(errMsg), http.StatusTooManyRequests)
|
||||
return
|
||||
}
|
||||
} else if t == fv1.ExecutorTypeNewdeploy {
|
||||
fsvc, err := et.GetFuncSvcFromCache(fn)
|
||||
} else if t == fv1.ExecutorTypeNewdeploy || t == fv1.ExecutorTypeContainer {
|
||||
fsvc, err := et.GetFuncSvcFromCache(ctx, fn)
|
||||
if err == nil {
|
||||
if et.IsValid(fsvc) {
|
||||
if et.IsValid(ctx, fsvc) {
|
||||
// Cached, return svc address
|
||||
executor.writeResponse(w, fsvc.Address, fn.ObjectMeta.Name)
|
||||
return
|
||||
}
|
||||
executor.logger.Debug("deleting cache entry for invalid address",
|
||||
logger.Debug("deleting cache entry for invalid address",
|
||||
zap.String("function_name", fn.ObjectMeta.Name),
|
||||
zap.String("function_namespace", fn.ObjectMeta.Namespace),
|
||||
zap.String("address", fsvc.Address))
|
||||
et.DeleteFuncSvcFromCache(fsvc)
|
||||
et.DeleteFuncSvcFromCache(ctx, fsvc)
|
||||
}
|
||||
}
|
||||
|
||||
serviceName, err := executor.getServiceForFunction(fn)
|
||||
serviceName, err := executor.getServiceForFunction(ctx, fn)
|
||||
if err != nil {
|
||||
code, msg := ferror.GetHTTPError(err)
|
||||
executor.logger.Error("error getting service for function",
|
||||
logger.Error("error getting service for function",
|
||||
zap.Error(err),
|
||||
zap.String("function", fn.ObjectMeta.Name),
|
||||
zap.String("fission_http_error", msg))
|
||||
@@ -139,9 +144,10 @@ func (executor *Executor) writeResponse(w http.ResponseWriter, serviceName strin
|
||||
// stale addresses are not returned to the router.
|
||||
// To make it optimal, plan is to add an eager cache invalidator function that watches for pod deletion events and
|
||||
// invalidates the cache entry if the pod address was cached.
|
||||
func (executor *Executor) getServiceForFunction(fn *fv1.Function) (string, error) {
|
||||
func (executor *Executor) getServiceForFunction(ctx context.Context, fn *fv1.Function) (string, error) {
|
||||
respChan := make(chan *createFuncServiceResponse)
|
||||
executor.requestChan <- &createFuncServiceRequest{
|
||||
context: ctx,
|
||||
function: fn,
|
||||
respChan: respChan,
|
||||
}
|
||||
@@ -161,9 +167,12 @@ func (executor *Executor) tapService(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// find funcSvc and update its atime
|
||||
func (executor *Executor) tapServices(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, executor.logger)
|
||||
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
executor.logger.Error("failed to read tap service request", zap.Error(err))
|
||||
logger.Error("failed to read tap service request", zap.Error(err))
|
||||
http.Error(w, "Failed to read request", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -171,7 +180,7 @@ func (executor *Executor) tapServices(w http.ResponseWriter, r *http.Request) {
|
||||
tapSvcReqs := []client.TapServiceRequest{}
|
||||
err = json.Unmarshal(body, &tapSvcReqs)
|
||||
if err != nil {
|
||||
executor.logger.Error("failed to decode tap service request",
|
||||
logger.Error("failed to decode tap service request",
|
||||
zap.Error(err),
|
||||
zap.String("request-payload", string(body)))
|
||||
http.Error(w, "Failed to decode tap service request", http.StatusBadRequest)
|
||||
@@ -190,7 +199,7 @@ func (executor *Executor) tapServices(w http.ResponseWriter, r *http.Request) {
|
||||
continue
|
||||
}
|
||||
|
||||
err = et.TapService(svcHost)
|
||||
err = et.TapService(ctx, svcHost)
|
||||
if err != nil {
|
||||
errs = multierror.Append(errs,
|
||||
errors.Wrapf(err, "'%v' failed to tap function '%v' in '%v' with service url '%v'",
|
||||
@@ -199,7 +208,7 @@ func (executor *Executor) tapServices(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if errs.ErrorOrNil() != nil {
|
||||
executor.logger.Error("error tapping function service", zap.Error(errs))
|
||||
logger.Error("error tapping function service", zap.Error(errs))
|
||||
http.Error(w, "Not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
@@ -212,6 +221,7 @@ func (executor *Executor) healthHandler(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
func (executor *Executor) unTapService(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to read request", http.StatusInternalServerError)
|
||||
@@ -227,13 +237,13 @@ func (executor *Executor) unTapService(w http.ResponseWriter, r *http.Request) {
|
||||
t := tapSvcReq.FnExecutorType
|
||||
if t != fv1.ExecutorTypePoolmgr {
|
||||
msg := fmt.Sprintf("Unknown executor type '%v'", t)
|
||||
http.Error(w, msg, http.StatusBadRequest)
|
||||
http.Error(w, html.EscapeString(msg), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
et := executor.executorTypes[t]
|
||||
|
||||
et.UnTapService(key, tapSvcReq.ServiceURL)
|
||||
et.UnTapService(ctx, key, tapSvcReq.ServiceURL)
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
@@ -250,11 +260,17 @@ func (executor *Executor) GetHandler() http.Handler {
|
||||
}
|
||||
|
||||
// Serve starts an HTTP server.
|
||||
func (executor *Executor) Serve(port int) {
|
||||
func (executor *Executor) Serve(port int, openTracingEnabled bool) {
|
||||
executor.logger.Info("starting executor API", zap.Int("port", port))
|
||||
address := fmt.Sprintf(":%v", port)
|
||||
err := http.ListenAndServe(address, &ochttp.Handler{
|
||||
Handler: executor.GetHandler(),
|
||||
})
|
||||
|
||||
var handler http.Handler
|
||||
if openTracingEnabled {
|
||||
handler = &ochttp.Handler{Handler: executor.GetHandler()}
|
||||
} else {
|
||||
handler = otelUtils.GetHandlerWithOTEL(executor.GetHandler(), "fission-executor", otelUtils.UrlsToIgnore("/healthz"))
|
||||
}
|
||||
|
||||
err := http.ListenAndServe(address, handler)
|
||||
executor.logger.Fatal("done listening", zap.Error(err))
|
||||
}
|
||||
|
||||
@@ -28,12 +28,14 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"go.opencensus.io/plugin/ochttp"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/net/context/ctxhttp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
"github.com/fission/fission/pkg/utils/tracing"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -56,14 +58,19 @@ type (
|
||||
|
||||
// MakeClient initializes and returns a Client instance.
|
||||
func MakeClient(logger *zap.Logger, executorURL string) *Client {
|
||||
var hc *http.Client
|
||||
if tracing.TracingEnabled(logger) {
|
||||
hc = &http.Client{Transport: &ochttp.Transport{}}
|
||||
} else {
|
||||
hc = &http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)}
|
||||
}
|
||||
|
||||
c := &Client{
|
||||
logger: logger.Named("executor_client"),
|
||||
executorURL: strings.TrimSuffix(executorURL, "/"),
|
||||
tappedByURL: make(map[string]TapServiceRequest),
|
||||
requestChan: make(chan TapServiceRequest, 100),
|
||||
httpClient: &http.Client{
|
||||
Transport: &ochttp.Transport{},
|
||||
},
|
||||
httpClient: hc,
|
||||
}
|
||||
go c.service()
|
||||
return c
|
||||
@@ -143,8 +150,7 @@ func (c *Client) service() {
|
||||
svcReqs = append(svcReqs, req)
|
||||
}
|
||||
c.logger.Debug("tapped services in batch", zap.Int("service_count", len(urls)))
|
||||
|
||||
err := c._tapService(svcReqs)
|
||||
err := c._tapService(context.TODO(), svcReqs)
|
||||
if err != nil {
|
||||
c.logger.Error("error tapping function service address", zap.Error(err))
|
||||
}
|
||||
@@ -169,7 +175,7 @@ func (c *Client) TapService(fnMeta metav1.ObjectMeta, executorType fv1.ExecutorT
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) _tapService(tapSvcReqs []TapServiceRequest) error {
|
||||
func (c *Client) _tapService(ctx context.Context, tapSvcReqs []TapServiceRequest) error {
|
||||
executorURL := c.executorURL + "/v2/tapServices"
|
||||
|
||||
body, err := json.Marshal(tapSvcReqs)
|
||||
@@ -177,7 +183,7 @@ func (c *Client) _tapService(tapSvcReqs []TapServiceRequest) error {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := http.Post(executorURL, "application/json", bytes.NewReader(body))
|
||||
resp, err := ctxhttp.Post(ctx, c.httpClient, executorURL, "application/json", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright 2021 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package cms
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
k8sCache "k8s.io/client-go/tools/cache"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
"github.com/fission/fission/pkg/executor/executortype"
|
||||
)
|
||||
|
||||
func getConfigmapRelatedFuncs(ctx context.Context, logger *zap.Logger, m *metav1.ObjectMeta, fissionClient *crd.FissionClient) ([]fv1.Function, error) {
|
||||
funcList, err := fissionClient.CoreV1().Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// In future a cache that populates at start and is updated on changes might be better solution
|
||||
relatedFunctions := make([]fv1.Function, 0)
|
||||
for _, f := range funcList.Items {
|
||||
for _, cm := range f.Spec.ConfigMaps {
|
||||
if (cm.Name == m.Name) && (cm.Namespace == m.Namespace) {
|
||||
relatedFunctions = append(relatedFunctions, f)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return relatedFunctions, nil
|
||||
}
|
||||
|
||||
func ConfigMapEventHandlers(ctx context.Context, logger *zap.Logger, fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset, types map[fv1.ExecutorType]executortype.ExecutorType) k8sCache.ResourceEventHandlerFuncs {
|
||||
|
||||
return k8sCache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {},
|
||||
DeleteFunc: func(obj interface{}) {},
|
||||
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
|
||||
oldCm := oldObj.(*apiv1.ConfigMap)
|
||||
newCm := newObj.(*apiv1.ConfigMap)
|
||||
if oldCm.ObjectMeta.ResourceVersion != newCm.ObjectMeta.ResourceVersion {
|
||||
if newCm.ObjectMeta.Namespace != "kube-system" {
|
||||
logger.Debug("Configmap changed",
|
||||
zap.String("configmap_name", newCm.ObjectMeta.Name),
|
||||
zap.String("configmap_namespace", newCm.ObjectMeta.Namespace))
|
||||
}
|
||||
funcs, err := getConfigmapRelatedFuncs(ctx, logger, &newCm.ObjectMeta, fissionClient)
|
||||
if err != nil {
|
||||
logger.Error("Failed to get functions related to configmap", zap.String("configmap_name", newCm.ObjectMeta.Name), zap.String("configmap_namespace", newCm.ObjectMeta.Namespace))
|
||||
}
|
||||
refreshPods(ctx, logger, funcs, types)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -18,15 +18,11 @@ package cms
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
informerv1 "k8s.io/client-go/informers/core/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
@@ -38,133 +34,33 @@ type (
|
||||
ConfigSecretController struct {
|
||||
logger *zap.Logger
|
||||
|
||||
configmapController cache.Controller
|
||||
secretController cache.Controller
|
||||
|
||||
fissionClient *crd.FissionClient
|
||||
}
|
||||
)
|
||||
|
||||
//MakeConfigSecretController makes a controller for configmaps and secrets which changes related functions
|
||||
func MakeConfigSecretController(logger *zap.Logger, fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset, types map[fv1.ExecutorType]executortype.ExecutorType) *ConfigSecretController {
|
||||
// MakeConfigSecretController makes a controller for configmaps and secrets which changes related functions
|
||||
func MakeConfigSecretController(ctx context.Context, logger *zap.Logger, fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset, types map[fv1.ExecutorType]executortype.ExecutorType,
|
||||
configmapInformer informerv1.ConfigMapInformer,
|
||||
secretInformer informerv1.SecretInformer) *ConfigSecretController {
|
||||
logger.Debug("Creating ConfigMap & Secret Controller")
|
||||
_, cmcontroller := initConfigmapController(logger, fissionClient, kubernetesClient, types)
|
||||
_, scontroller := initSecretController(logger, fissionClient, kubernetesClient, types)
|
||||
cmsController := &ConfigSecretController{
|
||||
logger: logger,
|
||||
configmapController: cmcontroller,
|
||||
secretController: scontroller,
|
||||
fissionClient: fissionClient,
|
||||
logger: logger,
|
||||
fissionClient: fissionClient,
|
||||
}
|
||||
configmapInformer.Informer().AddEventHandler(ConfigMapEventHandlers(ctx, logger, fissionClient, kubernetesClient, types))
|
||||
secretInformer.Informer().AddEventHandler(SecretEventHandlers(ctx, logger, fissionClient, kubernetesClient, types))
|
||||
|
||||
return cmsController
|
||||
}
|
||||
|
||||
//Run runs the controllers for configmaps and secrets
|
||||
func (csController *ConfigSecretController) Run(ctx context.Context) {
|
||||
go csController.configmapController.Run(ctx.Done())
|
||||
go csController.secretController.Run(ctx.Done())
|
||||
}
|
||||
|
||||
func initConfigmapController(logger *zap.Logger, fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset, types map[fv1.ExecutorType]executortype.ExecutorType) (cache.Store, cache.Controller) {
|
||||
resyncPeriod := 30 * time.Second
|
||||
listWatch := cache.NewListWatchFromClient(kubernetesClient.CoreV1().RESTClient(), "configmaps", metav1.NamespaceAll, fields.Everything())
|
||||
store, controller := cache.NewInformer(listWatch, &apiv1.ConfigMap{}, resyncPeriod, cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {},
|
||||
DeleteFunc: func(obj interface{}) {},
|
||||
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
|
||||
oldCm := oldObj.(*apiv1.ConfigMap)
|
||||
newCm := newObj.(*apiv1.ConfigMap)
|
||||
if oldCm.ObjectMeta.ResourceVersion != newCm.ObjectMeta.ResourceVersion {
|
||||
if newCm.ObjectMeta.Namespace != "kube-system" {
|
||||
logger.Debug("Configmap changed",
|
||||
zap.String("configmap_name", newCm.ObjectMeta.Name),
|
||||
zap.String("configmap_namespace", newCm.ObjectMeta.Namespace))
|
||||
}
|
||||
funcs, err := getConfigmapRelatedFuncs(logger, &newCm.ObjectMeta, fissionClient)
|
||||
if err != nil {
|
||||
logger.Error("Failed to get functions related to configmap", zap.String("configmap_name", newCm.ObjectMeta.Name), zap.String("configmap_namespace", newCm.ObjectMeta.Namespace))
|
||||
}
|
||||
refreshPods(logger, funcs, types)
|
||||
}
|
||||
},
|
||||
})
|
||||
return store, controller
|
||||
}
|
||||
|
||||
func getConfigmapRelatedFuncs(logger *zap.Logger, m *metav1.ObjectMeta, fissionClient *crd.FissionClient) ([]fv1.Function, error) {
|
||||
funcList, err := fissionClient.CoreV1().Functions(metav1.NamespaceAll).List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// In future a cache that populates at start and is updated on changes might be better solution
|
||||
relatedFunctions := make([]fv1.Function, 0)
|
||||
for _, f := range funcList.Items {
|
||||
for _, cm := range f.Spec.ConfigMaps {
|
||||
if (cm.Name == m.Name) && (cm.Namespace == m.Namespace) {
|
||||
relatedFunctions = append(relatedFunctions, f)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return relatedFunctions, nil
|
||||
}
|
||||
|
||||
func initSecretController(logger *zap.Logger, fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset, types map[fv1.ExecutorType]executortype.ExecutorType) (cache.Store, cache.Controller) {
|
||||
resyncPeriod := 30 * time.Second
|
||||
listWatch := cache.NewListWatchFromClient(kubernetesClient.CoreV1().RESTClient(), "secrets", metav1.NamespaceAll, fields.Everything())
|
||||
store, controller := cache.NewInformer(listWatch, &apiv1.Secret{}, resyncPeriod, cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {},
|
||||
DeleteFunc: func(obj interface{}) {},
|
||||
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
|
||||
oldS := oldObj.(*apiv1.Secret)
|
||||
newS := newObj.(*apiv1.Secret)
|
||||
if oldS.ObjectMeta.ResourceVersion != newS.ObjectMeta.ResourceVersion {
|
||||
if newS.ObjectMeta.Namespace != "kube-system" {
|
||||
logger.Debug("Secret changed",
|
||||
zap.String("configmap_name", newS.ObjectMeta.Name),
|
||||
zap.String("configmap_namespace", newS.ObjectMeta.Namespace))
|
||||
|
||||
}
|
||||
funcs, err := getSecretRelatedFuncs(logger, &newS.ObjectMeta, fissionClient)
|
||||
if err != nil {
|
||||
logger.Error("Failed to get functions related to secret", zap.String("secret_name", newS.ObjectMeta.Name), zap.String("secret_namespace", newS.ObjectMeta.Namespace))
|
||||
}
|
||||
refreshPods(logger, funcs, types)
|
||||
}
|
||||
},
|
||||
})
|
||||
return store, controller
|
||||
|
||||
}
|
||||
|
||||
func getSecretRelatedFuncs(logger *zap.Logger, m *metav1.ObjectMeta, fissionClient *crd.FissionClient) ([]fv1.Function, error) {
|
||||
funcList, err := fissionClient.CoreV1().Functions(metav1.NamespaceAll).List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// In future a cache that populates at start and is updated on changes might be better solution
|
||||
relatedFunctions := make([]fv1.Function, 0)
|
||||
for _, f := range funcList.Items {
|
||||
for _, secret := range f.Spec.Secrets {
|
||||
if (secret.Name == m.Name) && (secret.Namespace == m.Namespace) {
|
||||
relatedFunctions = append(relatedFunctions, f)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return relatedFunctions, nil
|
||||
}
|
||||
|
||||
func refreshPods(logger *zap.Logger, funcs []fv1.Function, types map[fv1.ExecutorType]executortype.ExecutorType) {
|
||||
func refreshPods(ctx context.Context, logger *zap.Logger, funcs []fv1.Function, types map[fv1.ExecutorType]executortype.ExecutorType) {
|
||||
for _, f := range funcs {
|
||||
var err error
|
||||
|
||||
et, exists := types[f.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType]
|
||||
if exists {
|
||||
err = et.RefreshFuncPods(logger, f)
|
||||
err = et.RefreshFuncPods(ctx, logger, f)
|
||||
} else {
|
||||
err = errors.Errorf("Unknown executor type '%v'", f.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright 2021 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package cms
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
k8sCache "k8s.io/client-go/tools/cache"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
"github.com/fission/fission/pkg/executor/executortype"
|
||||
)
|
||||
|
||||
func getSecretRelatedFuncs(ctx context.Context, logger *zap.Logger, m *metav1.ObjectMeta, fissionClient *crd.FissionClient) ([]fv1.Function, error) {
|
||||
funcList, err := fissionClient.CoreV1().Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// In future a cache that populates at start and is updated on changes might be better solution
|
||||
relatedFunctions := make([]fv1.Function, 0)
|
||||
for _, f := range funcList.Items {
|
||||
for _, secret := range f.Spec.Secrets {
|
||||
if (secret.Name == m.Name) && (secret.Namespace == m.Namespace) {
|
||||
relatedFunctions = append(relatedFunctions, f)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return relatedFunctions, nil
|
||||
}
|
||||
|
||||
func SecretEventHandlers(ctx context.Context, logger *zap.Logger, fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset, types map[fv1.ExecutorType]executortype.ExecutorType) k8sCache.ResourceEventHandlerFuncs {
|
||||
return k8sCache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {},
|
||||
DeleteFunc: func(obj interface{}) {},
|
||||
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
|
||||
oldS := oldObj.(*apiv1.Secret)
|
||||
newS := newObj.(*apiv1.Secret)
|
||||
if oldS.ObjectMeta.ResourceVersion != newS.ObjectMeta.ResourceVersion {
|
||||
if newS.ObjectMeta.Namespace != "kube-system" {
|
||||
logger.Debug("Secret changed",
|
||||
zap.String("configmap_name", newS.ObjectMeta.Name),
|
||||
zap.String("configmap_namespace", newS.ObjectMeta.Namespace))
|
||||
}
|
||||
funcs, err := getSecretRelatedFuncs(ctx, logger, &newS.ObjectMeta, fissionClient)
|
||||
if err != nil {
|
||||
logger.Error("Failed to get functions related to secret", zap.String("secret_name", newS.ObjectMeta.Name), zap.String("secret_namespace", newS.ObjectMeta.Namespace))
|
||||
}
|
||||
refreshPods(ctx, logger, funcs, types)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
+106
-28
@@ -30,17 +30,23 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"go.uber.org/zap"
|
||||
k8sInformers "k8s.io/client-go/informers"
|
||||
k8sCache "k8s.io/client-go/tools/cache"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
"github.com/fission/fission/pkg/executor/cms"
|
||||
"github.com/fission/fission/pkg/executor/executortype"
|
||||
"github.com/fission/fission/pkg/executor/executortype/container"
|
||||
"github.com/fission/fission/pkg/executor/executortype/newdeploy"
|
||||
"github.com/fission/fission/pkg/executor/executortype/poolmgr"
|
||||
"github.com/fission/fission/pkg/executor/fscache"
|
||||
"github.com/fission/fission/pkg/executor/reaper"
|
||||
"github.com/fission/fission/pkg/executor/util"
|
||||
fetcherConfig "github.com/fission/fission/pkg/fetcher/config"
|
||||
genInformer "github.com/fission/fission/pkg/generated/informers/externalversions"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
otelUtils "github.com/fission/fission/pkg/utils/otel"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -54,10 +60,11 @@ type (
|
||||
fissionClient *crd.FissionClient
|
||||
|
||||
requestChan chan *createFuncServiceRequest
|
||||
fsCreateWg map[string]*sync.WaitGroup
|
||||
fsCreateWg sync.Map
|
||||
}
|
||||
|
||||
createFuncServiceRequest struct {
|
||||
context context.Context
|
||||
function *fv1.Function
|
||||
respChan chan *createFuncServiceResponse
|
||||
}
|
||||
@@ -69,8 +76,9 @@ type (
|
||||
)
|
||||
|
||||
// MakeExecutor returns an Executor for given ExecutorType(s).
|
||||
func MakeExecutor(logger *zap.Logger, cms *cms.ConfigSecretController,
|
||||
fissionClient *crd.FissionClient, types map[fv1.ExecutorType]executortype.ExecutorType) (*Executor, error) {
|
||||
func MakeExecutor(ctx context.Context, logger *zap.Logger, cms *cms.ConfigSecretController,
|
||||
fissionClient *crd.FissionClient, types map[fv1.ExecutorType]executortype.ExecutorType,
|
||||
informers []k8sCache.SharedIndexInformer) (*Executor, error) {
|
||||
executor := &Executor{
|
||||
logger: logger.Named("executor"),
|
||||
cms: cms,
|
||||
@@ -78,14 +86,19 @@ func MakeExecutor(logger *zap.Logger, cms *cms.ConfigSecretController,
|
||||
executorTypes: types,
|
||||
|
||||
requestChan: make(chan *createFuncServiceRequest),
|
||||
fsCreateWg: make(map[string]*sync.WaitGroup),
|
||||
}
|
||||
|
||||
// Run all informers
|
||||
for _, informer := range informers {
|
||||
go informer.Run(ctx.Done())
|
||||
}
|
||||
|
||||
for _, et := range types {
|
||||
go func(et executortype.ExecutorType) {
|
||||
et.Run(context.Background())
|
||||
et.Run(ctx)
|
||||
}(et)
|
||||
}
|
||||
go cms.Run(context.Background())
|
||||
|
||||
go executor.serveCreateFuncServices()
|
||||
|
||||
return executor, nil
|
||||
@@ -114,7 +127,7 @@ func (executor *Executor) serveCreateFuncServices() {
|
||||
specializationTimeout = fv1.DefaultSpecializationTimeOut
|
||||
}
|
||||
|
||||
fnSpecializationTimeoutContext, cancel := context.WithTimeout(context.Background(),
|
||||
fnSpecializationTimeoutContext, cancel := context.WithTimeout(req.context,
|
||||
time.Duration(specializationTimeout+buffer)*time.Second)
|
||||
defer cancel()
|
||||
|
||||
@@ -128,13 +141,13 @@ func (executor *Executor) serveCreateFuncServices() {
|
||||
}
|
||||
|
||||
// Cache miss -- is this first one to request the func?
|
||||
wg, found := executor.fsCreateWg[crd.CacheKey(fnMetadata)]
|
||||
wg, found := executor.fsCreateWg.Load(crd.CacheKey(fnMetadata))
|
||||
if !found {
|
||||
// create a waitgroup for other requests for
|
||||
// the same function to wait on
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
executor.fsCreateWg[crd.CacheKey(fnMetadata)] = wg
|
||||
executor.fsCreateWg.Store(crd.CacheKey(fnMetadata), wg)
|
||||
|
||||
// launch a goroutine for each request, to parallelize
|
||||
// the specialization of different functions
|
||||
@@ -157,7 +170,7 @@ func (executor *Executor) serveCreateFuncServices() {
|
||||
specializationTimeout = fv1.DefaultSpecializationTimeOut
|
||||
}
|
||||
|
||||
fnSpecializationTimeoutContext, cancel := context.WithTimeout(context.Background(),
|
||||
fnSpecializationTimeoutContext, cancel := context.WithTimeout(req.context,
|
||||
time.Duration(specializationTimeout+buffer)*time.Second)
|
||||
defer cancel()
|
||||
|
||||
@@ -166,7 +179,7 @@ func (executor *Executor) serveCreateFuncServices() {
|
||||
funcSvc: fsvc,
|
||||
err: err,
|
||||
}
|
||||
delete(executor.fsCreateWg, crd.CacheKey(fnMetadata))
|
||||
executor.fsCreateWg.Delete(crd.CacheKey(fnMetadata))
|
||||
wg.Done()
|
||||
}()
|
||||
} else {
|
||||
@@ -174,10 +187,18 @@ func (executor *Executor) serveCreateFuncServices() {
|
||||
go func() {
|
||||
executor.logger.Debug("waiting for concurrent request for the same function",
|
||||
zap.Any("function", fnMetadata))
|
||||
wg, ok := wg.(*sync.WaitGroup)
|
||||
if !ok {
|
||||
err := fmt.Errorf("could not convert value to workgroup for function %v in namespace %v", fnMetadata.Name, fnMetadata.Namespace)
|
||||
req.respChan <- &createFuncServiceResponse{
|
||||
funcSvc: nil,
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
// get the function service from the cache
|
||||
fsvc, err := executor.getFunctionServiceFromCache(req.function)
|
||||
fsvc, err := executor.getFunctionServiceFromCache(req.context, req.function)
|
||||
|
||||
// fsCache return error when the entry does not exist/expire.
|
||||
// It normally happened if there are multiple requests are
|
||||
@@ -194,7 +215,9 @@ func (executor *Executor) serveCreateFuncServices() {
|
||||
}
|
||||
|
||||
func (executor *Executor) createServiceForFunction(ctx context.Context, fn *fv1.Function) (*fscache.FuncSvc, error) {
|
||||
executor.logger.Debug("no cached function service found, creating one",
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, executor.logger)
|
||||
otelUtils.SpanTrackEvent(ctx, "createServiceForFunction", otelUtils.GetAttributesForFunction(fn)...)
|
||||
logger.Debug("no cached function service found, creating one",
|
||||
zap.String("function_name", fn.ObjectMeta.Name),
|
||||
zap.String("function_namespace", fn.ObjectMeta.Namespace))
|
||||
|
||||
@@ -207,7 +230,7 @@ func (executor *Executor) createServiceForFunction(ctx context.Context, fn *fv1.
|
||||
fsvc, fsvcErr := e.GetFuncSvc(ctx, fn)
|
||||
if fsvcErr != nil {
|
||||
e := "error creating service for function"
|
||||
executor.logger.Error(e,
|
||||
logger.Error(e,
|
||||
zap.Error(fsvcErr),
|
||||
zap.String("function_name", fn.ObjectMeta.Name),
|
||||
zap.String("function_namespace", fn.ObjectMeta.Namespace))
|
||||
@@ -217,13 +240,14 @@ func (executor *Executor) createServiceForFunction(ctx context.Context, fn *fv1.
|
||||
return fsvc, fsvcErr
|
||||
}
|
||||
|
||||
func (executor *Executor) getFunctionServiceFromCache(fn *fv1.Function) (*fscache.FuncSvc, error) {
|
||||
func (executor *Executor) getFunctionServiceFromCache(ctx context.Context, fn *fv1.Function) (*fscache.FuncSvc, error) {
|
||||
otelUtils.SpanTrackEvent(ctx, "getFunctionServiceFromCache", otelUtils.GetAttributesForFunction(fn)...)
|
||||
t := fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType
|
||||
e, ok := executor.executorTypes[t]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("Unknown executor type '%v'", t)
|
||||
}
|
||||
return e.GetFuncSvcFromCache(fn)
|
||||
return e.GetFuncSvcFromCache(ctx, fn)
|
||||
}
|
||||
|
||||
func serveMetric(logger *zap.Logger) {
|
||||
@@ -237,7 +261,7 @@ func serveMetric(logger *zap.Logger) {
|
||||
|
||||
// StartExecutor Starts executor and the executor components such as Poolmgr,
|
||||
// deploymgr and potential future executor types
|
||||
func StartExecutor(logger *zap.Logger, functionNamespace string, envBuilderNamespace string, port int) error {
|
||||
func StartExecutor(logger *zap.Logger, functionNamespace string, envBuilderNamespace string, port int, openTracingEnabled bool) error {
|
||||
fissionClient, kubernetesClient, _, metricsClient, err := crd.MakeFissionClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get kubernetes client")
|
||||
@@ -257,25 +281,63 @@ func StartExecutor(logger *zap.Logger, functionNamespace string, envBuilderNames
|
||||
|
||||
logger.Info("Starting executor", zap.String("instanceID", executorInstanceID))
|
||||
|
||||
informerFactory := genInformer.NewSharedInformerFactory(fissionClient, time.Minute*30)
|
||||
funcInformer := informerFactory.Core().V1().Functions()
|
||||
pkgInformer := informerFactory.Core().V1().Packages()
|
||||
envInformer := informerFactory.Core().V1().Environments()
|
||||
|
||||
gpmInformerFactory, err := utils.GetInformerFactoryByExecutor(kubernetesClient, fv1.ExecutorTypePoolmgr, time.Minute*30)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gpmPodInformer := gpmInformerFactory.Core().V1().Pods()
|
||||
gpmRsInformer := gpmInformerFactory.Apps().V1().ReplicaSets()
|
||||
gpm, err := poolmgr.MakeGenericPoolManager(
|
||||
logger,
|
||||
fissionClient, kubernetesClient, metricsClient,
|
||||
functionNamespace, fetcherConfig, executorInstanceID)
|
||||
functionNamespace, fetcherConfig, executorInstanceID,
|
||||
funcInformer, pkgInformer, envInformer,
|
||||
gpmPodInformer, gpmRsInformer)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "pool manager creation faied")
|
||||
}
|
||||
|
||||
ndmInformerFactory, err := utils.GetInformerFactoryByExecutor(kubernetesClient, fv1.ExecutorTypeNewdeploy, time.Minute*30)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ndmDeplInformer := ndmInformerFactory.Apps().V1().Deployments()
|
||||
ndmSvcInformer := ndmInformerFactory.Core().V1().Services()
|
||||
ndm, err := newdeploy.MakeNewDeploy(
|
||||
logger,
|
||||
fissionClient, kubernetesClient, fissionClient.CoreV1().RESTClient(),
|
||||
functionNamespace, fetcherConfig, executorInstanceID)
|
||||
fissionClient, kubernetesClient,
|
||||
functionNamespace, fetcherConfig, executorInstanceID,
|
||||
funcInformer, envInformer,
|
||||
ndmDeplInformer, ndmSvcInformer)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "new deploy manager creation faied")
|
||||
}
|
||||
|
||||
cnmInformerFactory, err := utils.GetInformerFactoryByExecutor(kubernetesClient, fv1.ExecutorTypeContainer, time.Minute*30)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cnmDeplInformer := cnmInformerFactory.Apps().V1().Deployments()
|
||||
cnmSvcInformer := cnmInformerFactory.Core().V1().Services()
|
||||
ctx := context.Background()
|
||||
cnm, err := container.MakeContainer(
|
||||
ctx, logger,
|
||||
fissionClient, kubernetesClient,
|
||||
functionNamespace, executorInstanceID, funcInformer,
|
||||
cnmDeplInformer, cnmSvcInformer)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "container manager creation faied")
|
||||
}
|
||||
|
||||
executorTypes := make(map[fv1.ExecutorType]executortype.ExecutorType)
|
||||
executorTypes[gpm.GetTypeName()] = gpm
|
||||
executorTypes[ndm.GetTypeName()] = ndm
|
||||
executorTypes[gpm.GetTypeName(ctx)] = gpm
|
||||
executorTypes[ndm.GetTypeName(ctx)] = ndm
|
||||
executorTypes[cnm.GetTypeName(ctx)] = cnm
|
||||
|
||||
adoptExistingResources, _ := strconv.ParseBool(os.Getenv("ADOPT_EXISTING_RESOURCES"))
|
||||
|
||||
@@ -285,24 +347,40 @@ func StartExecutor(logger *zap.Logger, functionNamespace string, envBuilderNames
|
||||
go func(et executortype.ExecutorType) {
|
||||
defer wg.Done()
|
||||
if adoptExistingResources {
|
||||
et.AdoptExistingResources()
|
||||
et.AdoptExistingResources(ctx)
|
||||
}
|
||||
et.CleanupOldExecutorObjects()
|
||||
et.CleanupOldExecutorObjects(ctx)
|
||||
}(et)
|
||||
}
|
||||
// set hard timeout for resource adoption
|
||||
// TODO: use context to control the waiting time once kubernetes client supports it.
|
||||
util.WaitTimeout(wg, 30*time.Second)
|
||||
|
||||
cms := cms.MakeConfigSecretController(logger, fissionClient, kubernetesClient, executorTypes)
|
||||
k8sInformerFactory := k8sInformers.NewSharedInformerFactory(kubernetesClient, time.Minute*30)
|
||||
configmapInformer := k8sInformerFactory.Core().V1().ConfigMaps()
|
||||
secretInformer := k8sInformerFactory.Core().V1().Secrets()
|
||||
|
||||
api, err := MakeExecutor(logger, cms, fissionClient, executorTypes)
|
||||
cms := cms.MakeConfigSecretController(ctx, logger, fissionClient, kubernetesClient, executorTypes, configmapInformer, secretInformer)
|
||||
|
||||
api, err := MakeExecutor(ctx, logger, cms, fissionClient, executorTypes,
|
||||
[]k8sCache.SharedIndexInformer{
|
||||
funcInformer.Informer(),
|
||||
pkgInformer.Informer(),
|
||||
envInformer.Informer(),
|
||||
configmapInformer.Informer(),
|
||||
secretInformer.Informer(),
|
||||
gpmPodInformer.Informer(),
|
||||
gpmRsInformer.Informer(),
|
||||
ndmDeplInformer.Informer(),
|
||||
ndmSvcInformer.Informer(),
|
||||
cnmDeplInformer.Informer(),
|
||||
cnmSvcInformer.Informer(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go reaper.CleanupRoleBindings(logger, kubernetesClient, fissionClient, functionNamespace, envBuilderNamespace, time.Minute*30)
|
||||
go api.Serve(port)
|
||||
go api.Serve(port, openTracingEnabled)
|
||||
go serveMetric(logger)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -173,7 +173,7 @@ func TestExecutor(t *testing.T) {
|
||||
|
||||
// create poolmgr
|
||||
port := 9999
|
||||
err = StartExecutor(logger, functionNs, "fission-builder", port)
|
||||
err = StartExecutor(logger, functionNs, "fission-builder", port, true)
|
||||
if err != nil {
|
||||
log.Panicf("failed to start poolmgr: %v", err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
Copyright 2020 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"go.uber.org/zap"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
k8s_err "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
// getResources gets the resources(CPU, memory) set for the function
|
||||
func (cn *Container) getResources(fn *fv1.Function) apiv1.ResourceRequirements {
|
||||
resources := fn.Spec.Resources
|
||||
if resources.Requests == nil {
|
||||
resources.Requests = make(map[apiv1.ResourceName]resource.Quantity)
|
||||
}
|
||||
if resources.Limits == nil {
|
||||
resources.Limits = make(map[apiv1.ResourceName]resource.Quantity)
|
||||
}
|
||||
|
||||
val, ok := fn.Spec.Resources.Requests[apiv1.ResourceCPU]
|
||||
if ok && !val.IsZero() {
|
||||
resources.Requests[apiv1.ResourceCPU] = fn.Spec.Resources.Requests[apiv1.ResourceCPU]
|
||||
}
|
||||
|
||||
val, ok = fn.Spec.Resources.Requests[apiv1.ResourceMemory]
|
||||
if ok && !val.IsZero() {
|
||||
resources.Requests[apiv1.ResourceMemory] = fn.Spec.Resources.Requests[apiv1.ResourceMemory]
|
||||
}
|
||||
|
||||
val, ok = fn.Spec.Resources.Limits[apiv1.ResourceCPU]
|
||||
if ok && !val.IsZero() {
|
||||
resources.Limits[apiv1.ResourceCPU] = fn.Spec.Resources.Limits[apiv1.ResourceCPU]
|
||||
}
|
||||
|
||||
val, ok = fn.Spec.Resources.Limits[apiv1.ResourceMemory]
|
||||
if ok && !val.IsZero() {
|
||||
resources.Limits[apiv1.ResourceMemory] = fn.Spec.Resources.Limits[apiv1.ResourceMemory]
|
||||
}
|
||||
|
||||
return resources
|
||||
}
|
||||
|
||||
// cleanupContainer cleans all kubernetes objects related to function
|
||||
func (cn *Container) cleanupContainer(ctx context.Context, ns string, name string) error {
|
||||
result := &multierror.Error{}
|
||||
|
||||
err := cn.deleteSvc(ctx, ns, name)
|
||||
if err != nil && !k8s_err.IsNotFound(err) {
|
||||
cn.logger.Error("error deleting service for Container function",
|
||||
zap.Error(err),
|
||||
zap.String("function_name", name),
|
||||
zap.String("function_namespace", ns))
|
||||
result = multierror.Append(result, err)
|
||||
}
|
||||
|
||||
err = cn.deleteHpa(ctx, ns, name)
|
||||
if err != nil && !k8s_err.IsNotFound(err) {
|
||||
cn.logger.Error("error deleting HPA for Container function",
|
||||
zap.Error(err),
|
||||
zap.String("function_name", name),
|
||||
zap.String("function_namespace", ns))
|
||||
result = multierror.Append(result, err)
|
||||
}
|
||||
|
||||
err = cn.deleteDeployment(ctx, ns, name)
|
||||
if err != nil && !k8s_err.IsNotFound(err) {
|
||||
cn.logger.Error("error deleting deployment for Container function",
|
||||
zap.Error(err),
|
||||
zap.String("function_name", name),
|
||||
zap.String("function_namespace", ns))
|
||||
result = multierror.Append(result, err)
|
||||
}
|
||||
|
||||
return result.ErrorOrNil()
|
||||
}
|
||||
|
||||
// referencedResourcesRVSum returns the sum of resource version of all resources the function references to.
|
||||
// We used to update timestamp in the deployment environment field in order to trigger a rolling update when
|
||||
// the function referenced resources get updated. However, use timestamp means we are not able to avoid tri-
|
||||
// ggering a rolling update when executor tries to adopt orphaned deployment due to timestamp changed which
|
||||
// is unwanted. In order to let executor adopt deployment without triggering a rolling update, we need an
|
||||
// identical way to get a value that can reflect resources changed without affecting by the time.
|
||||
// To achieve this goal, the sum of the resource version of all referenced resources is a good fit for our
|
||||
// scenario since the sum of the resource version is always the same as long as no resources changed.
|
||||
func referencedResourcesRVSum(ctx context.Context, client *kubernetes.Clientset, namespace string, secrets []fv1.SecretReference, cfgmaps []fv1.ConfigMapReference) (int, error) {
|
||||
rvCount := 0
|
||||
|
||||
if len(secrets) > 0 {
|
||||
list, err := client.CoreV1().Secrets(namespace).List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
objmap := make(map[string]apiv1.Secret)
|
||||
for _, secret := range list.Items {
|
||||
objmap[secret.Namespace+"/"+secret.Name] = secret
|
||||
}
|
||||
|
||||
for _, ref := range secrets {
|
||||
s, ok := objmap[ref.Namespace+"/"+ref.Name]
|
||||
if ok {
|
||||
rv, _ := strconv.ParseInt(s.ResourceVersion, 10, 32)
|
||||
rvCount += int(rv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(cfgmaps) > 0 {
|
||||
list, err := client.CoreV1().ConfigMaps(namespace).List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
objmap := make(map[string]apiv1.ConfigMap)
|
||||
for _, cfg := range list.Items {
|
||||
objmap[cfg.Namespace+"/"+cfg.Name] = cfg
|
||||
}
|
||||
|
||||
for _, ref := range cfgmaps {
|
||||
s, ok := objmap[ref.Namespace+"/"+ref.Name]
|
||||
if ok {
|
||||
rv, _ := strconv.ParseInt(s.ResourceVersion, 10, 32)
|
||||
rvCount += int(rv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rvCount, nil
|
||||
}
|
||||
@@ -0,0 +1,774 @@
|
||||
/*
|
||||
Copyright 2020 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
k8sErrs "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
k8sTypes "k8s.io/apimachinery/pkg/types"
|
||||
appsinformers "k8s.io/client-go/informers/apps/v1"
|
||||
coreinformers "k8s.io/client-go/informers/core/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
appslisters "k8s.io/client-go/listers/apps/v1"
|
||||
corelisters "k8s.io/client-go/listers/core/v1"
|
||||
k8sCache "k8s.io/client-go/tools/cache"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
"github.com/fission/fission/pkg/executor/executortype"
|
||||
"github.com/fission/fission/pkg/executor/fscache"
|
||||
"github.com/fission/fission/pkg/executor/reaper"
|
||||
finformerv1 "github.com/fission/fission/pkg/generated/informers/externalversions/core/v1"
|
||||
"github.com/fission/fission/pkg/throttler"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
"github.com/fission/fission/pkg/utils/maps"
|
||||
otelUtils "github.com/fission/fission/pkg/utils/otel"
|
||||
)
|
||||
|
||||
var _ executortype.ExecutorType = &Container{}
|
||||
|
||||
type (
|
||||
// Container represents an executor type
|
||||
Container struct {
|
||||
logger *zap.Logger
|
||||
|
||||
kubernetesClient *kubernetes.Clientset
|
||||
fissionClient *crd.FissionClient
|
||||
instanceID string
|
||||
// fetcherConfig *fetcherConfig.Config
|
||||
|
||||
runtimeImagePullPolicy apiv1.PullPolicy
|
||||
namespace string
|
||||
useIstio bool
|
||||
|
||||
fsCache *fscache.FunctionServiceCache // cache funcSvc's by function, address and pod name
|
||||
|
||||
throttler *throttler.Throttler
|
||||
|
||||
defaultIdlePodReapTime time.Duration
|
||||
|
||||
deplLister appslisters.DeploymentLister
|
||||
svcLister corelisters.ServiceLister
|
||||
|
||||
deplListerSynced k8sCache.InformerSynced
|
||||
svcListerSynced k8sCache.InformerSynced
|
||||
}
|
||||
)
|
||||
|
||||
// MakeContainer initializes and returns an instance of CaaF
|
||||
func MakeContainer(
|
||||
ctx context.Context,
|
||||
logger *zap.Logger,
|
||||
fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset,
|
||||
namespace string,
|
||||
instanceID string,
|
||||
funcInformer finformerv1.FunctionInformer,
|
||||
deplInformer appsinformers.DeploymentInformer,
|
||||
svcInformer coreinformers.ServiceInformer,
|
||||
) (executortype.ExecutorType, error) {
|
||||
enableIstio := false
|
||||
if len(os.Getenv("ENABLE_ISTIO")) > 0 {
|
||||
istio, err := strconv.ParseBool(os.Getenv("ENABLE_ISTIO"))
|
||||
if err != nil {
|
||||
logger.Error("failed to parse 'ENABLE_ISTIO', set to false", zap.Error(err))
|
||||
}
|
||||
enableIstio = istio
|
||||
}
|
||||
|
||||
caaf := &Container{
|
||||
logger: logger.Named("CaaF"),
|
||||
|
||||
fissionClient: fissionClient,
|
||||
kubernetesClient: kubernetesClient,
|
||||
instanceID: instanceID,
|
||||
|
||||
namespace: namespace,
|
||||
fsCache: fscache.MakeFunctionServiceCache(logger),
|
||||
throttler: throttler.MakeThrottler(1 * time.Minute),
|
||||
|
||||
runtimeImagePullPolicy: utils.GetImagePullPolicy(os.Getenv("RUNTIME_IMAGE_PULL_POLICY")),
|
||||
useIstio: enableIstio,
|
||||
// Time is set slightly higher than NewDeploy as cold starts are longer for CaaF
|
||||
defaultIdlePodReapTime: 1 * time.Minute,
|
||||
}
|
||||
caaf.deplLister = deplInformer.Lister()
|
||||
caaf.deplListerSynced = deplInformer.Informer().HasSynced
|
||||
|
||||
caaf.svcLister = svcInformer.Lister()
|
||||
caaf.svcListerSynced = svcInformer.Informer().HasSynced
|
||||
|
||||
funcInformer.Informer().AddEventHandler(caaf.FuncInformerHandler(ctx))
|
||||
return caaf, nil
|
||||
}
|
||||
|
||||
// Run start the function along with an object reaper.
|
||||
func (caaf *Container) Run(ctx context.Context) {
|
||||
if ok := k8sCache.WaitForCacheSync(ctx.Done(), caaf.deplListerSynced, caaf.svcListerSynced); !ok {
|
||||
caaf.logger.Fatal("failed to wait for caches to sync")
|
||||
}
|
||||
go caaf.idleObjectReaper()
|
||||
}
|
||||
|
||||
// GetTypeName returns the executor type name.
|
||||
func (caaf *Container) GetTypeName(ctx context.Context) fv1.ExecutorType {
|
||||
return fv1.ExecutorTypeContainer
|
||||
}
|
||||
|
||||
// GetTotalAvailable has not been implemented for CaaF.
|
||||
func (caaf *Container) GetTotalAvailable(fn *fv1.Function) int {
|
||||
// Not Implemented for CaaF.
|
||||
return 0
|
||||
}
|
||||
|
||||
// UnTapService has not been implemented for CaaF.
|
||||
func (caaf *Container) UnTapService(ctx context.Context, key string, svcHost string) {
|
||||
// Not Implemented for CaaF.
|
||||
}
|
||||
|
||||
// GetFuncSvc returns a function service; error otherwise.
|
||||
func (caaf *Container) GetFuncSvc(ctx context.Context, fn *fv1.Function) (*fscache.FuncSvc, error) {
|
||||
return caaf.createFunction(ctx, fn)
|
||||
}
|
||||
|
||||
// GetFuncSvcFromCache returns a function service from cache; error otherwise.
|
||||
func (caaf *Container) GetFuncSvcFromCache(ctx context.Context, fn *fv1.Function) (*fscache.FuncSvc, error) {
|
||||
otelUtils.SpanTrackEvent(ctx, "GetFuncSvcFromCache", otelUtils.GetAttributesForFunction(fn)...)
|
||||
return caaf.fsCache.GetByFunction(&fn.ObjectMeta)
|
||||
}
|
||||
|
||||
// DeleteFuncSvcFromCache deletes a function service from cache.
|
||||
func (caaf *Container) DeleteFuncSvcFromCache(ctx context.Context, fsvc *fscache.FuncSvc) {
|
||||
caaf.fsCache.DeleteEntry(fsvc)
|
||||
}
|
||||
|
||||
// GetFuncSvcFromPoolCache has not been implemented for Container Functions
|
||||
func (caaf *Container) GetFuncSvcFromPoolCache(ctx context.Context, fn *fv1.Function, requestsPerPod int) (*fscache.FuncSvc, int, error) {
|
||||
// Not Implemented for NewDeployment. Will be used when support of concurrent specialization of same function is added.
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
// TapService makes a TouchByAddress request to the cache.
|
||||
func (caaf *Container) TapService(ctx context.Context, svcHost string) error {
|
||||
err := caaf.fsCache.TouchByAddress(svcHost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsValid does a get on the service address to ensure it's a valid service, then
|
||||
// scale deployment to 1 replica if there are no available replicas for function.
|
||||
// Return true if no error occurs, return false otherwise.
|
||||
func (caaf *Container) IsValid(ctx context.Context, fsvc *fscache.FuncSvc) bool {
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, caaf.logger)
|
||||
otelUtils.SpanTrackEvent(ctx, "IsValid", otelUtils.GetAttributesForFuncSvc(fsvc)...)
|
||||
if len(strings.Split(fsvc.Address, ".")) == 0 {
|
||||
logger.Error("address not found in function service")
|
||||
return false
|
||||
}
|
||||
if len(fsvc.KubernetesObjects) == 0 {
|
||||
logger.Error("no kubernetes object related to function", zap.String("function", fsvc.Function.Name))
|
||||
return false
|
||||
}
|
||||
for _, obj := range fsvc.KubernetesObjects {
|
||||
if strings.ToLower(obj.Kind) == "service" {
|
||||
_, err := caaf.svcLister.Services(obj.Namespace).Get(obj.Name)
|
||||
if err != nil {
|
||||
if !k8sErrs.IsNotFound(err) {
|
||||
logger.Error("error validating function service", zap.String("function", fsvc.Function.Name), zap.Error(err))
|
||||
}
|
||||
return false
|
||||
}
|
||||
} else if strings.ToLower(obj.Kind) == "deployment" {
|
||||
currentDeploy, err := caaf.deplLister.Deployments(obj.Namespace).Get(obj.Name)
|
||||
if err != nil {
|
||||
if !k8sErrs.IsNotFound(err) {
|
||||
logger.Error("error validating function deployment", zap.String("function", fsvc.Function.Name), zap.Error(err))
|
||||
}
|
||||
return false
|
||||
}
|
||||
if currentDeploy.Status.AvailableReplicas < 1 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// RefreshFuncPods deletes pods related to the function so that new pods are replenished
|
||||
func (caaf *Container) RefreshFuncPods(ctx context.Context, logger *zap.Logger, f fv1.Function) error {
|
||||
|
||||
funcLabels := caaf.getDeployLabels(f.ObjectMeta)
|
||||
|
||||
dep, err := caaf.kubernetesClient.AppsV1().Deployments(metav1.NamespaceAll).List(ctx, metav1.ListOptions{
|
||||
LabelSelector: labels.Set(funcLabels).AsSelector().String(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Ideally there should be only one deployment but for now we rely on label/selector to ensure that condition
|
||||
for _, deployment := range dep.Items {
|
||||
rvCount, err := referencedResourcesRVSum(ctx, caaf.kubernetesClient, deployment.Namespace, f.Spec.Secrets, f.Spec.ConfigMaps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
patch := fmt.Sprintf(`{"spec" : {"template": {"spec":{"containers":[{"name": "%s", "env":[{"name": "%s", "value": "%v"}]}]}}}}`,
|
||||
f.ObjectMeta.Name, fv1.ResourceVersionCount, rvCount)
|
||||
|
||||
_, err = caaf.kubernetesClient.AppsV1().Deployments(deployment.ObjectMeta.Namespace).Patch(ctx, deployment.ObjectMeta.Name,
|
||||
k8sTypes.StrategicMergePatchType,
|
||||
[]byte(patch), metav1.PatchOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AdoptExistingResources attempts to adopt resources for functions in all namespaces.
|
||||
func (caaf *Container) AdoptExistingResources(ctx context.Context) {
|
||||
fnList, err := caaf.fissionClient.CoreV1().Functions(metav1.NamespaceAll).List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
caaf.logger.Error("error getting function list", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
|
||||
for i := range fnList.Items {
|
||||
fn := &fnList.Items[i]
|
||||
if fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType == fv1.ExecutorTypeContainer {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
_, err = caaf.fnCreate(ctx, fn)
|
||||
if err != nil {
|
||||
caaf.logger.Warn("failed to adopt resources for function", zap.Error(err))
|
||||
return
|
||||
}
|
||||
caaf.logger.Info("adopt resources for function", zap.String("function", fn.ObjectMeta.Name))
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// CleanupOldExecutorObjects cleans orphaned resources.
|
||||
func (caaf *Container) CleanupOldExecutorObjects(ctx context.Context) {
|
||||
caaf.logger.Info("CaaF starts to clean orphaned resources", zap.String("instanceID", caaf.instanceID))
|
||||
|
||||
errs := &multierror.Error{}
|
||||
listOpts := metav1.ListOptions{
|
||||
LabelSelector: labels.Set(map[string]string{fv1.EXECUTOR_TYPE: string(fv1.ExecutorTypeContainer)}).AsSelector().String(),
|
||||
}
|
||||
|
||||
err := reaper.CleanupHpa(ctx, caaf.logger, caaf.kubernetesClient, caaf.instanceID, listOpts)
|
||||
if err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
}
|
||||
|
||||
err = reaper.CleanupDeployments(ctx, caaf.logger, caaf.kubernetesClient, caaf.instanceID, listOpts)
|
||||
if err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
}
|
||||
|
||||
err = reaper.CleanupServices(ctx, caaf.logger, caaf.kubernetesClient, caaf.instanceID, listOpts)
|
||||
if err != nil {
|
||||
errs = multierror.Append(errs, err)
|
||||
}
|
||||
|
||||
if errs.ErrorOrNil() != nil {
|
||||
// TODO retry reaper; logged and ignored for now
|
||||
caaf.logger.Error("Failed to cleanup old executor objects", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func (caaf *Container) createFunction(ctx context.Context, fn *fv1.Function) (*fscache.FuncSvc, error) {
|
||||
if fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType != fv1.ExecutorTypeContainer {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
fsvcObj, err := caaf.throttler.RunOnce(string(fn.ObjectMeta.UID), func(ableToCreate bool) (interface{}, error) {
|
||||
if ableToCreate {
|
||||
return caaf.fnCreate(ctx, fn)
|
||||
}
|
||||
return caaf.fsCache.GetByFunctionUID(fn.ObjectMeta.UID)
|
||||
})
|
||||
if err != nil {
|
||||
e := "error creating k8s resources for function"
|
||||
caaf.logger.Error(e,
|
||||
zap.Error(err),
|
||||
zap.String("function_name", fn.ObjectMeta.Name),
|
||||
zap.String("function_namespace", fn.ObjectMeta.Namespace))
|
||||
return nil, errors.Wrapf(err, "%s %s_%s", e, fn.ObjectMeta.Name, fn.ObjectMeta.Namespace)
|
||||
}
|
||||
|
||||
fsvc, ok := fsvcObj.(*fscache.FuncSvc)
|
||||
if !ok {
|
||||
caaf.logger.Panic("receive unknown object while creating function - expected pointer of function service object")
|
||||
}
|
||||
|
||||
return fsvc, err
|
||||
}
|
||||
|
||||
func (caaf *Container) deleteFunction(ctx context.Context, fn *fv1.Function) error {
|
||||
if fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType != fv1.ExecutorTypeContainer {
|
||||
return nil
|
||||
}
|
||||
err := caaf.fnDelete(ctx, fn)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "error deleting kubernetes objects of function %v", fn.ObjectMeta)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (caaf *Container) fnCreate(ctx context.Context, fn *fv1.Function) (*fscache.FuncSvc, error) {
|
||||
cleanupFunc := func(ns string, name string) {
|
||||
err := caaf.cleanupContainer(ctx, ns, name)
|
||||
if err != nil {
|
||||
caaf.logger.Error("received error while cleaning function resources",
|
||||
zap.String("namespace", ns), zap.String("name", name))
|
||||
}
|
||||
}
|
||||
objName := caaf.getObjName(fn)
|
||||
deployLabels := caaf.getDeployLabels(fn.ObjectMeta)
|
||||
deployAnnotations := caaf.getDeployAnnotations(fn.ObjectMeta)
|
||||
|
||||
// to support backward compatibility, if the function was created in default ns, we fall back to creating the
|
||||
// deployment of the function in fission-function ns
|
||||
ns := caaf.namespace
|
||||
if fn.ObjectMeta.Namespace != metav1.NamespaceDefault {
|
||||
ns = fn.ObjectMeta.Namespace
|
||||
}
|
||||
|
||||
// Envoy(istio-proxy) returns 404 directly before istio pilot
|
||||
// propagates latest Envoy-specific configuration.
|
||||
// Since Container waits for pods of deployment to be ready,
|
||||
// change the order of kubeObject creation (create service first,
|
||||
// then deployment) to take advantage of waiting time.
|
||||
svc, err := caaf.createOrGetSvc(ctx, fn, deployLabels, deployAnnotations, objName, ns)
|
||||
if err != nil {
|
||||
caaf.logger.Error("error creating service", zap.Error(err), zap.String("service", objName))
|
||||
go cleanupFunc(ns, objName)
|
||||
return nil, errors.Wrapf(err, "error creating service %v", objName)
|
||||
}
|
||||
svcAddress := fmt.Sprintf("%v.%v", svc.Name, svc.Namespace)
|
||||
|
||||
depl, err := caaf.createOrGetDeployment(ctx, fn, objName, deployLabels, deployAnnotations, ns)
|
||||
if err != nil {
|
||||
caaf.logger.Error("error creating deployment", zap.Error(err), zap.String("deployment", objName))
|
||||
go cleanupFunc(ns, objName)
|
||||
return nil, errors.Wrapf(err, "error creating deployment %v", objName)
|
||||
}
|
||||
|
||||
hpa, err := caaf.createOrGetHpa(ctx, objName, &fn.Spec.InvokeStrategy.ExecutionStrategy, depl, deployLabels, deployAnnotations)
|
||||
if err != nil {
|
||||
caaf.logger.Error("error creating HPA", zap.Error(err), zap.String("hpa", objName))
|
||||
go cleanupFunc(ns, objName)
|
||||
return nil, errors.Wrapf(err, "error creating the HPA %v", objName)
|
||||
}
|
||||
|
||||
kubeObjRefs := []apiv1.ObjectReference{
|
||||
{
|
||||
//obj.TypeMeta.Kind does not work hence this, needs investigation and a fix
|
||||
Kind: "deployment",
|
||||
Name: depl.ObjectMeta.Name,
|
||||
APIVersion: depl.TypeMeta.APIVersion,
|
||||
Namespace: depl.ObjectMeta.Namespace,
|
||||
ResourceVersion: depl.ObjectMeta.ResourceVersion,
|
||||
UID: depl.ObjectMeta.UID,
|
||||
},
|
||||
{
|
||||
Kind: "service",
|
||||
Name: svc.ObjectMeta.Name,
|
||||
APIVersion: svc.TypeMeta.APIVersion,
|
||||
Namespace: svc.ObjectMeta.Namespace,
|
||||
ResourceVersion: svc.ObjectMeta.ResourceVersion,
|
||||
UID: svc.ObjectMeta.UID,
|
||||
},
|
||||
{
|
||||
Kind: "horizontalpodautoscaler",
|
||||
Name: hpa.ObjectMeta.Name,
|
||||
APIVersion: hpa.TypeMeta.APIVersion,
|
||||
Namespace: hpa.ObjectMeta.Namespace,
|
||||
ResourceVersion: hpa.ObjectMeta.ResourceVersion,
|
||||
UID: hpa.ObjectMeta.UID,
|
||||
},
|
||||
}
|
||||
|
||||
fsvc := &fscache.FuncSvc{
|
||||
Name: objName,
|
||||
Function: &fn.ObjectMeta,
|
||||
Address: svcAddress,
|
||||
KubernetesObjects: kubeObjRefs,
|
||||
Executor: fv1.ExecutorTypeContainer,
|
||||
}
|
||||
|
||||
_, err = caaf.fsCache.Add(*fsvc)
|
||||
if err != nil {
|
||||
caaf.logger.Error("error adding function to cache", zap.Error(err), zap.Any("function", fsvc.Function))
|
||||
return fsvc, err
|
||||
}
|
||||
|
||||
caaf.fsCache.IncreaseColdStarts(fn.ObjectMeta.Name, string(fn.ObjectMeta.UID))
|
||||
|
||||
return fsvc, nil
|
||||
}
|
||||
|
||||
func (caaf *Container) updateFunction(ctx context.Context, oldFn *fv1.Function, newFn *fv1.Function) error {
|
||||
|
||||
if oldFn.ObjectMeta.ResourceVersion == newFn.ObjectMeta.ResourceVersion {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ignoring updates to functions which are not of Container type
|
||||
if newFn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType != fv1.ExecutorTypeContainer &&
|
||||
oldFn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType != fv1.ExecutorTypeContainer {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Executor type is no longer Container
|
||||
if newFn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType != fv1.ExecutorTypeContainer &&
|
||||
oldFn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType == fv1.ExecutorTypeContainer {
|
||||
caaf.logger.Info("function does not use new deployment executor anymore, deleting resources",
|
||||
zap.Any("function", newFn))
|
||||
// IMP - pass the oldFn, as the new/modified function is not in cache
|
||||
return caaf.deleteFunction(ctx, oldFn)
|
||||
}
|
||||
|
||||
// Executor type changed to Container from something else
|
||||
if oldFn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType != fv1.ExecutorTypeContainer &&
|
||||
newFn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType == fv1.ExecutorTypeContainer {
|
||||
caaf.logger.Info("function type changed to Container, creating resources",
|
||||
zap.Any("old_function", oldFn.ObjectMeta),
|
||||
zap.Any("new_function", newFn.ObjectMeta))
|
||||
_, err := caaf.createFunction(ctx, newFn)
|
||||
if err != nil {
|
||||
caaf.updateStatus(oldFn, err, "error changing the function's type to Container")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if oldFn.Spec.InvokeStrategy != newFn.Spec.InvokeStrategy {
|
||||
|
||||
// to support backward compatibility, if the function was created in default ns, we fall back to creating the
|
||||
// deployment of the function in fission-function ns, so cleaning up resources there
|
||||
ns := caaf.namespace
|
||||
if newFn.ObjectMeta.Namespace != metav1.NamespaceDefault {
|
||||
ns = newFn.ObjectMeta.Namespace
|
||||
}
|
||||
|
||||
fsvc, err := caaf.fsCache.GetByFunctionUID(newFn.ObjectMeta.UID)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "error updating function due to unable to find function service cache: %v", oldFn)
|
||||
return err
|
||||
}
|
||||
|
||||
hpa, err := caaf.getHpa(ctx, ns, fsvc.Name)
|
||||
if err != nil {
|
||||
caaf.updateStatus(oldFn, err, "error getting HPA while updating function")
|
||||
return err
|
||||
}
|
||||
|
||||
hpaChanged := false
|
||||
|
||||
if newFn.Spec.InvokeStrategy.ExecutionStrategy.MinScale != oldFn.Spec.InvokeStrategy.ExecutionStrategy.MinScale {
|
||||
replicas := int32(newFn.Spec.InvokeStrategy.ExecutionStrategy.MinScale)
|
||||
hpa.Spec.MinReplicas = &replicas
|
||||
hpaChanged = true
|
||||
}
|
||||
|
||||
if newFn.Spec.InvokeStrategy.ExecutionStrategy.MaxScale != oldFn.Spec.InvokeStrategy.ExecutionStrategy.MaxScale {
|
||||
hpa.Spec.MaxReplicas = int32(newFn.Spec.InvokeStrategy.ExecutionStrategy.MaxScale)
|
||||
hpaChanged = true
|
||||
}
|
||||
|
||||
if newFn.Spec.InvokeStrategy.ExecutionStrategy.TargetCPUPercent != oldFn.Spec.InvokeStrategy.ExecutionStrategy.TargetCPUPercent {
|
||||
targetCpupercent := int32(newFn.Spec.InvokeStrategy.ExecutionStrategy.TargetCPUPercent)
|
||||
hpa.Spec.TargetCPUUtilizationPercentage = &targetCpupercent
|
||||
hpaChanged = true
|
||||
}
|
||||
|
||||
if hpaChanged {
|
||||
err := caaf.updateHpa(ctx, hpa)
|
||||
if err != nil {
|
||||
caaf.updateStatus(oldFn, err, "error updating HPA while updating function")
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deployChanged := false
|
||||
|
||||
// If length of slice has changed then no need to check individual elements
|
||||
if len(oldFn.Spec.Secrets) != len(newFn.Spec.Secrets) {
|
||||
deployChanged = true
|
||||
} else {
|
||||
for i, newSecret := range newFn.Spec.Secrets {
|
||||
if newSecret != oldFn.Spec.Secrets[i] {
|
||||
deployChanged = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(oldFn.Spec.ConfigMaps) != len(newFn.Spec.ConfigMaps) {
|
||||
deployChanged = true
|
||||
} else {
|
||||
for i, newConfig := range newFn.Spec.ConfigMaps {
|
||||
if newConfig != oldFn.Spec.ConfigMaps[i] {
|
||||
deployChanged = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(oldFn.Spec.PodSpec, newFn.Spec.PodSpec) {
|
||||
deployChanged = true
|
||||
}
|
||||
|
||||
if deployChanged {
|
||||
return caaf.updateFuncDeployment(ctx, newFn)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (caaf *Container) updateFuncDeployment(ctx context.Context, fn *fv1.Function) error {
|
||||
|
||||
fsvc, err := caaf.fsCache.GetByFunctionUID(fn.ObjectMeta.UID)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "error updating function due to unable to find function service cache: %v", fn)
|
||||
return err
|
||||
}
|
||||
fnObjName := fsvc.Name
|
||||
|
||||
deployLabels := caaf.getDeployLabels(fn.ObjectMeta)
|
||||
caaf.logger.Info("updating deployment due to function update",
|
||||
zap.String("deployment", fnObjName), zap.Any("function", fn.ObjectMeta.Name))
|
||||
|
||||
// to support backward compatibility, if the function was created in default ns, we fall back to creating the
|
||||
// deployment of the function in fission-function ns
|
||||
ns := caaf.namespace
|
||||
if fn.ObjectMeta.Namespace != metav1.NamespaceDefault {
|
||||
ns = fn.ObjectMeta.Namespace
|
||||
}
|
||||
|
||||
existingDepl, err := caaf.kubernetesClient.AppsV1().Deployments(ns).Get(ctx, fnObjName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// the resource version inside function packageRef is changed,
|
||||
// so the content of fetchRequest in deployment cmd is different.
|
||||
// Therefore, the deployment update will trigger a rolling update.
|
||||
newDeployment, err := caaf.getDeploymentSpec(ctx, fn, existingDepl.Spec.Replicas, // use current replicas instead of minscale in the ExecutionStrategy.
|
||||
fnObjName, ns, deployLabels, caaf.getDeployAnnotations(fn.ObjectMeta))
|
||||
if err != nil {
|
||||
caaf.updateStatus(fn, err, "failed to get new deployment spec while updating function")
|
||||
return err
|
||||
}
|
||||
|
||||
err = caaf.updateDeployment(ctx, newDeployment, ns)
|
||||
if err != nil {
|
||||
caaf.updateStatus(fn, err, "failed to update deployment while updating function")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (caaf *Container) fnDelete(ctx context.Context, fn *fv1.Function) error {
|
||||
multierr := &multierror.Error{}
|
||||
|
||||
// GetByFunction uses resource version as part of cache key, however,
|
||||
// the resource version in function metadata will be changed when a function
|
||||
// is deleted and cause Container backend fails to delete the entry.
|
||||
// Use GetByFunctionUID instead of GetByFunction here to find correct
|
||||
// fsvc entry.
|
||||
fsvc, err := caaf.fsCache.GetByFunctionUID(fn.ObjectMeta.UID)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("fsvc not found in cache: %v", fn.ObjectMeta))
|
||||
return err
|
||||
}
|
||||
|
||||
objName := fsvc.Name
|
||||
|
||||
_, err = caaf.fsCache.DeleteOld(fsvc, time.Second*0)
|
||||
if err != nil {
|
||||
multierr = multierror.Append(multierr,
|
||||
errors.Wrapf(err, "error deleting the function from cache"))
|
||||
}
|
||||
|
||||
// to support backward compatibility, if the function was created in default ns, we fall back to creating the
|
||||
// deployment of the function in fission-function ns, so cleaning up resources there
|
||||
ns := caaf.namespace
|
||||
if fn.ObjectMeta.Namespace != metav1.NamespaceDefault {
|
||||
ns = fn.ObjectMeta.Namespace
|
||||
}
|
||||
|
||||
err = caaf.cleanupContainer(ctx, ns, objName)
|
||||
multierr = multierror.Append(multierr, err)
|
||||
|
||||
return multierr.ErrorOrNil()
|
||||
}
|
||||
|
||||
// getObjName returns a unique name for kubernetes objects of function
|
||||
func (caaf *Container) getObjName(fn *fv1.Function) string {
|
||||
// use meta uuid of function, this ensure we always get the same name for the same function.
|
||||
uid := fn.ObjectMeta.UID[len(fn.ObjectMeta.UID)-17:]
|
||||
var functionMetadata string
|
||||
if len(fn.ObjectMeta.Name)+len(fn.ObjectMeta.Namespace) < 35 {
|
||||
functionMetadata = fn.ObjectMeta.Name + "-" + fn.ObjectMeta.Namespace
|
||||
} else {
|
||||
if len(fn.ObjectMeta.Name) > 17 {
|
||||
functionMetadata = fn.ObjectMeta.Name[:17]
|
||||
} else {
|
||||
functionMetadata = fn.ObjectMeta.Name
|
||||
}
|
||||
if len(fn.ObjectMeta.Namespace) > 17 {
|
||||
functionMetadata = functionMetadata + "-" + fn.ObjectMeta.Namespace[:17]
|
||||
} else {
|
||||
functionMetadata = functionMetadata + "-" + fn.ObjectMeta.Namespace
|
||||
}
|
||||
}
|
||||
// contructed name should be 63 characters long, as it is a valid k8s name
|
||||
// functionMetadata should be 35 characters long, as we take 17 characters from functionUid
|
||||
// with newdeploy 10 character prefix
|
||||
return strings.ToLower(fmt.Sprintf("container-%s-%s", functionMetadata, uid))
|
||||
}
|
||||
|
||||
func (caaf *Container) getDeployLabels(fnMeta metav1.ObjectMeta) map[string]string {
|
||||
deployLabels := maps.CopyStringMap(fnMeta.Labels)
|
||||
deployLabels[fv1.EXECUTOR_TYPE] = string(fv1.ExecutorTypeContainer)
|
||||
deployLabels[fv1.FUNCTION_NAME] = fnMeta.Name
|
||||
deployLabels[fv1.FUNCTION_NAMESPACE] = fnMeta.Namespace
|
||||
deployLabels[fv1.FUNCTION_UID] = string(fnMeta.UID)
|
||||
return deployLabels
|
||||
}
|
||||
|
||||
func (caaf *Container) getDeployAnnotations(fnMeta metav1.ObjectMeta) map[string]string {
|
||||
deployAnnotations := maps.CopyStringMap(fnMeta.Annotations)
|
||||
deployAnnotations[fv1.EXECUTOR_INSTANCEID_LABEL] = caaf.instanceID
|
||||
deployAnnotations[fv1.FUNCTION_RESOURCE_VERSION] = fnMeta.ResourceVersion
|
||||
return deployAnnotations
|
||||
}
|
||||
|
||||
// updateStatus is a function which updates status of update.
|
||||
// Current implementation only logs messages, in future it will update function status
|
||||
func (caaf *Container) updateStatus(fn *fv1.Function, err error, message string) {
|
||||
caaf.logger.Error("function status update", zap.Error(err), zap.Any("function", fn), zap.String("message", message))
|
||||
}
|
||||
|
||||
// idleObjectReaper reaps objects after certain idle time
|
||||
func (caaf *Container) idleObjectReaper() {
|
||||
ctx := context.Background()
|
||||
|
||||
pollSleep := 5 * time.Second
|
||||
for {
|
||||
time.Sleep(pollSleep)
|
||||
|
||||
funcSvcs, err := caaf.fsCache.ListOld(pollSleep)
|
||||
if err != nil {
|
||||
caaf.logger.Error("error reaping idle pods", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
for i := range funcSvcs {
|
||||
fsvc := funcSvcs[i]
|
||||
|
||||
if fsvc.Executor != fv1.ExecutorTypeContainer {
|
||||
continue
|
||||
}
|
||||
|
||||
fn, err := caaf.fissionClient.CoreV1().Functions(fsvc.Function.Namespace).Get(ctx, fsvc.Function.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
// CaaF manager handles the function delete event and clean cache/kubeobjs itself,
|
||||
// so we ignore the not found error for functions with CaaF executor type here.
|
||||
if k8sErrs.IsNotFound(err) && fsvc.Executor == fv1.ExecutorTypeContainer {
|
||||
continue
|
||||
}
|
||||
caaf.logger.Error("error getting function", zap.Error(err), zap.String("function", fsvc.Function.Name))
|
||||
continue
|
||||
}
|
||||
|
||||
idlePodReapTime := caaf.defaultIdlePodReapTime
|
||||
if fn.Spec.IdleTimeout != nil {
|
||||
idlePodReapTime = time.Duration(*fn.Spec.IdleTimeout) * time.Second
|
||||
}
|
||||
|
||||
if time.Since(fsvc.Atime) < idlePodReapTime {
|
||||
continue
|
||||
}
|
||||
|
||||
go func() {
|
||||
deployObj := getDeploymentObj(fsvc.KubernetesObjects)
|
||||
if deployObj == nil {
|
||||
caaf.logger.Error("error finding function deployment", zap.Error(err), zap.String("function", fsvc.Function.Name))
|
||||
return
|
||||
}
|
||||
|
||||
currentDeploy, err := caaf.kubernetesClient.AppsV1().
|
||||
Deployments(deployObj.Namespace).Get(ctx, deployObj.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
caaf.logger.Error("error getting function deployment", zap.Error(err), zap.String("function", fsvc.Function.Name))
|
||||
return
|
||||
}
|
||||
|
||||
minScale := int32(fn.Spec.InvokeStrategy.ExecutionStrategy.MinScale)
|
||||
|
||||
// do nothing if the current replicas is already lower than minScale
|
||||
if *currentDeploy.Spec.Replicas <= minScale {
|
||||
return
|
||||
}
|
||||
|
||||
err = caaf.scaleDeployment(ctx, deployObj.Namespace, deployObj.Name, minScale)
|
||||
if err != nil {
|
||||
caaf.logger.Error("error scaling down function deployment", zap.Error(err), zap.String("function", fsvc.Function.Name))
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getDeploymentObj(kubeobjs []apiv1.ObjectReference) *apiv1.ObjectReference {
|
||||
for _, kubeobj := range kubeobjs {
|
||||
switch strings.ToLower(kubeobj.Kind) {
|
||||
case "deployment":
|
||||
return &kubeobj
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
Copyright 2020 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
k8s_err "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/executor/util"
|
||||
otelUtils "github.com/fission/fission/pkg/utils/otel"
|
||||
)
|
||||
|
||||
func (cn *Container) createOrGetDeployment(ctx context.Context, fn *fv1.Function, deployName string, deployLabels map[string]string, deployAnnotations map[string]string, deployNamespace string) (*appsv1.Deployment, error) {
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, cn.logger)
|
||||
|
||||
// The specializationTimeout here refers to the creation of the pod and not the loading of function
|
||||
// as in other executors.
|
||||
specializationTimeout := fn.Spec.InvokeStrategy.ExecutionStrategy.SpecializationTimeout
|
||||
minScale := int32(fn.Spec.InvokeStrategy.ExecutionStrategy.MinScale)
|
||||
|
||||
// Always scale to at least one pod when createOrGetDeployment
|
||||
// is called. The idleObjectReaper will scale-in the deployment
|
||||
// later if no requests to the function.
|
||||
if minScale <= 0 {
|
||||
minScale = 1
|
||||
}
|
||||
|
||||
deployment, err := cn.getDeploymentSpec(ctx, fn, &minScale, deployName, deployNamespace, deployLabels, deployAnnotations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingDepl, err := cn.kubernetesClient.AppsV1().Deployments(deployNamespace).Get(ctx, deployName, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
// Try to adopt orphan deployment created by the old executor.
|
||||
if existingDepl.Annotations[fv1.EXECUTOR_INSTANCEID_LABEL] != cn.instanceID {
|
||||
existingDepl.Annotations = deployment.Annotations
|
||||
existingDepl.Labels = deployment.Labels
|
||||
existingDepl.Spec.Template.Spec.Containers = deployment.Spec.Template.Spec.Containers
|
||||
existingDepl.Spec.Template.Spec.ServiceAccountName = deployment.Spec.Template.Spec.ServiceAccountName
|
||||
existingDepl.Spec.Template.Spec.TerminationGracePeriodSeconds = deployment.Spec.Template.Spec.TerminationGracePeriodSeconds
|
||||
|
||||
// Update with the latest deployment spec. Kubernetes will trigger
|
||||
// rolling update if spec is different from the one in the cluster.
|
||||
existingDepl, err = cn.kubernetesClient.AppsV1().Deployments(deployNamespace).Update(ctx, existingDepl, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
logger.Warn("error adopting cn", zap.Error(err),
|
||||
zap.String("cn", deployName), zap.String("ns", deployNamespace))
|
||||
return nil, err
|
||||
}
|
||||
// In this case, we just return without waiting for it for fast bootstraping.
|
||||
return existingDepl, nil
|
||||
}
|
||||
|
||||
if *existingDepl.Spec.Replicas < minScale {
|
||||
err = cn.scaleDeployment(ctx, existingDepl.Namespace, existingDepl.Name, minScale)
|
||||
if err != nil {
|
||||
logger.Error("error scaling up function deployment", zap.Error(err), zap.String("function", fn.ObjectMeta.Name))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if existingDepl.Status.AvailableReplicas < minScale {
|
||||
existingDepl, err = cn.waitForDeploy(ctx, existingDepl, minScale, specializationTimeout)
|
||||
}
|
||||
|
||||
return existingDepl, err
|
||||
} else if k8s_err.IsNotFound(err) {
|
||||
depl, err := cn.kubernetesClient.AppsV1().Deployments(deployNamespace).Create(ctx, deployment, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
if k8s_err.IsAlreadyExists(err) {
|
||||
depl, err = cn.kubernetesClient.AppsV1().Deployments(deployNamespace).Get(ctx, deployName, metav1.GetOptions{})
|
||||
}
|
||||
if err != nil {
|
||||
logger.Error("error while creating function deployment",
|
||||
zap.Error(err),
|
||||
zap.String("function", fn.ObjectMeta.Name),
|
||||
zap.String("deployment_name", deployName),
|
||||
zap.String("deployment_namespace", deployNamespace))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
otelUtils.SpanTrackEvent(ctx, "deploymentCreated", otelUtils.GetAttributesForDeployment(depl)...)
|
||||
if minScale > 0 {
|
||||
depl, err = cn.waitForDeploy(ctx, depl, minScale, specializationTimeout)
|
||||
}
|
||||
return depl, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (cn *Container) updateDeployment(ctx context.Context, deployment *appsv1.Deployment, ns string) error {
|
||||
_, err := cn.kubernetesClient.AppsV1().Deployments(ns).Update(ctx, deployment, metav1.UpdateOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (cn *Container) deleteDeployment(ctx context.Context, ns string, name string) error {
|
||||
// DeletePropagationBackground deletes the object immediately and dependent are deleted later
|
||||
// DeletePropagationForeground not advisable; it marks for deleteion and API can still serve those objects
|
||||
deletePropagation := metav1.DeletePropagationBackground
|
||||
return cn.kubernetesClient.AppsV1().Deployments(ns).Delete(ctx, name, metav1.DeleteOptions{
|
||||
PropagationPolicy: &deletePropagation,
|
||||
})
|
||||
}
|
||||
|
||||
func (cn *Container) waitForDeploy(ctx context.Context, depl *appsv1.Deployment, replicas int32, specializationTimeout int) (latestDepl *appsv1.Deployment, err error) {
|
||||
oldStatus := depl.Status
|
||||
otelUtils.SpanTrackEvent(ctx, "waitForDeployment", otelUtils.GetAttributesForDeployment(depl)...)
|
||||
// if no specializationTimeout is set, use default value
|
||||
if specializationTimeout < fv1.DefaultSpecializationTimeOut {
|
||||
specializationTimeout = fv1.DefaultSpecializationTimeOut
|
||||
}
|
||||
|
||||
for i := 0; i < specializationTimeout; i++ {
|
||||
latestDepl, err := cn.kubernetesClient.AppsV1().Deployments(depl.ObjectMeta.Namespace).Get(ctx, depl.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO check for imagePullerror
|
||||
// use AvailableReplicas here is better than ReadyReplicas
|
||||
// since the pods may not be able to serve network traffic yet.
|
||||
if latestDepl.Status.AvailableReplicas >= replicas {
|
||||
otelUtils.SpanTrackEvent(ctx, "deploymentAvailable", otelUtils.GetAttributesForDeployment(latestDepl)...)
|
||||
return latestDepl, err
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, cn.logger)
|
||||
logger.Error("Deployment provision failed within timeout window",
|
||||
zap.String("name", latestDepl.Name), zap.Any("old_status", oldStatus),
|
||||
zap.Any("current_status", latestDepl.Status), zap.Int("timeout", specializationTimeout))
|
||||
|
||||
// this error appears in the executor pod logs
|
||||
timeoutError := fmt.Errorf("failed to create deployment within the timeout window of %d seconds", specializationTimeout)
|
||||
return nil, timeoutError
|
||||
}
|
||||
|
||||
func (cn *Container) getDeploymentSpec(ctx context.Context, fn *fv1.Function, targetReplicas *int32,
|
||||
deployName string, deployNamespace string, deployLabels map[string]string, deployAnnotations map[string]string) (*appsv1.Deployment, error) {
|
||||
|
||||
replicas := int32(fn.Spec.InvokeStrategy.ExecutionStrategy.MinScale)
|
||||
if targetReplicas != nil {
|
||||
replicas = *targetReplicas
|
||||
}
|
||||
|
||||
gracePeriodSeconds := int64(6 * 60)
|
||||
|
||||
podAnnotations := make(map[string]string)
|
||||
|
||||
if cn.useIstio {
|
||||
podAnnotations["sidecar.istio.io/inject"] = "false"
|
||||
}
|
||||
|
||||
podLabels := make(map[string]string)
|
||||
|
||||
for k, v := range deployLabels {
|
||||
podLabels[k] = v
|
||||
}
|
||||
|
||||
// Set maxUnavailable and maxSurge to 20% is because we want
|
||||
// fission to rollout newer function version gradually without
|
||||
// affecting any online service. For example, if you set maxSurge
|
||||
// to 100%, the new ReplicaSet scales up immediately and may
|
||||
// consume all remaining compute resources which might be an
|
||||
// issue if a cluster's resource is on a budget.
|
||||
// TODO: add to ExecutionStrategy so that the user
|
||||
// can do more fine control over different functions.
|
||||
maxUnavailable := intstr.FromString("20%")
|
||||
maxSurge := intstr.FromString("20%")
|
||||
|
||||
// Container updates the environment variable "LastUpdateTimestamp" of deployment
|
||||
// whenever a configmap/secret gets an update, but it also leaves multiple ReplicaSets for
|
||||
// rollback purpose. Since fission always update a deployment instead of performing a
|
||||
// rollback, set RevisionHistoryLimit to 0 to disable this feature.
|
||||
revisionHistoryLimit := int32(0)
|
||||
|
||||
resources := cn.getResources(fn)
|
||||
|
||||
// Other executor types rely on Environments to add configmaps and secrets
|
||||
envFromSources, err := util.ConvertConfigSecrets(ctx, fn, cn.kubernetesClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rvCount, err := referencedResourcesRVSum(ctx, cn.kubernetesClient, fn.ObjectMeta.Namespace, fn.Spec.Secrets, fn.Spec.ConfigMaps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if fn.Spec.PodSpec == nil {
|
||||
return nil, fmt.Errorf("podSpec is not set for function %s", fn.ObjectMeta.Name)
|
||||
}
|
||||
|
||||
container := &apiv1.Container{
|
||||
Name: fn.ObjectMeta.Name,
|
||||
ImagePullPolicy: cn.runtimeImagePullPolicy,
|
||||
TerminationMessagePath: "/dev/termination-log",
|
||||
Lifecycle: &apiv1.Lifecycle{
|
||||
PreStop: &apiv1.Handler{
|
||||
Exec: &apiv1.ExecAction{
|
||||
Command: []string{
|
||||
"/bin/sleep",
|
||||
fmt.Sprintf("%v", gracePeriodSeconds),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Env: []apiv1.EnvVar{
|
||||
{
|
||||
Name: fv1.ResourceVersionCount,
|
||||
Value: fmt.Sprintf("%v", rvCount),
|
||||
},
|
||||
},
|
||||
EnvFrom: envFromSources,
|
||||
// https://istio.io/docs/setup/kubernetes/additional-setup/requirements/
|
||||
Resources: resources,
|
||||
}
|
||||
podSpec, err := util.MergePodSpec(&apiv1.PodSpec{
|
||||
Containers: []apiv1.Container{*container},
|
||||
TerminationGracePeriodSeconds: &gracePeriodSeconds,
|
||||
}, fn.Spec.PodSpec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pod := apiv1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: podLabels,
|
||||
Annotations: podAnnotations,
|
||||
},
|
||||
Spec: *podSpec,
|
||||
}
|
||||
|
||||
pod.Spec = *(util.ApplyImagePullSecret("", pod.Spec))
|
||||
|
||||
deployment := &appsv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: deployName,
|
||||
Labels: deployLabels,
|
||||
Annotations: deployAnnotations,
|
||||
},
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: &replicas,
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: deployLabels,
|
||||
},
|
||||
Template: pod,
|
||||
Strategy: appsv1.DeploymentStrategy{
|
||||
Type: appsv1.RollingUpdateDeploymentStrategyType,
|
||||
RollingUpdate: &appsv1.RollingUpdateDeployment{
|
||||
MaxUnavailable: &maxUnavailable,
|
||||
MaxSurge: &maxSurge,
|
||||
},
|
||||
},
|
||||
RevisionHistoryLimit: &revisionHistoryLimit,
|
||||
},
|
||||
}
|
||||
|
||||
return deployment, nil
|
||||
}
|
||||
|
||||
func (caaf *Container) scaleDeployment(ctx context.Context, deplNS string, deplName string, replicas int32) error {
|
||||
caaf.logger.Info("scaling deployment",
|
||||
zap.String("deployment", deplName),
|
||||
zap.String("namespace", deplNS),
|
||||
zap.Int32("replicas", replicas))
|
||||
_, err := caaf.kubernetesClient.AppsV1().Deployments(deplNS).UpdateScale(ctx, deplName, &autoscalingv1.Scale{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: deplName,
|
||||
Namespace: deplNS,
|
||||
},
|
||||
Spec: autoscalingv1.ScaleSpec{
|
||||
Replicas: replicas,
|
||||
},
|
||||
}, metav1.UpdateOptions{})
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright 2020 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
k8sCache "k8s.io/client-go/tools/cache"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
func (caaf *Container) FuncInformerHandler(ctx context.Context) k8sCache.ResourceEventHandlerFuncs {
|
||||
return k8sCache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
fn := obj.(*fv1.Function)
|
||||
fnExecutorType := fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType
|
||||
if fnExecutorType != "" && fnExecutorType != fv1.ExecutorTypeContainer {
|
||||
return
|
||||
}
|
||||
// TODO: A workaround to process items in parallel. We should use workqueue ("k8s.io/client-go/util/workqueue")
|
||||
// and worker pattern to process items instead of moving process to another goroutine.
|
||||
// example: https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/job/job_controller.go
|
||||
go func() {
|
||||
log := caaf.logger.With(zap.String("function_name", fn.ObjectMeta.Name), zap.String("function_namespace", fn.ObjectMeta.Namespace))
|
||||
log.Debug("start function create handler")
|
||||
_, err := caaf.createFunction(ctx, fn)
|
||||
if err != nil {
|
||||
log.Error("error eager creating function", zap.Error(err))
|
||||
}
|
||||
log.Debug("end function create handler")
|
||||
}()
|
||||
},
|
||||
DeleteFunc: func(obj interface{}) {
|
||||
fn := obj.(*fv1.Function)
|
||||
fnExecutorType := fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType
|
||||
if fnExecutorType != "" && fnExecutorType != fv1.ExecutorTypeContainer {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
log := caaf.logger.With(zap.String("function_name", fn.ObjectMeta.Name), zap.String("function_namespace", fn.ObjectMeta.Namespace))
|
||||
log.Debug("start function delete handler")
|
||||
err := caaf.deleteFunction(ctx, fn)
|
||||
if err != nil {
|
||||
log.Error("error deleting function", zap.Error(err))
|
||||
}
|
||||
log.Debug("end function delete handler")
|
||||
}()
|
||||
},
|
||||
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
|
||||
oldFn := oldObj.(*fv1.Function)
|
||||
newFn := newObj.(*fv1.Function)
|
||||
fnExecutorType := oldFn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType
|
||||
if fnExecutorType != "" && fnExecutorType != fv1.ExecutorTypeContainer {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
log := caaf.logger.With(zap.String("function_name", newFn.ObjectMeta.Name),
|
||||
zap.String("function_namespace", newFn.ObjectMeta.Namespace),
|
||||
zap.String("old_function_name", oldFn.ObjectMeta.Name))
|
||||
log.Debug("start function update handler")
|
||||
err := caaf.updateFunction(ctx, oldFn, newFn)
|
||||
if err != nil {
|
||||
log.Error("error updating function",
|
||||
zap.Error(err))
|
||||
}
|
||||
log.Debug("end function update handler")
|
||||
|
||||
}()
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright 2020 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
asv1 "k8s.io/api/autoscaling/v1"
|
||||
k8s_err "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
otelUtils "github.com/fission/fission/pkg/utils/otel"
|
||||
)
|
||||
|
||||
const (
|
||||
DeploymentKind = "Deployment"
|
||||
DeploymentVersion = "apps/v1"
|
||||
)
|
||||
|
||||
func (cn *Container) createOrGetHpa(ctx context.Context, hpaName string, execStrategy *fv1.ExecutionStrategy,
|
||||
depl *appsv1.Deployment, deployLabels map[string]string, deployAnnotations map[string]string) (*asv1.HorizontalPodAutoscaler, error) {
|
||||
|
||||
if depl == nil {
|
||||
return nil, errors.New("failed to create HPA, found empty deployment")
|
||||
}
|
||||
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, cn.logger)
|
||||
minRepl := int32(execStrategy.MinScale)
|
||||
if minRepl == 0 {
|
||||
minRepl = 1
|
||||
}
|
||||
maxRepl := int32(execStrategy.MaxScale)
|
||||
if maxRepl == 0 {
|
||||
maxRepl = minRepl
|
||||
}
|
||||
targetCPU := int32(execStrategy.TargetCPUPercent)
|
||||
|
||||
hpa := &asv1.HorizontalPodAutoscaler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: hpaName,
|
||||
Labels: deployLabels,
|
||||
Annotations: deployAnnotations,
|
||||
},
|
||||
Spec: asv1.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: asv1.CrossVersionObjectReference{
|
||||
Kind: DeploymentKind,
|
||||
Name: depl.ObjectMeta.Name,
|
||||
APIVersion: DeploymentVersion,
|
||||
},
|
||||
MinReplicas: &minRepl,
|
||||
MaxReplicas: maxRepl,
|
||||
TargetCPUUtilizationPercentage: &targetCPU,
|
||||
},
|
||||
}
|
||||
|
||||
existingHpa, err := cn.getHpa(ctx, depl.ObjectMeta.Namespace, hpaName)
|
||||
if err == nil {
|
||||
// to adopt orphan service
|
||||
if existingHpa.Annotations[fv1.EXECUTOR_INSTANCEID_LABEL] != cn.instanceID {
|
||||
existingHpa.Annotations = hpa.Annotations
|
||||
existingHpa.Labels = hpa.Labels
|
||||
existingHpa.Spec = hpa.Spec
|
||||
existingHpa, err = cn.kubernetesClient.AutoscalingV1().HorizontalPodAutoscalers(depl.ObjectMeta.Namespace).Update(ctx, existingHpa, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
logger.Warn("error adopting HPA", zap.Error(err),
|
||||
zap.String("HPA", hpaName), zap.String("ns", depl.ObjectMeta.Namespace))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return existingHpa, err
|
||||
} else if k8s_err.IsNotFound(err) {
|
||||
cHpa, err := cn.kubernetesClient.AutoscalingV1().HorizontalPodAutoscalers(depl.ObjectMeta.Namespace).Create(ctx, hpa, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
if k8s_err.IsAlreadyExists(err) {
|
||||
cHpa, err = cn.getHpa(ctx, depl.ObjectMeta.Namespace, hpaName)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
otelUtils.SpanTrackEvent(ctx, "hpaCreated", otelUtils.GetAttributesForHPA(cHpa)...)
|
||||
return cHpa, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (cn *Container) getHpa(ctx context.Context, ns, name string) (*asv1.HorizontalPodAutoscaler, error) {
|
||||
return cn.kubernetesClient.AutoscalingV1().HorizontalPodAutoscalers(ns).Get(ctx, name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (cn *Container) updateHpa(ctx context.Context, hpa *asv1.HorizontalPodAutoscaler) error {
|
||||
_, err := cn.kubernetesClient.AutoscalingV1().HorizontalPodAutoscalers(hpa.ObjectMeta.Namespace).Update(ctx, hpa, metav1.UpdateOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (cn *Container) deleteHpa(ctx context.Context, ns string, name string) error {
|
||||
return cn.kubernetesClient.AutoscalingV1().HorizontalPodAutoscalers(ns).Delete(ctx, name, metav1.DeleteOptions{})
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright 2020 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/zap"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
k8s_err "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
otelUtils "github.com/fission/fission/pkg/utils/otel"
|
||||
)
|
||||
|
||||
func (cn *Container) getSvPort(fn *fv1.Function) (port int32, err error) {
|
||||
if fn.Spec.PodSpec == nil {
|
||||
return port, fmt.Errorf("podspec is empty for function %s", fn.ObjectMeta.Name)
|
||||
}
|
||||
if len(fn.Spec.PodSpec.Containers) != 1 {
|
||||
return port, fmt.Errorf("podspec should have exactly one container %s", fn.ObjectMeta.Name)
|
||||
}
|
||||
if len(fn.Spec.PodSpec.Containers[0].Ports) != 1 {
|
||||
return port, fmt.Errorf("container should have exactly one port %s", fn.ObjectMeta.Name)
|
||||
}
|
||||
return fn.Spec.PodSpec.Containers[0].Ports[0].ContainerPort, nil
|
||||
}
|
||||
|
||||
func (cn *Container) createOrGetSvc(ctx context.Context, fn *fv1.Function, deployLabels map[string]string, deployAnnotations map[string]string, svcName string, svcNamespace string) (*apiv1.Service, error) {
|
||||
targetPort, err := cn.getSvPort(fn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, cn.logger)
|
||||
service := &apiv1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: svcName,
|
||||
Labels: deployLabels,
|
||||
Annotations: deployAnnotations,
|
||||
},
|
||||
Spec: apiv1.ServiceSpec{
|
||||
Ports: []apiv1.ServicePort{
|
||||
{
|
||||
Name: "http-env",
|
||||
Port: int32(80),
|
||||
TargetPort: intstr.FromInt(int(targetPort)),
|
||||
},
|
||||
},
|
||||
Selector: deployLabels,
|
||||
Type: apiv1.ServiceTypeClusterIP,
|
||||
},
|
||||
}
|
||||
|
||||
existingSvc, err := cn.kubernetesClient.CoreV1().Services(svcNamespace).Get(ctx, svcName, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
// to adopt orphan service
|
||||
if existingSvc.Annotations[fv1.EXECUTOR_INSTANCEID_LABEL] != cn.instanceID {
|
||||
existingSvc.Annotations = service.Annotations
|
||||
existingSvc.Labels = service.Labels
|
||||
existingSvc.Spec.Ports = service.Spec.Ports
|
||||
existingSvc.Spec.Selector = service.Spec.Selector
|
||||
existingSvc.Spec.Type = service.Spec.Type
|
||||
existingSvc, err = cn.kubernetesClient.CoreV1().Services(svcNamespace).Update(ctx, existingSvc, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
logger.Warn("error adopting service", zap.Error(err),
|
||||
zap.String("service", svcName), zap.String("ns", svcNamespace))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return existingSvc, err
|
||||
} else if k8s_err.IsNotFound(err) {
|
||||
svc, err := cn.kubernetesClient.CoreV1().Services(svcNamespace).Create(ctx, service, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
if k8s_err.IsAlreadyExists(err) {
|
||||
svc, err = cn.kubernetesClient.CoreV1().Services(svcNamespace).Get(ctx, svcName, metav1.GetOptions{})
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
otelUtils.SpanTrackEvent(ctx, "svcCreated", otelUtils.GetAttributesForSvc(svc)...)
|
||||
return svc, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (cn *Container) deleteSvc(ctx context.Context, ns string, name string) error {
|
||||
return cn.kubernetesClient.CoreV1().Services(ns).Delete(ctx, name, metav1.DeleteOptions{})
|
||||
}
|
||||
@@ -30,37 +30,37 @@ type ExecutorType interface {
|
||||
Run(context.Context)
|
||||
|
||||
// GetTypeName returns the name of executor type
|
||||
GetTypeName() fv1.ExecutorType
|
||||
GetTypeName(context.Context) fv1.ExecutorType
|
||||
|
||||
// GetFuncSvc specializes function pod(s) and returns a service URL for the function.
|
||||
GetFuncSvc(context.Context, *fv1.Function) (*fscache.FuncSvc, error)
|
||||
|
||||
// GetFuncSvcFromCache retrieves function service from cache.
|
||||
GetFuncSvcFromCache(*fv1.Function) (*fscache.FuncSvc, error)
|
||||
GetFuncSvcFromCache(context.Context, *fv1.Function) (*fscache.FuncSvc, error)
|
||||
|
||||
// GetFuncSvcFromPoolCache retrieves function service and number of active instances after filtering on requestsPerPod and CPULimit
|
||||
GetFuncSvcFromPoolCache(fn *fv1.Function, requestsPerPod int) (*fscache.FuncSvc, int, error)
|
||||
GetFuncSvcFromPoolCache(ctx context.Context, fn *fv1.Function, requestsPerPod int) (*fscache.FuncSvc, int, error)
|
||||
|
||||
// DeleteFuncSvcFromCache deletes function service entry in cache.
|
||||
DeleteFuncSvcFromCache(*fscache.FuncSvc)
|
||||
DeleteFuncSvcFromCache(context.Context, *fscache.FuncSvc)
|
||||
|
||||
// TapService updates the access time of function service entry to
|
||||
// avoid idle pod reaper recycles pods.
|
||||
TapService(serviceUrl string) error
|
||||
TapService(ctx context.Context, serviceUrl string) error
|
||||
|
||||
// UnTapService updates the isActive to false
|
||||
UnTapService(key string, svcHost string)
|
||||
UnTapService(ctx context.Context, key string, svcHost string)
|
||||
|
||||
// IsValid returns true if a function service is valid. Different executor types
|
||||
// use distinct ways to examine the function service.
|
||||
IsValid(*fscache.FuncSvc) bool
|
||||
IsValid(context.Context, *fscache.FuncSvc) bool
|
||||
|
||||
// RefreshFuncPods refreshes function pods if the secrets/configmaps pods reference to get updated.
|
||||
RefreshFuncPods(*zap.Logger, fv1.Function) error
|
||||
RefreshFuncPods(context.Context, *zap.Logger, fv1.Function) error
|
||||
|
||||
// AdoptOrphanResources adopts existing resources created by the deleted executor.
|
||||
AdoptExistingResources()
|
||||
AdoptExistingResources(context.Context)
|
||||
|
||||
// CleanupOldExecutorObjects cleans up resources created by old executor instances
|
||||
CleanupOldExecutorObjects()
|
||||
CleanupOldExecutorObjects(context.Context)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2021 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package newdeploy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8sCache "k8s.io/client-go/tools/cache"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
func (deploy *NewDeploy) EnvEventHandlers() k8sCache.ResourceEventHandlerFuncs {
|
||||
return k8sCache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {},
|
||||
DeleteFunc: func(obj interface{}) {},
|
||||
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
|
||||
newEnv := newObj.(*fv1.Environment)
|
||||
oldEnv := oldObj.(*fv1.Environment)
|
||||
ctx := context.Background()
|
||||
// Currently only an image update in environment calls for function's deployment recreation. In future there might be more attributes which would want to do it
|
||||
if oldEnv.Spec.Runtime.Image != newEnv.Spec.Runtime.Image {
|
||||
deploy.logger.Debug("Updating all function of the environment that changed, old env:", zap.Any("environment", oldEnv))
|
||||
funcs := deploy.getEnvFunctions(ctx, &newEnv.ObjectMeta)
|
||||
for _, f := range funcs {
|
||||
function, err := deploy.fissionClient.CoreV1().Functions(f.ObjectMeta.Namespace).Get(ctx, f.ObjectMeta.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
deploy.logger.Error("Error getting function", zap.Error(err), zap.Any("function", function))
|
||||
continue
|
||||
}
|
||||
err = deploy.updateFuncDeployment(ctx, function, newEnv)
|
||||
if err != nil {
|
||||
deploy.logger.Error("Error updating function", zap.Error(err), zap.Any("function", function))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user