Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f955d1182a | ||
|
|
1cbc0ba9ff | ||
|
|
0936c6a2d7 | ||
|
|
f0ec328d24 | ||
|
|
2b1ac28300 | ||
|
|
0fb2096788 | ||
|
|
6e375629e7 | ||
|
|
1133386ce9 | ||
|
|
f99f10134c | ||
|
|
6c431e4d9b | ||
|
|
31c81e132e | ||
|
|
a5f3402dbc | ||
|
|
784bd82ec7 | ||
|
|
cd742a6d18 | ||
|
|
32530ac474 | ||
|
|
117c383fac |
@@ -92,7 +92,7 @@ jobs:
|
||||
helm repo update
|
||||
kubectl create ns monitoring
|
||||
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring \
|
||||
--set grafana.enabled=false --set alertmanager.enabled=false
|
||||
--version 45.28.0 --set grafana.enabled=false --set alertmanager.enabled=false
|
||||
|
||||
- name: Build and Install Fission CLI
|
||||
run: |
|
||||
@@ -234,7 +234,7 @@ jobs:
|
||||
helm repo update
|
||||
kubectl create ns monitoring
|
||||
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring \
|
||||
--set grafana.enabled=false --set alertmanager.enabled=false
|
||||
--version 45.28.0 --set grafana.enabled=false --set alertmanager.enabled=false
|
||||
|
||||
- name: Build and Install Fission CLI
|
||||
run: |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
apiVersion: v2
|
||||
name: fission-all
|
||||
version: v1.19.0-rc1
|
||||
appVersion: v1.19.0-rc1
|
||||
version: v1.19.0
|
||||
appVersion: v1.19.0
|
||||
description: Fission is a fast serverless framework for Kubernetes.
|
||||
home: https://fission.io/
|
||||
icon: https://fission.io/images/fission-logo-white.svg
|
||||
|
||||
@@ -12,7 +12,7 @@ metadata:
|
||||
application: fission-router
|
||||
spec:
|
||||
{{- if not .Values.router.deployAsDaemonSet }}
|
||||
replicas: 1
|
||||
replicas: {{ .Values.router.replicas | default 1 }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
|
||||
@@ -25,7 +25,7 @@ image: fission/fission-bundle
|
||||
## It is also used by the chart to identify version of the few more images apart from fission-bundle.
|
||||
## Keep it empty for using latest tag.
|
||||
##
|
||||
imageTag: v1.19.0-rc1
|
||||
imageTag: v1.19.0
|
||||
|
||||
## pullPolicy represents the pull policy to use for images in the chart.
|
||||
##
|
||||
@@ -103,7 +103,7 @@ fetcher:
|
||||
## image represents the image of the fetcher component.
|
||||
image: fission/fetcher
|
||||
## imageTag represents the tag of the image of the fetcher component.
|
||||
imageTag: v1.19.0-rc1
|
||||
imageTag: v1.19.0
|
||||
|
||||
## Fetcher is only for to downloading or uploading archive.
|
||||
## Normally, you don't need to change the value here, unless necessary.
|
||||
@@ -211,6 +211,9 @@ router:
|
||||
## deployAsDaemonSet decides whether to deploy router as a DaemonSet or a Deployment.
|
||||
##
|
||||
deployAsDaemonSet: false
|
||||
## replicas decides how many router pods to deploy. Only used when deployAsDaemonSet is false.
|
||||
##
|
||||
replicas: 1
|
||||
## svcAddressMaxRetries is the max times for router to retry with a specific function service address
|
||||
##
|
||||
svcAddressMaxRetries: 5
|
||||
@@ -685,7 +688,7 @@ preUpgradeChecks:
|
||||
image: fission/pre-upgrade-checks
|
||||
## pre-install/pre-upgrade checks image version
|
||||
##
|
||||
imageTag: v1.19.0-rc1
|
||||
imageTag: v1.19.0
|
||||
|
||||
## Fission post-install/post-upgrade reporting live in this image
|
||||
##
|
||||
@@ -817,7 +820,7 @@ mqt_keda:
|
||||
connector_images:
|
||||
kafka:
|
||||
image: fission/keda-kafka-http-connector
|
||||
tag: v0.11
|
||||
tag: v0.12
|
||||
rabbitmq:
|
||||
image: fission/keda-rabbitmq-http-connector
|
||||
tag: v0.10
|
||||
@@ -826,16 +829,16 @@ mqt_keda:
|
||||
tag: v0.10
|
||||
aws_sqs:
|
||||
image: fission/keda-aws-sqs-http-connector
|
||||
tag: v0.10
|
||||
tag: v0.11
|
||||
nats_steaming:
|
||||
image: fission/keda-nats-streaming-http-connector
|
||||
tag: v0.12
|
||||
tag: v0.13
|
||||
nats_jetstream:
|
||||
image: fission/keda-nats-jetstream-http-connector
|
||||
tag: v0.2
|
||||
tag: v0.4
|
||||
gcp_pubsub:
|
||||
image: fission/keda-gcp-pubsub-http-connector
|
||||
tag: v0.5
|
||||
tag: v0.6
|
||||
redis:
|
||||
image: fission/keda-redis-http-connector
|
||||
tag: v0.3
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.17
|
||||
FROM alpine:3.18
|
||||
RUN apk add --update ca-certificates
|
||||
COPY builder /builder
|
||||
ENTRYPOINT ["/builder"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.17
|
||||
FROM alpine:3.18
|
||||
RUN apk add --update ca-certificates
|
||||
COPY fetcher /
|
||||
ENTRYPOINT ["/fetcher"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.17
|
||||
FROM alpine:3.18
|
||||
RUN apk add --update ca-certificates
|
||||
COPY fission-bundle /
|
||||
ENTRYPOINT ["/fission-bundle"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.17
|
||||
FROM alpine:3.18
|
||||
RUN apk add --update ca-certificates
|
||||
COPY pre-upgrade-checks /
|
||||
ENTRYPOINT ["/pre-upgrade-checks"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.17
|
||||
FROM alpine:3.18
|
||||
RUN apk add --update ca-certificates
|
||||
COPY reporter /
|
||||
ENTRYPOINT ["/reporter"]
|
||||
@@ -7,45 +7,45 @@ require (
|
||||
github.com/bep/debounce v1.2.1
|
||||
github.com/dchest/uniuri v1.2.0
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/elastic/crd-ref-docs v0.0.8
|
||||
github.com/emicklei/go-restful-openapi/v2 v2.9.1
|
||||
github.com/emicklei/go-restful/v3 v3.10.1
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/emicklei/go-restful/v3 v3.10.2
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/go-git/go-git/v5 v5.4.2
|
||||
github.com/go-openapi/spec v0.20.7
|
||||
github.com/golang-jwt/jwt/v4 v4.4.3
|
||||
github.com/go-git/go-git/v5 v5.6.1
|
||||
github.com/go-openapi/spec v0.20.9
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/graymeta/stow v0.2.8
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hashicorp/go-retryablehttp v0.7.1
|
||||
github.com/imdario/mergo v0.3.13
|
||||
github.com/influxdata/influxdb v1.11.0
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2
|
||||
github.com/imdario/mergo v0.3.15
|
||||
github.com/influxdata/influxdb v1.11.1
|
||||
github.com/mholt/archiver/v3 v3.5.1
|
||||
github.com/minio/minio-go v6.0.14+incompatible
|
||||
github.com/ory/dockertest v3.3.5+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.14.0
|
||||
github.com/prometheus/common v0.37.0
|
||||
github.com/robfig/cron/v3 v3.0.0
|
||||
github.com/prometheus/client_golang v1.15.1
|
||||
github.com/prometheus/common v0.43.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
|
||||
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/wcharczuk/go-chart v2.0.1+incompatible
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0
|
||||
go.opentelemetry.io/contrib/propagators/autoprop v0.37.0
|
||||
go.opentelemetry.io/otel v1.11.2
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.2
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.2
|
||||
go.opentelemetry.io/otel/sdk v1.11.2
|
||||
go.opentelemetry.io/otel/trace v1.11.2
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.41.1
|
||||
go.opentelemetry.io/contrib/propagators/autoprop v0.41.1
|
||||
go.opentelemetry.io/otel v1.15.1
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.1
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.1
|
||||
go.opentelemetry.io/otel/sdk v1.15.1
|
||||
go.opentelemetry.io/otel/trace v1.15.1
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/net v0.7.0
|
||||
google.golang.org/grpc v1.51.0
|
||||
golang.org/x/net v0.10.0
|
||||
google.golang.org/grpc v1.55.0
|
||||
k8s.io/api v0.25.4
|
||||
k8s.io/apiextensions-apiserver v0.25.4
|
||||
k8s.io/apimachinery v0.25.4
|
||||
@@ -57,7 +57,8 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.99.0 // indirect
|
||||
cloud.google.com/go/compute v1.18.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.27 // indirect
|
||||
@@ -70,15 +71,15 @@ require (
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.4 // indirect
|
||||
github.com/andybalholm/brotli v1.0.1 // indirect
|
||||
github.com/aws/aws-sdk-go v1.42.34 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blend/go-sdk v1.20220112.5 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cloudflare/circl v1.1.0 // indirect
|
||||
github.com/containerd/continuity v0.2.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
@@ -94,20 +95,20 @@ require (
|
||||
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.3.1 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.4.1 // indirect
|
||||
github.com/go-ini/ini v1.66.4 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-logr/zapr v1.2.3 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/gobuffalo/flect v0.2.5 // indirect
|
||||
github.com/goccy/go-yaml v1.1.5 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.1 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/gobuffalo/flect v0.3.0 // indirect
|
||||
github.com/goccy/go-yaml v1.11.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||
github.com/google/gofuzz v1.1.0 // indirect
|
||||
@@ -115,10 +116,10 @@ require (
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/huandu/xstrings v1.2.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/huandu/xstrings v1.3.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
||||
@@ -132,13 +133,13 @@ require (
|
||||
github.com/klauspost/compress v1.15.11 // indirect
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/lib/pq v1.10.4 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/mitchellh/copystructure v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
@@ -148,49 +149,50 @@ require (
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.1.5 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/skeema/knownhosts v1.1.0 // indirect
|
||||
github.com/ulikunitz/xz v0.5.9 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.2 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/aws v1.12.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.12.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.12.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/ot v1.12.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2 // indirect
|
||||
go.opentelemetry.io/otel/metric v0.34.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/aws v1.16.1 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.16.1 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.16.1 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/ot v1.16.1 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.1 // indirect
|
||||
go.opentelemetry.io/otel/metric v0.38.1 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
golang.org/x/crypto v0.3.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.7.0 // indirect
|
||||
golang.org/x/image v0.5.0 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/term v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
golang.org/x/oauth2 v0.7.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/term v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
|
||||
golang.org/x/tools v0.8.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
k8s.io/component-base v0.25.4 // indirect
|
||||
k8s.io/klog/v2 v2.70.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
k8s.io/klog/v2 v2.90.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a // indirect
|
||||
k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
)
|
||||
|
||||
@@ -44,6 +44,7 @@ type (
|
||||
|
||||
func MakeClient(logger *zap.Logger, builderUrl string) *Client {
|
||||
hc := retryablehttp.NewClient()
|
||||
hc.ErrorHandler = retryablehttp.PassthroughErrorHandler
|
||||
hc.HTTPClient.Transport = otelhttp.NewTransport(hc.HTTPClient.Transport)
|
||||
return &Client{
|
||||
logger: logger.Named("builder_client"),
|
||||
@@ -62,7 +63,7 @@ func (c *Client) Build(ctx context.Context, req *builder.PackageBuildRequest) (*
|
||||
|
||||
resp, err := ctxhttp.Post(ctx, c.httpClient.StandardClient(), c.url, "application/json", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return nil, ferror.MakeErrorFromHTTP(resp)
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
|
||||
@@ -31,8 +31,10 @@ import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
"github.com/fission/fission/pkg/executor/client"
|
||||
"github.com/fission/fission/pkg/executor/fscache"
|
||||
"github.com/fission/fission/pkg/utils/httpserver"
|
||||
"github.com/fission/fission/pkg/utils/metrics"
|
||||
otelUtils "github.com/fission/fission/pkg/utils/otel"
|
||||
@@ -148,7 +150,24 @@ func (executor *Executor) getServiceForFunction(ctx context.Context, fn *fv1.Fun
|
||||
respChan: respChan,
|
||||
}
|
||||
resp := <-respChan
|
||||
cleanUp := func(funcSvc *fscache.FuncSvc) {
|
||||
et, ok := executor.executorTypes[fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType]
|
||||
if !ok {
|
||||
executor.logger.Error("unknown executor type received in function service", zap.Any("executor", funcSvc.Executor))
|
||||
return
|
||||
}
|
||||
if funcSvc != nil {
|
||||
et.UnTapService(ctx, crd.CacheKey(funcSvc.Function), resp.funcSvc.Address)
|
||||
} else {
|
||||
et.MarkSpecializationFailure(ctx, crd.CacheKey(&fn.ObjectMeta))
|
||||
}
|
||||
}
|
||||
if errors.Is(ctx.Err(), context.Canceled) {
|
||||
cleanUp(resp.funcSvc)
|
||||
return "", ferror.MakeError(499, "client leave early in the process of getServiceForFunction")
|
||||
}
|
||||
if resp.err != nil {
|
||||
cleanUp(resp.funcSvc)
|
||||
return "", resp.err
|
||||
}
|
||||
return resp.funcSvc.Address, resp.err
|
||||
@@ -244,6 +263,19 @@ func (executor *Executor) unTapService(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// dumpDebugInfo => dump function service for pool cache
|
||||
func (executor *Executor) dumpDebugInfo(w http.ResponseWriter, r *http.Request) {
|
||||
// currently we are considering dumping function only for pool manager
|
||||
et := executor.executorTypes[fv1.ExecutorTypePoolmgr]
|
||||
if err := et.DumpDebugInfo(r.Context()); err != nil {
|
||||
code, msg := ferror.GetHTTPError(err)
|
||||
http.Error(w, msg, code)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// GetHandler returns an http.Handler.
|
||||
func (executor *Executor) GetHandler() http.Handler {
|
||||
r := mux.NewRouter()
|
||||
@@ -253,6 +285,7 @@ func (executor *Executor) GetHandler() http.Handler {
|
||||
r.HandleFunc("/v2/tapServices", executor.tapServices).Methods("POST")
|
||||
r.HandleFunc("/healthz", executor.healthHandler).Methods("GET")
|
||||
r.HandleFunc("/v2/unTapService", executor.unTapService).Methods("POST")
|
||||
r.HandleFunc("/v2/debugInfo", executor.dumpDebugInfo).Methods("GET")
|
||||
return r
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,11 @@ func (caaf *Container) UnTapService(ctx context.Context, key string, svcHost str
|
||||
// Not Implemented for CaaF.
|
||||
}
|
||||
|
||||
// MarkSpecializationFailure has not been implemented for CaaF.
|
||||
func (caaf *Container) MarkSpecializationFailure(ctx context.Context, key 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)
|
||||
@@ -457,7 +462,7 @@ func (caaf *Container) fnCreate(ctx context.Context, fn *fv1.Function) (*fscache
|
||||
_, err = caaf.fsCache.Add(*fsvc)
|
||||
if err != nil {
|
||||
caaf.logger.Error("error adding function to cache", zap.Error(err), zap.Any("function", fsvc.Function))
|
||||
metrics.FuncError.WithLabelValues(fn.ObjectMeta.Name, fn.ObjectMeta.Namespace).Inc()
|
||||
metrics.ColdStartsError.WithLabelValues(fn.ObjectMeta.Name, fn.ObjectMeta.Namespace).Inc()
|
||||
return fsvc, err
|
||||
}
|
||||
|
||||
@@ -782,3 +787,7 @@ func getDeploymentObj(kubeobjs []apiv1.ObjectReference) *apiv1.ObjectReference {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (caaf *Container) DumpDebugInfo(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ type ExecutorType interface {
|
||||
// GetFuncSvcFromCache retrieves function service from cache.
|
||||
GetFuncSvcFromCache(context.Context, *fv1.Function) (*fscache.FuncSvc, error)
|
||||
|
||||
// DumpDebugInfo dump function service cache to temporary directory of executor pod.
|
||||
DumpDebugInfo(context.Context) error
|
||||
|
||||
// DeleteFuncSvcFromCache deletes function service entry in cache.
|
||||
DeleteFuncSvcFromCache(context.Context, *fscache.FuncSvc)
|
||||
|
||||
@@ -48,6 +51,9 @@ type ExecutorType interface {
|
||||
// UnTapService updates the isActive to false
|
||||
UnTapService(ctx context.Context, key string, svcHost string)
|
||||
|
||||
// ReduceSpecializationInProgress updates the svcWaiting count in funcSvcGroup
|
||||
MarkSpecializationFailure(ctx context.Context, key string)
|
||||
|
||||
// IsValid returns true if a function service is valid. Different executor types
|
||||
// use distinct ways to examine the function service.
|
||||
IsValid(context.Context, *fscache.FuncSvc) bool
|
||||
|
||||
@@ -199,6 +199,11 @@ func (deploy *NewDeploy) UnTapService(ctx context.Context, key string, svcHost s
|
||||
// Not Implemented for NewDeployment. Will be used when support of concurrent specialization of same function is added.
|
||||
}
|
||||
|
||||
// MarkSpecializationFailure has not been implemented for NewDeployment.
|
||||
func (deploy *NewDeploy) MarkSpecializationFailure(ctx context.Context, key string) {
|
||||
// Not Implemented for NewDeployment. Will be used when support of concurrent specialization of same function is added.
|
||||
}
|
||||
|
||||
// TapService makes a TouchByAddress request to the cache.
|
||||
func (deploy *NewDeploy) TapService(ctx context.Context, svcHost string) error {
|
||||
otelUtils.SpanTrackEvent(ctx, "TapService")
|
||||
@@ -500,7 +505,7 @@ func (deploy *NewDeploy) fnCreate(ctx context.Context, fn *fv1.Function) (*fscac
|
||||
_, err = deploy.fsCache.Add(*fsvc)
|
||||
if err != nil {
|
||||
deploy.logger.Error("error adding function to cache", zap.Error(err), zap.Any("function", fsvc.Function))
|
||||
metrics.FuncError.WithLabelValues(fn.ObjectMeta.Name, fn.ObjectMeta.Namespace).Inc()
|
||||
metrics.ColdStartsError.WithLabelValues(fn.ObjectMeta.Name, fn.ObjectMeta.Namespace).Inc()
|
||||
return fsvc, err
|
||||
}
|
||||
|
||||
@@ -884,3 +889,7 @@ func (deploy *NewDeploy) scaleDeployment(ctx context.Context, deplNS string, dep
|
||||
}, metav1.UpdateOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (deploy *NewDeploy) DumpDebugInfo(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ func TestRefreshFuncPods(t *testing.T) {
|
||||
|
||||
nsResolver := utils.NamespaceResolver{
|
||||
FunctionNamespace: functionNamespace,
|
||||
BuiderNamespace: builderNamespace,
|
||||
BuilderNamespace: builderNamespace,
|
||||
DefaultNamespace: defaultNamespace,
|
||||
}
|
||||
ndm.nsResolver = &nsResolver
|
||||
|
||||
@@ -47,7 +47,6 @@ import (
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
"github.com/fission/fission/pkg/executor/fscache"
|
||||
"github.com/fission/fission/pkg/executor/metrics"
|
||||
fetcherClient "github.com/fission/fission/pkg/fetcher/client"
|
||||
fetcherConfig "github.com/fission/fission/pkg/fetcher/config"
|
||||
"github.com/fission/fission/pkg/generated/clientset/versioned"
|
||||
@@ -227,6 +226,14 @@ func (gp *GenericPool) updateCPUUtilizationSvc(ctx context.Context) {
|
||||
// returns the key and pod API object.
|
||||
func (gp *GenericPool) choosePod(ctx context.Context, newLabels map[string]string) (string, *apiv1.Pod, error) {
|
||||
startTime := time.Now()
|
||||
podTimeout := startTime.Add(gp.podReadyTimeout)
|
||||
deadline, ok := ctx.Deadline()
|
||||
if ok {
|
||||
deadline = deadline.Add(-1 * time.Second)
|
||||
if deadline.Before(podTimeout) {
|
||||
podTimeout = deadline
|
||||
}
|
||||
}
|
||||
expoDelay := 100 * time.Millisecond
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, gp.logger)
|
||||
if !cache.WaitForCacheSync(ctx.Done(), gp.readyPodListerSynced) {
|
||||
@@ -235,10 +242,14 @@ func (gp *GenericPool) choosePod(ctx context.Context, newLabels map[string]strin
|
||||
}
|
||||
for {
|
||||
// Retries took too long, error out.
|
||||
if time.Since(startTime) > gp.podReadyTimeout {
|
||||
logger.Error("timed out waiting for pod", zap.Any("labels", newLabels), zap.Duration("timeout", gp.podReadyTimeout))
|
||||
if time.Now().After(podTimeout) {
|
||||
logger.Error("timed out waiting for pod", zap.Any("labels", newLabels), zap.Duration("timeout", podTimeout.Sub(startTime)))
|
||||
return "", nil, errors.New("timeout: waited too long to get a ready pod")
|
||||
}
|
||||
if ctx.Err() != nil {
|
||||
logger.Error("context canceled while waiting for pod", zap.Any("labels", newLabels), zap.Duration("timeout", podTimeout.Sub(startTime)))
|
||||
return "", nil, fmt.Errorf("context canceled while waiting for pod: %w", ctx.Err())
|
||||
}
|
||||
|
||||
var chosenPod *apiv1.Pod
|
||||
var key string
|
||||
@@ -517,7 +528,7 @@ func (gp *GenericPool) getFuncSvc(ctx context.Context, fn *fv1.Function) (*fscac
|
||||
// Remove old versions function pods
|
||||
for _, pod := range podList.Items {
|
||||
// Delete pod no matter what status it is
|
||||
gp.kubernetesClient.CoreV1().Pods(gp.fnNamespace).Delete(ctx, pod.ObjectMeta.Name, metav1.DeleteOptions{}) //nolint errcheck
|
||||
gp.kubernetesClient.CoreV1().Pods(gp.fnNamespace).Delete(ctx, pod.ObjectMeta.Name, metav1.DeleteOptions{}) // nolint errcheck
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,7 +624,6 @@ func (gp *GenericPool) getFuncSvc(ctx context.Context, fn *fv1.Function) (*fscac
|
||||
gp.fsCache.PodToFsvc.Store(pod.GetObjectMeta().GetName(), fsvc)
|
||||
gp.podFSVCMap.Store(pod.ObjectMeta.Name, []interface{}{crd.CacheKey(fsvc.Function), fsvc.Address})
|
||||
gp.fsCache.AddFunc(ctx, *fsvc, fn.GetRequestPerPod())
|
||||
metrics.ColdStarts.WithLabelValues(fn.ObjectMeta.Name, fn.ObjectMeta.Namespace).Inc()
|
||||
|
||||
logger.Info("added function service",
|
||||
zap.String("pod", pod.ObjectMeta.Name),
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fission/fission/pkg/executor/metrics"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.uber.org/zap"
|
||||
@@ -186,7 +187,16 @@ func (gpm *GenericPoolManager) GetTypeName(ctx context.Context) fv1.ExecutorType
|
||||
return fv1.ExecutorTypePoolmgr
|
||||
}
|
||||
|
||||
func (gpm *GenericPoolManager) GetFuncSvc(ctx context.Context, fn *fv1.Function) (*fscache.FuncSvc, error) {
|
||||
func (gpm *GenericPoolManager) GetFuncSvc(ctx context.Context, fn *fv1.Function) (fnSvc *fscache.FuncSvc, fErr error) {
|
||||
defer func() {
|
||||
if fErr != nil {
|
||||
metrics.ColdStartsError.WithLabelValues(fn.ObjectMeta.Name, fn.ObjectMeta.Namespace).Inc()
|
||||
return
|
||||
}
|
||||
|
||||
metrics.ColdStarts.WithLabelValues(fn.ObjectMeta.Name, fn.ObjectMeta.Namespace).Inc()
|
||||
}()
|
||||
|
||||
otelUtils.SpanTrackEvent(ctx, "GetFuncSvc", otelUtils.GetAttributesForFunction(fn)...)
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, gpm.logger)
|
||||
|
||||
@@ -194,12 +204,14 @@ func (gpm *GenericPoolManager) GetFuncSvc(ctx context.Context, fn *fv1.Function)
|
||||
logger.Debug("getting environment for function", zap.String("function", fn.ObjectMeta.Name))
|
||||
env, err := gpm.getFunctionEnv(ctx, fn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
fErr = err
|
||||
return
|
||||
}
|
||||
|
||||
pool, created, err := gpm.getPool(ctx, env)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
fErr = err
|
||||
return
|
||||
}
|
||||
|
||||
if created {
|
||||
@@ -209,7 +221,8 @@ func (gpm *GenericPoolManager) GetFuncSvc(ctx context.Context, fn *fv1.Function)
|
||||
// from GenericPool -> get one function container
|
||||
// (this also adds to the cache)
|
||||
logger.Debug("getting function service from pool", zap.String("function", fn.ObjectMeta.Name))
|
||||
return pool.getFuncSvc(ctx, fn)
|
||||
fnSvc, fErr = pool.getFuncSvc(ctx, fn)
|
||||
return fnSvc, fErr
|
||||
}
|
||||
|
||||
func (gpm *GenericPoolManager) GetFuncSvcFromCache(ctx context.Context, fn *fv1.Function) (*fscache.FuncSvc, error) {
|
||||
@@ -239,6 +252,14 @@ func (gpm *GenericPoolManager) TapService(ctx context.Context, svcHost string) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gpm *GenericPoolManager) MarkSpecializationFailure(ctx context.Context, key string) {
|
||||
otelUtils.SpanTrackEvent(ctx, "MarkSpecializationFailure",
|
||||
attribute.KeyValue{Key: "key", Value: attribute.StringValue(key)})
|
||||
logger := otelUtils.LoggerWithTraceID(ctx, gpm.logger)
|
||||
logger.Info("marking specialization failure", zap.Any("key", key))
|
||||
gpm.fsCache.MarkSpecializationFailure(key)
|
||||
}
|
||||
|
||||
// IsValid checks if pod is not deleted and that it has the address passed as the argument. Also checks that all the
|
||||
// containers in it are reporting a ready status for the healthCheck.
|
||||
func (gpm *GenericPoolManager) IsValid(ctx context.Context, fsvc *fscache.FuncSvc) bool {
|
||||
@@ -741,3 +762,7 @@ func (gpm *GenericPoolManager) NoActiveConnectionEventChecker(ctx context.Contex
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func (gpm *GenericPoolManager) DumpDebugInfo(ctx context.Context) error {
|
||||
return gpm.fsCache.DumpDebugInfo(ctx)
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/fission/fission/pkg/crd"
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
"github.com/fission/fission/pkg/executor/metrics"
|
||||
"github.com/fission/fission/pkg/executor/util"
|
||||
)
|
||||
|
||||
type fscRequestType int
|
||||
@@ -170,6 +171,27 @@ func (fsc *FunctionServiceCache) service() {
|
||||
}
|
||||
}
|
||||
|
||||
// DumpDebugInfo => dump function service cache data to temporary directory of executor pod.
|
||||
func (fsc *FunctionServiceCache) DumpDebugInfo(ctx context.Context) error {
|
||||
fsc.logger.Info("dumping function service")
|
||||
|
||||
file, err := util.CreateDumpFile(fsc.logger)
|
||||
if err != nil {
|
||||
fsc.logger.Error("error while creating file/dir", zap.String("error", err.Error()))
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
err = fsc.connFunctionCache.LogFnSvcGroup(ctx, file)
|
||||
if err != nil {
|
||||
fsc.logger.Error("error while logging function service group", zap.String("error", err.Error()))
|
||||
return err
|
||||
}
|
||||
|
||||
fsc.logger.Info("dumped function service")
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetByFunction gets a function service from cache using function key.
|
||||
func (fsc *FunctionServiceCache) GetByFunction(m *metav1.ObjectMeta) (*FuncSvc, error) {
|
||||
key := crd.CacheKey(m)
|
||||
@@ -244,6 +266,10 @@ func (fsc *FunctionServiceCache) MarkAvailable(key string, svcHost string) {
|
||||
fsc.connFunctionCache.MarkAvailable(key, svcHost)
|
||||
}
|
||||
|
||||
func (fsc *FunctionServiceCache) MarkSpecializationFailure(key string) {
|
||||
fsc.connFunctionCache.MarkSpecializationFailure(key)
|
||||
}
|
||||
|
||||
// Add adds a function service to cache if it does not exist already.
|
||||
func (fsc *FunctionServiceCache) Add(fsvc FuncSvc) (*FuncSvc, error) {
|
||||
existing, err := fsc.byFunction.Set(crd.CacheKey(fsvc.Function), &fsvc)
|
||||
|
||||
@@ -17,8 +17,10 @@ limitations under the License.
|
||||
package fscache
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
@@ -36,6 +38,8 @@ const (
|
||||
markAvailable
|
||||
deleteValue
|
||||
setCPUUtilization
|
||||
markSpecializationFailure
|
||||
logFuncSvc
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -65,6 +69,7 @@ type (
|
||||
ctx context.Context
|
||||
function string
|
||||
address string
|
||||
dumpWriter io.Writer
|
||||
value *FuncSvc
|
||||
requestsPerPod int
|
||||
cpuUsage resource.Quantity
|
||||
@@ -232,9 +237,59 @@ func (c *PoolCache) service() {
|
||||
}
|
||||
}
|
||||
}
|
||||
case markSpecializationFailure:
|
||||
if c.cache[req.function].svcWaiting > c.cache[req.function].queue.Len() {
|
||||
c.cache[req.function].svcWaiting--
|
||||
if c.cache[req.function].svcWaiting == c.cache[req.function].queue.Len() {
|
||||
expiredRequests := c.cache[req.function].queue.Expired()
|
||||
c.cache[req.function].svcWaiting = c.cache[req.function].svcWaiting - expiredRequests
|
||||
}
|
||||
}
|
||||
case deleteValue:
|
||||
delete(c.cache[req.function].svcs, req.address)
|
||||
req.responseChannel <- resp
|
||||
case logFuncSvc:
|
||||
datawriter := bufio.NewWriter(req.dumpWriter)
|
||||
|
||||
writefnSvcGrp := func(svcGrp *funcSvcGroup) error {
|
||||
_, err := datawriter.WriteString(fmt.Sprintf("svc_waiting:%d\tqueue_len:%d", svcGrp.svcWaiting, svcGrp.queue.Len()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(svcGrp.svcs) == 0 {
|
||||
_, err := datawriter.WriteString("\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for addr, fnSvc := range svcGrp.svcs {
|
||||
_, err := datawriter.WriteString(fmt.Sprintf("\tfunction_name:%s\tfn_svc_address:%s\tactive_req:%d\tcurrent_cpu_usage:%v\tcpu_limit:%v\n",
|
||||
fnSvc.val.Function.Name, addr, fnSvc.activeRequests, fnSvc.currentCPUUsage, fnSvc.cpuLimit))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, fnSvcGrp := range c.cache {
|
||||
err := writefnSvcGrp(fnSvcGrp)
|
||||
if err != nil {
|
||||
resp.error = err
|
||||
break
|
||||
}
|
||||
}
|
||||
err := datawriter.Flush()
|
||||
if err != nil {
|
||||
if resp.error == nil {
|
||||
resp.error = err
|
||||
} else {
|
||||
resp.error = fmt.Errorf("%v, %v", resp.error, err)
|
||||
}
|
||||
}
|
||||
req.responseChannel <- resp
|
||||
default:
|
||||
resp.error = ferror.MakeError(ferror.ErrorInvalidArgument,
|
||||
fmt.Sprintf("invalid request type: %v", req.requestType))
|
||||
@@ -328,3 +383,23 @@ func (c *PoolCache) DeleteValue(ctx context.Context, function, address string) e
|
||||
resp := <-respChannel
|
||||
return resp.error
|
||||
}
|
||||
|
||||
// ReduceSpecializationInProgress reduces the svcWaiting count
|
||||
func (c *PoolCache) MarkSpecializationFailure(function string) {
|
||||
c.requestChannel <- &request{
|
||||
requestType: markSpecializationFailure,
|
||||
function: function,
|
||||
responseChannel: make(chan *response),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *PoolCache) LogFnSvcGroup(ctx context.Context, file io.Writer) error {
|
||||
respChannel := make(chan *response)
|
||||
c.requestChannel <- &request{
|
||||
requestType: logFuncSvc,
|
||||
dumpWriter: file,
|
||||
responseChannel: respChannel,
|
||||
}
|
||||
resp := <-respChannel
|
||||
return resp.error
|
||||
}
|
||||
|
||||
@@ -38,6 +38,31 @@ func (q *Queue) Pop() *svcWait {
|
||||
return svcWait
|
||||
}
|
||||
|
||||
func (q *Queue) Expired() int {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
expired := 0
|
||||
svcExpired := []*list.Element{}
|
||||
for item := q.items.Front(); item != nil; item = item.Next() {
|
||||
svcWait, ok := item.Value.(*svcWait)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if svcWait.ctx.Err() != nil {
|
||||
close(svcWait.svcChannel)
|
||||
svcExpired = append(svcExpired, item)
|
||||
expired = expired + 1
|
||||
}
|
||||
}
|
||||
|
||||
for _, item := range svcExpired {
|
||||
q.items.Remove(item)
|
||||
}
|
||||
|
||||
return expired
|
||||
}
|
||||
|
||||
func (q *Queue) Len() int {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package fscache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
@@ -113,3 +114,78 @@ func TestQueueLen(t *testing.T) {
|
||||
t.Errorf("Expected queue length to be 1, got %d", q.Len())
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpiredWhenAllItemsExpired(t *testing.T) {
|
||||
q := NewQueue()
|
||||
if q.Expired() != 0 {
|
||||
t.Errorf("Expected Expired to return 0, got %d", q.Expired())
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
item := &svcWait{
|
||||
svcChannel: make(chan *FuncSvc),
|
||||
ctx: ctx,
|
||||
}
|
||||
q.Push(item)
|
||||
if q.Len() != 1 {
|
||||
t.Errorf("Expected queue length to be 1, got %d", q.Len())
|
||||
}
|
||||
cancel()
|
||||
if q.Expired() != 1 {
|
||||
t.Errorf("Expected Expired to return 1, got %d", q.Expired())
|
||||
}
|
||||
if q.Len() != 0 {
|
||||
t.Errorf("Expected queue length to be 0, got %d", q.Len())
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpiredWhenFewItemsExpired(t *testing.T) {
|
||||
q := NewQueue()
|
||||
if q.Expired() != 0 {
|
||||
t.Errorf("Expected Expired to return 0, got %d", q.Expired())
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
q.Push(&svcWait{
|
||||
svcChannel: make(chan *FuncSvc),
|
||||
ctx: ctx,
|
||||
})
|
||||
q.Push(&svcWait{
|
||||
svcChannel: make(chan *FuncSvc),
|
||||
ctx: context.Background(),
|
||||
})
|
||||
if q.Len() != 2 {
|
||||
t.Errorf("Expected queue length to be 1, got %d", q.Len())
|
||||
}
|
||||
cancel()
|
||||
if q.Expired() != 1 {
|
||||
t.Errorf("Expected Expired to return 1, got %d", q.Expired())
|
||||
}
|
||||
if q.Len() != 1 {
|
||||
t.Errorf("Expected queue length to be 0, got %d", q.Len())
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpiredWhenNoItemsExpired(t *testing.T) {
|
||||
q := NewQueue()
|
||||
if q.Expired() != 0 {
|
||||
t.Errorf("Expected Expired to return 0, got %d", q.Expired())
|
||||
}
|
||||
|
||||
q.Push(&svcWait{
|
||||
svcChannel: make(chan *FuncSvc),
|
||||
ctx: context.Background(),
|
||||
})
|
||||
q.Push(&svcWait{
|
||||
svcChannel: make(chan *FuncSvc),
|
||||
ctx: context.Background(),
|
||||
})
|
||||
if q.Len() != 2 {
|
||||
t.Errorf("Expected queue length to be 1, got %d", q.Len())
|
||||
}
|
||||
if q.Expired() != 0 {
|
||||
t.Errorf("Expected Expired to return 1, got %d", q.Expired())
|
||||
}
|
||||
if q.Len() != 2 {
|
||||
t.Errorf("Expected queue length to be 0, got %d", q.Len())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ var (
|
||||
},
|
||||
functionLabels,
|
||||
)
|
||||
FuncError = prometheus.NewCounterVec(
|
||||
ColdStartsError = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "fission_function_cold_start_errors_total",
|
||||
Help: "Count of fission cold start errors",
|
||||
@@ -54,5 +54,5 @@ func init() {
|
||||
registry := metrics.Registry
|
||||
registry.MustRegister(ColdStarts)
|
||||
registry.MustRegister(FuncRunningSummary)
|
||||
registry.MustRegister(FuncError)
|
||||
registry.MustRegister(ColdStartsError)
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ import (
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
dumpFileName string = "fission-dump"
|
||||
)
|
||||
|
||||
// ApplyImagePullSecret applies image pull secret to the give pod spec.
|
||||
// It's intentional not to check the existence of secret here.
|
||||
// First, Kubernetes will set Pod status to "ImagePullBackOff" once
|
||||
@@ -152,3 +156,11 @@ func GetObjectReaperInterval(logger *zap.Logger, executorType fv1.ExecutorType,
|
||||
func getExecutorEnvVarName(executor fv1.ExecutorType) string {
|
||||
return strings.ToUpper(string(executor)) + "_OBJECT_REAPER_INTERVAL"
|
||||
}
|
||||
|
||||
// CreateDumpFile => create dump file inside temp directory
|
||||
func CreateDumpFile(logger *zap.Logger) (*os.File, error) {
|
||||
dumpPath := os.TempDir()
|
||||
logger.Info("creating dump file", zap.String("dump_path", dumpPath))
|
||||
|
||||
return os.Create(fmt.Sprintf("%s/%s-%d.txt", dumpPath, dumpFileName, time.Now().Unix()))
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ func (opts *CreateSubCommand) run(input cli.Input) (err error) {
|
||||
}
|
||||
|
||||
specFile := fmt.Sprintf("env-%v.yaml", m.Name)
|
||||
err = spec.SpecSave(*opts.env, specFile)
|
||||
err = spec.SpecSave(*opts.env, specFile, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving environment spec")
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
@@ -78,7 +79,20 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
m := opts.env.ObjectMeta
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
err := opts.env.Validate()
|
||||
if err != nil {
|
||||
return fv1.AggregateValidationErrors("Environment", err)
|
||||
}
|
||||
|
||||
specFile := fmt.Sprintf("env-%s.yaml", m.Name)
|
||||
err = spec.SpecSave(*opts.env, specFile, true)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving environment spec")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
enew, err := opts.Client().FissionClientSet.CoreV1().Environments(opts.env.ObjectMeta.Namespace).Update(input.Context(), opts.env, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error updating environment")
|
||||
|
||||
@@ -363,7 +363,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
|
||||
}
|
||||
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
err := spec.SpecSave(*opts.function, opts.specFile)
|
||||
err := spec.SpecSave(*opts.function, opts.specFile, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving function spec")
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ func (opts *RunContainerSubCommand) run(input cli.Input) error {
|
||||
}
|
||||
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
err := spec.SpecSave(*opts.function, opts.specFile)
|
||||
err := spec.SpecSave(*opts.function, opts.specFile, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving function spec")
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||
_package "github.com/fission/fission/pkg/fission-cli/cmd/package"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
@@ -35,6 +36,7 @@ import (
|
||||
type UpdateSubCommand struct {
|
||||
cmd.CommandActioner
|
||||
function *fv1.Function
|
||||
specFile string
|
||||
}
|
||||
|
||||
func Update(input cli.Input) error {
|
||||
@@ -55,6 +57,9 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error in updating function ")
|
||||
}
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
opts.specFile = fmt.Sprintf("function-%s.yaml", fnName)
|
||||
}
|
||||
|
||||
function, err := opts.Client().FissionClientSet.CoreV1().Functions(fnNamespace).Get(input.Context(), input.String(flagkey.FnName), metav1.GetOptions{})
|
||||
if err != nil {
|
||||
@@ -193,7 +198,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
|
||||
return errors.Errorf("Package is used by multiple functions, use --%v to force update", flagkey.PkgForce)
|
||||
}
|
||||
|
||||
newPkgMeta, err := _package.UpdatePackage(input, opts.Client(), pkg)
|
||||
newPkgMeta, err := _package.UpdatePackage(input, opts.Client(), opts.specFile, pkg)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("error updating package '%v'", pkgName))
|
||||
}
|
||||
@@ -243,6 +248,17 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
err := opts.function.Validate()
|
||||
if err != nil {
|
||||
return fv1.AggregateValidationErrors("Function", err)
|
||||
}
|
||||
err = spec.SpecSave(*opts.function, opts.specFile, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving function spec")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
_, err := opts.Client().FissionClientSet.CoreV1().Functions(opts.function.Namespace).Update(input.Context(), opts.function, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error updating function")
|
||||
|
||||
@@ -219,7 +219,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
|
||||
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
specFile := fmt.Sprintf("route-%v.yaml", opts.trigger.ObjectMeta.Name)
|
||||
err := spec.SpecSave(*opts.trigger, specFile)
|
||||
err := spec.SpecSave(*opts.trigger, specFile, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving HTTP trigger spec")
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
@@ -148,7 +149,18 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
err := opts.trigger.Validate()
|
||||
if err != nil {
|
||||
return fv1.AggregateValidationErrors("HTTPTrigger", err)
|
||||
}
|
||||
specFile := fmt.Sprintf("route-%s.yaml", opts.trigger.ObjectMeta.Name)
|
||||
err = spec.SpecSave(*opts.trigger, specFile, true)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving HTTP trigger spec")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err := util.CheckHTTPTriggerDuplicates(input.Context(), opts.Client(), opts.trigger)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error while creating HTTP Trigger")
|
||||
|
||||
@@ -119,7 +119,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
|
||||
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
specFile := fmt.Sprintf("kubewatch-%v.yaml", opts.watcher.ObjectMeta.Name)
|
||||
err := spec.SpecSave(*opts.watcher, specFile)
|
||||
err := spec.SpecSave(*opts.watcher, specFile, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving kubewatch spec")
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
|
||||
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
specFile := fmt.Sprintf("mqtrigger-%v.yaml", opts.trigger.ObjectMeta.Name)
|
||||
err := spec.SpecSave(*opts.trigger, specFile)
|
||||
err := spec.SpecSave(*opts.trigger, specFile, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving message queue trigger spec")
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
@@ -148,6 +149,18 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
err := opts.trigger.Validate()
|
||||
if err != nil {
|
||||
return fv1.AggregateValidationErrors("MessageQueueTrigger", err)
|
||||
}
|
||||
specFile := fmt.Sprintf("mqtrigger-%s.yaml", opts.trigger.ObjectMeta.Name)
|
||||
err = spec.SpecSave(*opts.trigger, specFile, true)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving message queue trigger spec")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
_, err := opts.Client().FissionClientSet.CoreV1().MessageQueueTriggers(opts.trigger.ObjectMeta.Namespace).Update(input.Context(), opts.trigger, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error updating message queue trigger")
|
||||
|
||||
@@ -216,7 +216,7 @@ func CreatePackage(input cli.Input, client cmd.Client, pkgName string, pkgNamesp
|
||||
return &pkg.ObjectMeta, nil
|
||||
}
|
||||
|
||||
err = spec.SpecSave(*pkg, specFile)
|
||||
err = spec.SpecSave(*pkg, specFile, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error saving package spec")
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ func CreateArchive(client cmd.Client, input cli.Input, includeFiles []string, no
|
||||
aus.Name = oldAus.Name
|
||||
} else {
|
||||
// save the uploadspec
|
||||
err := spec.SpecSave(*aus, specFile)
|
||||
err := spec.SpecSave(*aus, specFile, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error saving archive spec")
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ import (
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
type UpdateSubCommand struct {
|
||||
@@ -61,6 +63,7 @@ func (opts *UpdateSubCommand) complete(input cli.Input) (err error) {
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
pkgName := input.String(flagkey.PkgName)
|
||||
pkg, err := opts.Client().FissionClientSet.CoreV1().Packages(opts.pkgNamespace).Get(input.Context(), opts.pkgName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -79,8 +82,8 @@ func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
if !forceUpdate && len(fnList) > 1 {
|
||||
return errors.Errorf("package is used by multiple functions, use --%v to force update", flagkey.PkgForce)
|
||||
}
|
||||
|
||||
newPkgMeta, err := UpdatePackage(input, opts.Client(), pkg)
|
||||
specFile := fmt.Sprintf("package-%s.yaml", pkgName)
|
||||
newPkgMeta, err := UpdatePackage(input, opts.Client(), specFile, pkg)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error updating package")
|
||||
}
|
||||
@@ -95,7 +98,7 @@ func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdatePackage(input cli.Input, client cmd.Client, pkg *fv1.Package) (*metav1.ObjectMeta, error) {
|
||||
func UpdatePackage(input cli.Input, client cmd.Client, specFile string, pkg *fv1.Package) (*metav1.ObjectMeta, error) {
|
||||
envName := input.String(flagkey.PkgEnvironment)
|
||||
srcArchiveFiles := input.StringSlice(flagkey.PkgSrcArchive)
|
||||
deployArchiveFiles := input.StringSlice(flagkey.PkgDeployArchive)
|
||||
@@ -174,6 +177,27 @@ func UpdatePackage(input cli.Input, client cmd.Client, pkg *fv1.Package) (*metav
|
||||
}
|
||||
}
|
||||
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
// if a package with the same spec exists, don't create a new spec file
|
||||
fr, err := spec.ReadSpecs(util.GetSpecDir(input), util.GetSpecIgnore(input), false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error reading specs")
|
||||
}
|
||||
|
||||
obj := fr.SpecExists(pkg, true, true)
|
||||
if obj != nil {
|
||||
pkg := obj.(*fv1.Package)
|
||||
fmt.Printf("Re-using previously created package %s\n", pkg.ObjectMeta.Name)
|
||||
return &pkg.ObjectMeta, nil
|
||||
}
|
||||
|
||||
err = spec.SpecSave(*pkg, specFile, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error saving package spec")
|
||||
}
|
||||
return &pkg.ObjectMeta, nil
|
||||
}
|
||||
|
||||
newPkgMeta, err := client.FissionClientSet.CoreV1().Packages(pkg.ObjectMeta.Namespace).Update(input.Context(), pkg, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "update package")
|
||||
|
||||
@@ -127,7 +127,7 @@ func MapKey(m *metav1.ObjectMeta) string {
|
||||
}
|
||||
|
||||
// save saves object encoded value to spec file under given spec directory
|
||||
func save(data []byte, specDir string, specFile string) error {
|
||||
func save(data []byte, specDir string, specFile string, truncate bool) error {
|
||||
// verify
|
||||
if _, err := os.Stat(filepath.Join(specDir, "fission-deployment-config.yaml")); os.IsNotExist(err) {
|
||||
return errors.Wrap(err, "Couldn't find specs, run `fission spec init` first")
|
||||
@@ -137,6 +137,9 @@ func save(data []byte, specDir string, specFile string) error {
|
||||
// check if the file is new
|
||||
newFile := false
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
if truncate {
|
||||
return errors.Errorf("spec file does not exists")
|
||||
}
|
||||
newFile = true
|
||||
}
|
||||
|
||||
@@ -147,11 +150,19 @@ func save(data []byte, specDir string, specFile string) error {
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// if we're appending, add a yaml document separator
|
||||
if !newFile {
|
||||
_, err = f.Write([]byte("\n---\n"))
|
||||
if truncate {
|
||||
err = f.Truncate(0)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "couldn't write to spec file")
|
||||
return errors.Wrap(err, "couldn't truncate the spec file")
|
||||
}
|
||||
|
||||
} else {
|
||||
// if we're appending, add a yaml document separator
|
||||
if !newFile {
|
||||
_, err = f.Write([]byte("\n---\n"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "couldn't write to spec file")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +175,7 @@ func save(data []byte, specDir string, specFile string) error {
|
||||
}
|
||||
|
||||
// called from `fission * create --spec`
|
||||
func SpecSave(resource interface{}, specFile string) error {
|
||||
func SpecSave(resource interface{}, specFile string, update bool) error {
|
||||
var specDir = "specs"
|
||||
|
||||
meta, kind, data, err := crdToYaml(resource)
|
||||
@@ -186,7 +197,11 @@ func SpecSave(resource interface{}, specFile string) error {
|
||||
return errors.Errorf("same name resource (%v) already exists in namespace (%v)", meta.Name, meta.Namespace)
|
||||
}
|
||||
|
||||
err = save(data, specDir, specFile)
|
||||
truncate := false
|
||||
if update {
|
||||
truncate = true
|
||||
}
|
||||
err = save(data, specDir, specFile, truncate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
|
||||
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
specFile := fmt.Sprintf("timetrigger-%v.yaml", opts.trigger.ObjectMeta.Name)
|
||||
err := spec.SpecSave(*opts.trigger, specFile)
|
||||
err := spec.SpecSave(*opts.trigger, specFile, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving time trigger spec")
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
@@ -86,6 +87,18 @@ func (opts *UpdateSubCommand) complete(input cli.Input) error {
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
err := opts.trigger.Validate()
|
||||
if err != nil {
|
||||
return fv1.AggregateValidationErrors("TimeTrigger", err)
|
||||
}
|
||||
specFile := fmt.Sprintf("timetrigger-%s.yaml", opts.trigger.ObjectMeta.Name)
|
||||
err = spec.SpecSave(*opts.trigger, specFile, true)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error saving time trigger spec")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
_, err := opts.Client().FissionClientSet.CoreV1().TimeTriggers(opts.trigger.ObjectMeta.Namespace).Update(input.Context(), opts.trigger, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error updating Time trigger")
|
||||
|
||||
@@ -67,6 +67,12 @@ func (rw *ResponseWriterWrapper) WriteHeader(statuscode int) {
|
||||
rw.ResponseWriter.WriteHeader(statuscode)
|
||||
}
|
||||
|
||||
func (rw *ResponseWriterWrapper) Flush() {
|
||||
if f, ok := rw.ResponseWriter.(http.Flusher); ok {
|
||||
f.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
func HTTPMetricMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if util.IsWebsocketRequest(r) {
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var dataRow = []byte("I'm the data Row\n")
|
||||
|
||||
func chunkedHandler(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, cancel := context.WithCancel(r.Context())
|
||||
ticker := time.NewTicker(time.Second) // We may set it to 10 secs
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
_, _ = w.Write(dataRow)
|
||||
if f, ok := w.(http.Flusher); ok {
|
||||
f.Flush()
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Emulate some work
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
// Telling the loop that keeps the connection alive to end
|
||||
cancel()
|
||||
|
||||
// Waiting until the loop ends
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestChunked(t *testing.T) {
|
||||
mr := mux.NewRouter()
|
||||
mr.Use(HTTPMetricMiddleware)
|
||||
mr.Handle("/", http.HandlerFunc(chunkedHandler))
|
||||
s := httptest.NewServer(mr)
|
||||
defer s.Close()
|
||||
|
||||
resp, err := http.Get(s.URL)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, resp.TransferEncoding, "chunked")
|
||||
defer resp.Body.Close()
|
||||
|
||||
r := bufio.NewReader(resp.Body)
|
||||
for {
|
||||
line, err := readChunkedResponseLine(r)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return
|
||||
}
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
if len(line) == 0 {
|
||||
log.Println("Alive!")
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Println(string(line)) // we got the final response
|
||||
assert.Equal(t, dataRow, append(line, '\n'))
|
||||
}
|
||||
}
|
||||
|
||||
func readChunkedResponseLine(r *bufio.Reader) ([]byte, error) {
|
||||
line, isPrefix, err := r.ReadLine()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if isPrefix {
|
||||
rest, err := readChunkedResponseLine(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
line = append(line, rest...)
|
||||
}
|
||||
|
||||
return line, nil
|
||||
}
|
||||
@@ -20,7 +20,7 @@ const (
|
||||
type (
|
||||
NamespaceResolver struct {
|
||||
FunctionNamespace string
|
||||
BuiderNamespace string
|
||||
BuilderNamespace string
|
||||
DefaultNamespace string
|
||||
FissionResourceNS map[string]string
|
||||
Logger *zap.Logger
|
||||
@@ -40,14 +40,14 @@ var nsResolver *NamespaceResolver
|
||||
func init() {
|
||||
nsResolver = &NamespaceResolver{
|
||||
FunctionNamespace: os.Getenv(ENV_FUNCTION_NAMESPACE),
|
||||
BuiderNamespace: os.Getenv(ENV_BUILDER_NAMESPACE),
|
||||
BuilderNamespace: os.Getenv(ENV_BUILDER_NAMESPACE),
|
||||
DefaultNamespace: os.Getenv(ENV_DEFAULT_NAMESPACE),
|
||||
FissionResourceNS: GetNamespaces(),
|
||||
Logger: loggerfactory.GetLogger(),
|
||||
}
|
||||
|
||||
nsResolver.Logger.Debug("namespaces", zap.String("function_namespace", nsResolver.FunctionNamespace),
|
||||
zap.String("builder_namespace", nsResolver.BuiderNamespace),
|
||||
zap.String("builder_namespace", nsResolver.BuilderNamespace),
|
||||
zap.String("default_namespace", nsResolver.DefaultNamespace),
|
||||
zap.Any("fission_resource_namespace", listNamespaces(nsResolver.FissionResourceNS)))
|
||||
}
|
||||
@@ -96,8 +96,8 @@ func (nsr *NamespaceResolver) FissionNSWithOptions(option ...option) map[string]
|
||||
if options.functionNS && nsr.FunctionNamespace != "" {
|
||||
fissionResourceNS[nsr.FunctionNamespace] = nsr.FunctionNamespace
|
||||
}
|
||||
if options.builderNS && nsr.BuiderNamespace != "" {
|
||||
fissionResourceNS[nsr.BuiderNamespace] = nsr.BuiderNamespace
|
||||
if options.builderNS && nsr.BuilderNamespace != "" {
|
||||
fissionResourceNS[nsr.BuilderNamespace] = nsr.BuilderNamespace
|
||||
}
|
||||
if options.defaultNs && nsr.DefaultNamespace != "" {
|
||||
fissionResourceNS[nsr.DefaultNamespace] = nsr.DefaultNamespace
|
||||
@@ -118,7 +118,7 @@ func GetNamespaces() map[string]string {
|
||||
if len(envValue) > 0 {
|
||||
lstNamespaces := strings.Split(envValue, ",")
|
||||
for _, namespace := range lstNamespaces {
|
||||
//check to handle string with additional comma at the end of string. eg- ns1,ns2,
|
||||
// check to handle string with additional comma at the end of string. eg- ns1,ns2,
|
||||
if namespace != "" {
|
||||
namespaces[namespace] = namespace
|
||||
}
|
||||
@@ -132,14 +132,14 @@ func GetNamespaces() map[string]string {
|
||||
}
|
||||
|
||||
func (nsr *NamespaceResolver) GetBuilderNS(namespace string) string {
|
||||
if nsr.BuiderNamespace == "" {
|
||||
if nsr.BuilderNamespace == "" {
|
||||
return namespace
|
||||
}
|
||||
|
||||
if namespace != metav1.NamespaceDefault {
|
||||
return namespace
|
||||
}
|
||||
return nsr.BuiderNamespace
|
||||
return nsr.BuilderNamespace
|
||||
}
|
||||
|
||||
func (nsr *NamespaceResolver) GetFunctionNS(namespace string) string {
|
||||
@@ -154,7 +154,7 @@ func (nsr *NamespaceResolver) GetFunctionNS(namespace string) string {
|
||||
}
|
||||
|
||||
func (nsr *NamespaceResolver) ResolveNamespace(namespace string) string {
|
||||
if nsr.FunctionNamespace == "" || nsr.BuiderNamespace == "" {
|
||||
if nsr.FunctionNamespace == "" || nsr.BuilderNamespace == "" {
|
||||
return nsr.DefaultNamespace
|
||||
}
|
||||
return namespace
|
||||
|
||||
@@ -226,7 +226,7 @@ func TestNamespaceResolver(t *testing.T) {
|
||||
func getFissionNamespaces(builderNS, functionNS, defaultNS string) *NamespaceResolver {
|
||||
return &NamespaceResolver{
|
||||
FunctionNamespace: functionNS,
|
||||
BuiderNamespace: builderNS,
|
||||
BuilderNamespace: builderNS,
|
||||
DefaultNamespace: defaultNS,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ package profile
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
@@ -35,26 +34,18 @@ import (
|
||||
"github.com/fission/fission/pkg/utils/httpserver"
|
||||
)
|
||||
|
||||
func getPprofAddr() string {
|
||||
pprofHost := os.Getenv("PPROF_HOST")
|
||||
if pprofHost == "" {
|
||||
pprofHost = "localhost"
|
||||
}
|
||||
pprofPort := os.Getenv("PPROF_PORT")
|
||||
if pprofPort == "" {
|
||||
pprofPort = "6060"
|
||||
}
|
||||
return fmt.Sprintf("%s:%s", pprofHost, pprofPort)
|
||||
}
|
||||
|
||||
func ProfileIfEnabled(ctx context.Context, logger *zap.Logger) {
|
||||
enablePprof := os.Getenv("PPROF_ENABLED")
|
||||
if enablePprof != "true" {
|
||||
return
|
||||
}
|
||||
pprofPort := os.Getenv("PPROF_PORT")
|
||||
if pprofPort == "" {
|
||||
pprofPort = "6060"
|
||||
}
|
||||
|
||||
pprofMux := http.DefaultServeMux
|
||||
http.DefaultServeMux = http.NewServeMux()
|
||||
|
||||
go httpserver.StartServer(ctx, logger, "pprof", getPprofAddr(), pprofMux)
|
||||
go httpserver.StartServer(ctx, logger, "pprof", pprofPort, pprofMux)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user