diff --git a/.github/workflows/build-web-console.yaml b/.github/workflows/build-web-console.yaml deleted file mode 100644 index fbf71337a..000000000 --- a/.github/workflows/build-web-console.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Build Web Console V1 - -on: - pull_request: - branches: - - master - paths: - - 'web_console/**' - -defaults: - run: - working-directory: web_console - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [10.x, 12.x, 14.x] - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: npm ci - - run: npm run build diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4b1a59896..6b617d2f2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,7 +10,12 @@ on: jobs: test: - runs-on: ubuntu-latest + strategy: + matrix: + # As long as we need Python 3.6 here in the test, we can only use up to Ubuntu 20. + # https://github.com/actions/setup-python/issues/544 + os: [ubuntu-20.04] + runs-on: ${{ matrix.os }} name: CI tests steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml deleted file mode 100644 index 8a26185f3..000000000 --- a/.github/workflows/publish-to-pypi.yml +++ /dev/null @@ -1,40 +0,0 @@ -# TODO add test pypi -name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI - -on: - push: - branches: - - nightly -jobs: - build-n-publish: - name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-18.04] - - steps: - - uses: actions/checkout@master - - name: Set up Python 3.6 - uses: actions/setup-python@v1 - with: - python-version: 3.6 - - name: Install pypa/build - run: >- - python -m - pip install - build - --user - - name: Build a binary wheel and a source tarball - run: >- - python -m - build - --wheel - --outdir dist/ - - name: Publish distribution 📦 to PyPI - uses: pypa/gh-action-pypi-publish@master - with: - user: fedlearner - password: ${{ secrets.PYPI_SECRET }} - diff --git a/.github/workflows/release-web-console-v2.yaml b/.github/workflows/release-web-console-v2.yaml deleted file mode 100644 index a20881bc5..000000000 --- a/.github/workflows/release-web-console-v2.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: Release Web Console V2 - -on: [push] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set Short Commit Sha - id: vars - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - - uses: whoan/docker-build-with-cache-action@v5 - with: - context: ./web_console_v2 - dockerfile: Dockerfile - image_name: fedlearner/fedlearner-web-console-v2 - image_tag: ${{ steps.vars.outputs.sha_short }} - username: fedlearner - password: "${{ secrets.DOCKER_REGISTRY }}" diff --git a/.github/workflows/release-web-console.yaml b/.github/workflows/release-web-console.yaml deleted file mode 100644 index f836d7563..000000000 --- a/.github/workflows/release-web-console.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Release Web Console - -on: [push] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set Short Commit Sha - id: vars - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - - uses: whoan/docker-build-with-cache-action@v5 - with: - context: ./web_console - image_name: fedlearner/fedlearner-web-console - image_tag: ${{ steps.vars.outputs.sha_short }} - username: fedlearner - password: "${{ secrets.DOCKER_REGISTRY }}" diff --git a/.github/workflows/tag-web-console.yaml b/.github/workflows/tag-web-console.yaml deleted file mode 100644 index 94748d8da..000000000 --- a/.github/workflows/tag-web-console.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Tag Web Console - -on: - release: - types: [published] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set Short Commit Sha - id: vars - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - - uses: whoan/docker-build-with-cache-action@v5 - with: - context: ./web_console - image_name: fedlearner/fedlearner-web-console - image_tag: ${{ github.event.release.tag_name }} - username: fedlearner - password: "${{ secrets.DOCKER_REGISTRY }}" diff --git a/.github/workflows/update-nightly.yml b/.github/workflows/update-nightly.yml deleted file mode 100644 index 6eade91f3..000000000 --- a/.github/workflows/update-nightly.yml +++ /dev/null @@ -1,21 +0,0 @@ -on: - workflow_dispatch: # Allow manual triggers - schedule: - - cron: 0 2 * * * # 4am UTC is 10pm in Beijing -name: Set nightly branch to master HEAD -jobs: - master-to-nightly: - if: github.repository == 'bytedance/fedlearner' # Don't do this in forks - runs-on: ubuntu-latest - steps: - - name: checkout - uses: actions/checkout@v1 - - - uses: robotology/gh-action-nightly-merge@v1.3.1 - name: Set nightly branch to master HEAD - with: - stable_branch: 'master' - development_branch: 'nightly' - allow_ff: false - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/web-console-v2-api.yaml b/.github/workflows/web-console-v2-api.yaml deleted file mode 100644 index 7dbbe96dd..000000000 --- a/.github/workflows/web-console-v2-api.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: Web Consolve V2 API CI - -on: - pull_request: - paths: - - 'web_console_v2/**' - - '.github/**' - push: - paths: - - 'web_console_v2/**' - - '.github/**' - -jobs: - test-api: - name: API tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Setup Python - uses: actions/setup-python@v2 - with: - python-version: '3.7' - - name: Install dependencies - working-directory: web_console_v2/api - run: | - pip install --upgrade pip - pip install -r requirements.txt - - name: Run test - working-directory: web_console_v2 - run: make api-test diff --git a/.github/workflows/web-console-v2-client.yaml b/.github/workflows/web-console-v2-client.yaml deleted file mode 100644 index 07f933e6b..000000000 --- a/.github/workflows/web-console-v2-client.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: Web Consolve V2 Client CI - -on: - pull_request: - paths: - - 'web_console_v2/client/**' - - '.github/**' - push: - paths: - - 'web_console_v2/client/**' - - '.github/**' - -defaults: - run: - working-directory: web_console_v2/client - -jobs: - test-client: - name: Client tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Use Node.js 12 - uses: actions/setup-node@v2.1.5 - with: - node-version: '12.x' - - run: pwd && npx pnpm@5.18.8 install && npx jest --coverage - - run: npx pnpm@5.18.8 build diff --git a/Dockerfile b/Dockerfile index 4b68b502f..793834389 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,9 +4,13 @@ WORKDIR /app COPY . /app RUN apt-get -y update \ + && apt-get -y install cron \ && apt-get -y install libgmp-dev \ && apt-get -y install libmpfr-dev \ && apt-get -y install libmpc-dev \ + # For krb5-user installation + && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install krb5-user \ && rm -rf /var/lib/apt/lists/* RUN pip install --upgrade pip \ diff --git a/Makefile b/Makefile index 1da507928..0d435abbe 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,14 @@ protobuf: --grpc_python_out=. \ protocols/fedlearner/channel/*.proto + python -m grpc_tools.protoc -I. \ + --python_out=. \ + fedlearner/fedavg/cluster/cluster.proto + python -m grpc_tools.protoc -I. \ + --python_out=. \ + --grpc_python_out=. \ + fedlearner/fedavg/training_service.proto + lint: pylint --rcfile ci/pylintrc fedlearner example diff --git a/deploy/charts/fedlearner-add-on/templates/ingress-v1.yaml b/deploy/charts/fedlearner-add-on/templates/ingress-v1.yaml new file mode 100644 index 000000000..a6429424f --- /dev/null +++ b/deploy/charts/fedlearner-add-on/templates/ingress-v1.yaml @@ -0,0 +1,39 @@ +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} + +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: fedlearner-proxy + namespace: {{ .Release.Namespace }} + labels: + {{- include "fedlearner-add-on.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + nginx.ingress.kubernetes.io/auth-tls-secret: default/ca-secret + nginx.ingress.kubernetes.io/auth-tls-verify-client: "on" + nginx.ingress.kubernetes.io/configuration-snippet: | + grpc_set_header Authority $http_x_host; + grpc_set_header Host $http_x_host; + grpc_next_upstream_tries 5; + {{- end }} +spec: + rules: + - host: {{ .Values.ingress.host | quote }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: fedlearner-stack-ingress-nginx-controller + port: + number: 80 + tls: + - hosts: + - {{ .Values.ingress.host }} + secretName: fedlearner-proxy-server +{{- end }} + +{{- end }} diff --git a/deploy/charts/fedlearner-add-on/templates/ingress.yaml b/deploy/charts/fedlearner-add-on/templates/ingress-v1beta1.yaml similarity index 55% rename from deploy/charts/fedlearner-add-on/templates/ingress.yaml rename to deploy/charts/fedlearner-add-on/templates/ingress-v1beta1.yaml index 0749161ce..23c2a0c2d 100644 --- a/deploy/charts/fedlearner-add-on/templates/ingress.yaml +++ b/deploy/charts/fedlearner-add-on/templates/ingress-v1beta1.yaml @@ -1,6 +1,7 @@ +{{- if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}} + {{- if .Values.ingress.enabled -}} -{{- $configurationSnippet := .Files.Get "configuration-snippet.txt" -}} -{{- $serverSnippet := .Files.Get "server-snippet.txt" -}} + {{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} apiVersion: networking.k8s.io/v1beta1 {{- else -}} @@ -15,14 +16,12 @@ metadata: {{- with .Values.ingress.annotations }} annotations: {{- toYaml . | nindent 4 }} - {{- if not (empty $configurationSnippet) }} + nginx.ingress.kubernetes.io/auth-tls-secret: default/ca-secret + nginx.ingress.kubernetes.io/auth-tls-verify-client: "on" nginx.ingress.kubernetes.io/configuration-snippet: | -{{ $configurationSnippet | indent 6 }} - {{- end }} - {{- if not (empty $serverSnippet) }} - nginx.ingress.kubernetes.io/server-snippet: | -{{ $serverSnippet | indent 6 }} - {{- end }} + grpc_set_header Authority $http_x_host; + grpc_set_header Host $http_x_host; + grpc_next_upstream_tries 5; {{- end }} spec: rules: @@ -31,6 +30,12 @@ spec: paths: - path: "/" backend: - serviceName: fedlearner-proxy - servicePort: {{ .Values.ingress.port }} + serviceName: fedlearner-stack-ingress-nginx-controller + servicePort: 80 + tls: + - hosts: + - {{ .Values.ingress.host }} + secretName: fedlearner-proxy-server +{{- end }} + {{- end }} diff --git a/deploy/charts/fedlearner-add-on/templates/secrets.yaml b/deploy/charts/fedlearner-add-on/templates/secrets.yaml index 4ac9e14a4..6addb1f56 100644 --- a/deploy/charts/fedlearner-add-on/templates/secrets.yaml +++ b/deploy/charts/fedlearner-add-on/templates/secrets.yaml @@ -1,14 +1,3 @@ -{{- if .Values.imageCredentials.enabled }} -apiVersion: v1 -kind: Secret -metadata: - name: regcred - namespace: {{ .Release.Namespace }} -type: kubernetes.io/dockerconfigjson -data: - .dockerconfigjson: {{ template "imagePullSecret" . }} -{{- end}} ---- {{- if .Values.tls.enabled }} apiVersion: v1 kind: Secret diff --git a/deploy/charts/fedlearner-add-on/values.yaml b/deploy/charts/fedlearner-add-on/values.yaml index 171f0eaad..afb897f65 100644 --- a/deploy/charts/fedlearner-add-on/values.yaml +++ b/deploy/charts/fedlearner-add-on/values.yaml @@ -2,26 +2,14 @@ # This is a YAML-formatted file. # Declare variables to be passed into your templates. -imageCredentials: - enabled: true - registry: "" - username: "" - password: "" - -service: - enabled: true - type: ExternalName - externalName: "" - ingress: enabled: true annotations: "nginx.ingress.kubernetes.io/proxy-body-size": 10g - "nginx.ingress.kubernetes.io/backend-protocol": GRPCS + "nginx.ingress.kubernetes.io/backend-protocol": GRPC "nginx.ingress.kubernetes.io/http2-insecure-port": "true" "kubernetes.io/ingress.class": nginx - host: external.name - port: 443 + host: test.fedlearner.net tls: enabled: true diff --git a/deploy/charts/fedlearner-pvc/.helmignore b/deploy/charts/fedlearner-pvc/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/deploy/charts/fedlearner-pvc/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/deploy/charts/fedlearner-pvc/Chart.yaml b/deploy/charts/fedlearner-pvc/Chart.yaml new file mode 100644 index 000000000..43a18ebbe --- /dev/null +++ b/deploy/charts/fedlearner-pvc/Chart.yaml @@ -0,0 +1,31 @@ +apiVersion: v2 +name: fedlearner-pvc +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" +dependencies: + - name: nfs-client-provisioner + version: 1.2.8 + condition: nfs-client-provisioner.enabled + - name: nfs-server-provisioner + version: 1.0.0 + condition: nfs-server-provisioner.enabled diff --git a/deploy/charts/fedlearner-stack/charts/nfs-client-provisioner-1.2.8.tgz b/deploy/charts/fedlearner-pvc/charts/nfs-client-provisioner-1.2.8.tgz similarity index 100% rename from deploy/charts/fedlearner-stack/charts/nfs-client-provisioner-1.2.8.tgz rename to deploy/charts/fedlearner-pvc/charts/nfs-client-provisioner-1.2.8.tgz diff --git a/deploy/charts/fedlearner-stack/charts/nfs-server-provisioner-1.0.0.tgz b/deploy/charts/fedlearner-pvc/charts/nfs-server-provisioner-1.0.0.tgz similarity index 100% rename from deploy/charts/fedlearner-stack/charts/nfs-server-provisioner-1.0.0.tgz rename to deploy/charts/fedlearner-pvc/charts/nfs-server-provisioner-1.0.0.tgz diff --git a/deploy/charts/fedlearner-pvc/templates/pv.yaml b/deploy/charts/fedlearner-pvc/templates/pv.yaml new file mode 100644 index 000000000..6247951f0 --- /dev/null +++ b/deploy/charts/fedlearner-pvc/templates/pv.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv-fedlearner-default +spec: + accessModes: + - ReadWriteMany + capacity: + storage: {{ .Values.nfs.capacity }} + mountOptions: + - vers=3 + - nolock,tcp,noresvport + nfs: + path: {{ .Values.nfs.path }} + server: {{ .Values.nfs.server }} + persistentVolumeReclaimPolicy: Retain + storageClassName: nfs diff --git a/deploy/charts/fedlearner-pvc/templates/pvc.yaml b/deploy/charts/fedlearner-pvc/templates/pvc.yaml new file mode 100644 index 000000000..4496eb4ec --- /dev/null +++ b/deploy/charts/fedlearner-pvc/templates/pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pvc-fedlearner-default +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.nfs.capacity }} + volumeName: pv-fedlearner-default + storageClassName: nfs diff --git a/deploy/charts/fedlearner-pvc/values.yaml b/deploy/charts/fedlearner-pvc/values.yaml new file mode 100644 index 000000000..1b3f09f7a --- /dev/null +++ b/deploy/charts/fedlearner-pvc/values.yaml @@ -0,0 +1,28 @@ +# Default values for fedlearner-pvc. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +nfs: + path: /data + server: 127.0.0.1 + capacity: 20Gi + +nfs-server-provisioner: + enabled: true + +nfs-client-provisioner: + enabled: false + + nfs: + path: / + mountOptions: + - vers=3 + - nolock,tcp,noresvport + + storageClass: + name: nfs + + image: + repository: registry.cn-beijing.aliyuncs.com/fedlearner/nfs-client-provisioner + tag: v4.0.0 + pullPolicy: IfNotPresent diff --git a/deploy/charts/fedlearner-stack/Chart.yaml b/deploy/charts/fedlearner-stack/Chart.yaml index 551a2a4bf..8a7de92b9 100644 --- a/deploy/charts/fedlearner-stack/Chart.yaml +++ b/deploy/charts/fedlearner-stack/Chart.yaml @@ -8,19 +8,9 @@ dependencies: - name: ingress-nginx repository: "" version: 2.1.0 -- name: nfs-client-provisioner - version: 1.2.8 - condition: nfs-client-provisioner.enabled -- name: nfs-server-provisioner - version: 1.0.0 - condition: nfs-server-provisioner.enabled - name: elastic-stack version: 2.0.0 condition: elastic-stack.enabled -- name: argo - repository: https://argoproj.github.io/argo-helm - version: 0.9.4 - condition: argo.enabled - name: mysql repository: "" version: 8.0.22 @@ -29,3 +19,7 @@ dependencies: repository: "" version: 4.8.2 condition: etcd.enabled +- name: sparkoperator + repository: http://storage.googleapis.com/kubernetes-charts-incubator + version: 0.8.4 + condition: sparkoperator.enabled diff --git a/deploy/charts/fedlearner-stack/charts/argo-0.9.4.tgz b/deploy/charts/fedlearner-stack/charts/argo-0.9.4.tgz deleted file mode 100644 index 69f988aa8..000000000 Binary files a/deploy/charts/fedlearner-stack/charts/argo-0.9.4.tgz and /dev/null differ diff --git a/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/filebeat/values.yaml b/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/filebeat/values.yaml index a5395a0f5..26e21ffdd 100755 --- a/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/filebeat/values.yaml +++ b/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/filebeat/values.yaml @@ -1,6 +1,6 @@ image: - repository: registry.cn-beijing.aliyuncs.com/fedlearner/filebeat-oss - tag: 7.0.1 + repository: registry.cn-beijing.aliyuncs.com/fedlearner/filebeat + tag: 7.10.0 pullPolicy: IfNotPresent config: @@ -64,6 +64,29 @@ config: json.keys_under_root: true json.overwrite_keys: true json.ignore_decoding_error: true + # for containerd log + - type: log + enabled: true + paths: + - /var/log/pods/*/*/*.log + processors: + - script: + lang: javascript + source: > + function process(event){ + var path = event.Get('log.file.path'); + path = path.split('/'); + var compath = path[4]; + compath = compath.split('_') + event.Put('kubernetes.namespace', compath[0]); + event.Put('kubernetes.pod.name', compath[1]); + event.Put('kubernetes.container.name', path[5]); + var message = event.Get('message'); + var parts = message.split(' '); + if (parts.length > 1 && (parts[1] == 'stdout' || parts[1] == 'stderr')) { + event.Put('stream', parts[1]) + } + } output.elasticsearch: hosts: [ "http://fedlearner-stack-elasticsearch-client:9200" ] @@ -79,7 +102,7 @@ config: - index: "metrics_v2" when.equals: index_type__: "metrics" - - index: "filebeat-7.0.1" + - index: "filebeat-7.10.0" # When a key contains a period, use this format for setting values on the command line: # --set config."http\.enabled"=true diff --git a/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/kibana/templates/ingress-v1.yaml b/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/kibana/templates/ingress-v1.yaml new file mode 100755 index 000000000..a24d4f9f0 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/kibana/templates/ingress-v1.yaml @@ -0,0 +1,40 @@ +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} + +{{- if .Values.ingress.enabled -}} +{{- $serviceName := include "kibana.fullname" . -}} +{{- $servicePort := .Values.service.externalPort -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + labels: + app: {{ template "kibana.name" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: {{ template "kibana.fullname" . }} + annotations: + {{- range $key, $value := .Values.ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + rules: + {{- range .Values.ingress.hosts }} + {{- $url := splitList "/" . }} + - host: {{ first $url }} + http: + paths: + - path: /{{ rest $url | join "/" }} + pathType: Prefix + backend: + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: +{{ toYaml .Values.ingress.tls | indent 4 }} + {{- end -}} +{{- end -}} + +{{- end }} diff --git a/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/kibana/templates/ingress.yaml b/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/kibana/templates/ingress-v1beta1.yaml similarity index 82% rename from deploy/charts/fedlearner-stack/charts/elastic-stack/charts/kibana/templates/ingress.yaml rename to deploy/charts/fedlearner-stack/charts/elastic-stack/charts/kibana/templates/ingress-v1beta1.yaml index 9d97e269a..35eb30e62 100755 --- a/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/kibana/templates/ingress.yaml +++ b/deploy/charts/fedlearner-stack/charts/elastic-stack/charts/kibana/templates/ingress-v1beta1.yaml @@ -1,7 +1,13 @@ +{{- if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}} + {{- if .Values.ingress.enabled -}} {{- $serviceName := include "kibana.fullname" . -}} {{- $servicePort := .Values.service.externalPort -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} kind: Ingress metadata: labels: @@ -31,3 +37,5 @@ spec: {{ toYaml .Values.ingress.tls | indent 4 }} {{- end -}} {{- end -}} + +{{- end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/.helmignore b/deploy/charts/fedlearner-stack/charts/sparkoperator/.helmignore new file mode 100755 index 000000000..b7f6f9f10 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/.helmignore @@ -0,0 +1 @@ +OWNERS diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/Chart.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/Chart.yaml new file mode 100755 index 000000000..75d7a8e2c --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +appVersion: v1beta2-1.2.0-3.0.0 +description: A Helm chart for Spark on Kubernetes operator +home: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator +keywords: +- spark +maintainers: +- email: yuchaoran2011@gmail.com + name: yuchaoran2011 +name: sparkoperator +version: 0.8.4 diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/README.md b/deploy/charts/fedlearner-stack/charts/sparkoperator/README.md new file mode 100755 index 000000000..a21364976 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/README.md @@ -0,0 +1,95 @@ +### Helm Chart for Spark Operator + +This is the Helm chart for the [Kubernetes Operator for Apache Spark](https://github.com/GoogleCloudPlatform/spark-on-k8s-operator). + +#### Prerequisites + +The Operator requires Kubernetes version 1.13 or above to use the subresource support for CustomResourceDefinitions, which became beta in 1.13 and is enabled by default in 1.13 and higher. + +#### Installing the chart + +First add the incubator repo: + +```bash +$ helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator +``` + +If using Helm 2, then the chart can be installed by running: + +```bash +$ helm install incubator/sparkoperator --namespace spark-operator --set sparkJobNamespace=default +``` + +Note that you need to use the `--namespace` flag during `helm install` to specify in which namespace you want to install the operator. The namespace can be existing or not. When it's not available, Helm would take care of creating the namespace. Note that this namespace has no relation to the namespace where you would like to deploy Spark jobs (i.e. the setting `sparkJobNamespace` shown in the table below). They can be the same namespace or different ones. + +If using Helm 3, then install the chart by running: + +```bash +$ helm install incubator/sparkoperator --generate-name --namespace spark-operator --set sparkJobNamespace=default +``` + +or + +```bash +$ helm install [RELEASE-NAME] incubator/sparkoperator --namespace spark-operator --set sparkJobNamespace=default +``` + +if you don't want Helm to automatically generate a name for you. + +#### Configuration + +The following table lists the configurable parameters of the Spark operator chart and their default values. + +| Parameter | Description | Default | +| ------------------------- | ------------------------------------------------------------ | -------------------------------------- | +| `image.repository` | The name of the operator image | `gcr.io/spark-operator/spark-operator` | +| `image.tag` | The version of the operator to install | `v1beta2-1.2.0-3.0.0` | +| `image.pullPolicy` | Docker image pull policy | `IfNotPresent` | +| `imagePullSecrets` | Docker image pull secrets | | +| `replicas` | The number of replicas of the operator Deployment | 1 | +| `sparkJobNamespace` | K8s namespace where Spark jobs are to be deployed | `` | +| `enableWebhook` | Whether to enable mutating admission webhook | false | +| `enableMetrics` | Whether to expose metrics to be scraped by Prometheus | true | +| `controllerThreads` | Number of worker threads used by the SparkApplication controller | 10 | +| `ingressUrlFormat` | Ingress URL format | "" | +| `logLevel` | Logging verbosity level | 2 | +| `installCrds` | Whether the release should install CRDs. | true | +| `metricsPort` | Port for the metrics endpoint | 10254 | +| `metricsEndpoint` | Metrics endpoint | "/metrics" | +| `metricsPrefix` | Prefix for the metrics | "" | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Tolerations for the sparkoperator deployment | `[]` | +| `podAnnotations` | Annotations to be added to pods | `{}` | +| `resyncInterval` | Informer resync interval in seconds | 30 | +| `webhookPort` | Service port of the webhook server | 8080 | +| `webhookNamespaceSelector`| The webhook will only operate on namespaces with this label, specified in the form key1=value1,key2=value2 | `""` | +| `resources` | Resources needed for the sparkoperator deployment | {} | +| `enableBatchScheduler` | Whether to enable batch scheduler for pod scheduling | false | +| `enableResourceQuotaEnforcement` | Whether to enable the ResourceQuota enforcement for SparkApplication resources. Requires the webhook to be enabled by setting enableWebhook to true. | false | +| `leaderElection.enable` | Whether to enable leader election when the operator Deployment has more than one replica, i.e., when `replicas` is greater than 1. | false | +| `leaderElection.lockName` | Lock name to use for leader election | `spark-operator-lock` | +| `leaderElection.lockNamespace` | Namespace to use for leader election | (namespace of release) | +| `securityContext` | Defines security context for operator container. | `{}` | +| `istio.enabled` | Whether Jobs will run in service mesh | false | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +#### Upgrading + +##### To 0.6.5 + +- `enableLeaderElection` has been renamed `leaderElection.enable` to keep all of the leader election stuff together + +##### To 0.6.2 + +###### Breaking changes + +- `cleanupCrdsBeforeInstall` has been removed for Helm 3 compatibility. If you wish to replicate this behavior before upgrading, do so manually (`kubectl delete CustomResourceDefinition sparkapplications.sparkoperator.k8s.io scheduledsparkapplications.sparkoperator.k8s.io`) + +###### Non-breaking changes + +- `app.kubernetes.io/name=sparkoperator` label is added to CRDs if installed at this version, for easier manual cleanup after chart deletion (`kubectl delete CustomResourceDefinition -l app.kubernetes.io/name=sparkoperator`) + +#### Contributing + +When making changes to values.yaml, update the files in `ci/` by running `hack/update-ci.sh`. diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/ci/test-values.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/ci/test-values.yaml new file mode 100755 index 000000000..86bd5d21b --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/ci/test-values.yaml @@ -0,0 +1,79 @@ +image: + repository: registry.cn-beijing.aliyuncs.com/fedlearner/spark-operator + pullPolicy: IfNotPresent + tag: v1beta2-1.2.0-3.0.0 +imagePullSecrets: [] + +rbac: + create: true + +serviceAccounts: + spark: + create: true + name: + sparkoperator: + create: true + name: + +sparkJobNamespace: "" +installCrds: true +controllerThreads: 10 +resyncInterval: 30 +ingressUrlFormat: "" +logLevel: 2 + +securityContext: {} + +enableWebhook: false +webhookPort: 8080 +## The webhook will only operate on namespaces with this label, specified in the form key1=value1,key2=value2 +## empty string will operate on all namespaces +webhookNamespaceSelector: "" + +enableMetrics: true +metricsPort: 10254 +metricsEndpoint: "/metrics" +metricsPrefix: "" + +## Node labels for pod assignment +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +## +nodeSelector: {} + +## Tolerations for the sparkoperator deployment +## +## Example: +## - key: "toleration=key" +## operator: "Equal" +## value: "value" +## effect: "NoSchedule" +## +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] + +podAnnotations: {} + +## Resources for the sparkoperator deployment +## Ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +## +resources: {} + +## Whether to enable batch scheduler for pod scheduling, +## if enabled, end user can specify batch scheduler name in spark application. +enableBatchScheduler: false + +## Whether to enable the ResourceQuota enforcement for SparkApplication resources. +## Requires the webhook to be enabled by setting enableWebhook to true. +## Ref: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/master/docs/user-guide.md#enabling-resource-quota-enforcement. +enableResourceQuotaEnforcement: false + +## Whether to enable leader election when the operator Deployment has more than one replica. +## Only applicable when `replicas` is set to a value greater than 1. +## Ref: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/master/docs/user-guide.md#enabling-leader-election-for-high-availability. +leaderElection: + enable: false + lockName: "spark-operator-lock" + ## Optionally store the lock in another namespace. Defaults to operator's namespace + # lockNamespace: "" +replicas: 1 diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/hack/update-ci.sh b/deploy/charts/fedlearner-stack/charts/sparkoperator/hack/update-ci.sh new file mode 100755 index 000000000..f262566d0 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/hack/update-ci.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +sed \ + -e 's/cleanupCrdsBeforeInstall: false/cleanupCrdsBeforeInstall: true/' \ + values.yaml > ci/test-values.yaml diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/_helpers.tpl b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/_helpers.tpl new file mode 100755 index 000000000..149c070b1 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/_helpers.tpl @@ -0,0 +1,58 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "sparkoperator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + {{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "sparkoperator.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + {{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "sparkoperator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + {{/* +Create the name of the service account to use +*/}} +{{- define "sparkoperator.serviceAccountName" -}} +{{- if .Values.serviceAccounts.sparkoperator.create -}} + {{ default (include "sparkoperator.fullname" .) .Values.serviceAccounts.sparkoperator.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.sparkoperator.name }} +{{- end -}} +{{- end -}} +{{- define "spark.serviceAccountName" -}} +{{- if .Values.serviceAccounts.spark.create -}} + {{ $sparkServiceaccount := printf "%s-%s" .Release.Name "spark" }} + {{ default $sparkServiceaccount .Values.serviceAccounts.spark.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.spark.name }} +{{- end -}} +{{- end -}} + {{/* +Create the leader-election namespace to use +*/}} +{{- define "sparkoperator.leaderElectionLockNamespace" -}} +{{- if .Values.leaderElection.lockNamespace -}} + {{- .Values.leaderElection.lockNamespace -}} +{{- else -}} + {{- .Release.Namespace -}} +{{- end -}} +{{- end -}} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/crd-cleanup-job.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/crd-cleanup-job.yaml new file mode 100755 index 000000000..3cb8b0e0b --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/crd-cleanup-job.yaml @@ -0,0 +1,65 @@ +{{ if .Values.installCrds }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "sparkoperator.fullname" . }}-crd-cleanup + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + template: + metadata: + name: {{ include "sparkoperator.fullname" . }}-crd-cleanup + {{- if .Values.istio.enabled }} + annotations: + "sidecar.istio.io/inject": "false" + {{- end }} + spec: + serviceAccountName: {{ include "sparkoperator.serviceAccountName" . }} + restartPolicy: OnFailure + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | trim | indent 8 }} + containers: + - name: delete-sparkapp-crd + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy}} + {{- if .Values.securityContext }} + securityContext: + {{- range $securityPolicy, $value := .Values.securityContext }} + {{ $securityPolicy }}: {{ $value }} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-c" + - "curl -ik \ + -X DELETE \ + -H \"Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" \ + -H \"Accept: application/json\" \ + -H \"Content-Type: application/json\" \ + https://kubernetes.default.svc/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/sparkapplications.sparkoperator.k8s.io" + - name: delete-scheduledsparkapp-crd + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy}} + {{- if .Values.securityContext }} + securityContext: + {{- range $securityPolicy, $value := .Values.securityContext }} + {{ $securityPolicy }}: {{ $value }} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-c" + - "curl -ik \ + -X DELETE \ + -H \"Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" \ + -H \"Accept: application/json\" \ + -H \"Content-Type: application/json\" \ + https://kubernetes.default.svc/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/scheduledsparkapplications.sparkoperator.k8s.io" +{{ end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/crds-v1.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/crds-v1.yaml new file mode 100755 index 000000000..653b9d238 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/crds-v1.yaml @@ -0,0 +1,8445 @@ +{{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion -}} + +{{ if .Values.installCrds }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (unknown) + api-approved.kubernetes.io: "https://github.com/kubernetes/kubernetes/pull/78458" + creationTimestamp: null + name: sparkapplications.sparkoperator.k8s.io +spec: + group: sparkoperator.k8s.io + names: + kind: SparkApplication + listKind: SparkApplicationList + plural: sparkapplications + shortNames: + - sparkapp + singular: sparkapplication + scope: Namespaced + versions: + - name: v1beta2 + served: true + storage: true + subresources: + status: { } + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + arguments: + items: + type: string + type: array + batchScheduler: + type: string + batchSchedulerOptions: + properties: + priorityClassName: + type: string + queue: + type: string + type: object + deps: + properties: + files: + items: + type: string + type: array + jars: + items: + type: string + type: array + pyFiles: + items: + type: string + type: array + type: object + driver: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + configMaps: + items: + properties: + name: + type: string + path: + type: string + required: + - name + - path + type: object + type: array + coreLimit: + type: string + coreRequest: + type: string + cores: + format: int32 + minimum: 1 + type: integer + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + envSecretKeyRefs: + additionalProperties: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + envVars: + additionalProperties: + type: string + type: object + gpu: + properties: + name: + type: string + quantity: + format: int64 + type: integer + required: + - name + - quantity + type: object + hostNetwork: + type: boolean + image: + type: string + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + javaOptions: + type: string + kubernetesMaster: + type: string + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + memory: + type: string + memoryOverhead: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + podName: + pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*' + type: string + schedulerName: + type: string + secrets: + items: + properties: + name: + type: string + path: + type: string + secretType: + type: string + required: + - name + - path + - secretType + type: object + type: array + securityContext: + properties: + fsGroup: + format: int64 + type: integer + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAnnotations: + additionalProperties: + type: string + type: object + sidecars: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + dynamicAllocation: + properties: + enabled: + type: boolean + initialExecutors: + format: int32 + type: integer + maxExecutors: + format: int32 + type: integer + minExecutors: + format: int32 + type: integer + shuffleTrackingTimeout: + format: int64 + type: integer + type: object + executor: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + configMaps: + items: + properties: + name: + type: string + path: + type: string + required: + - name + - path + type: object + type: array + coreLimit: + type: string + coreRequest: + type: string + cores: + format: int32 + minimum: 1 + type: integer + deleteOnTermination: + type: boolean + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + envSecretKeyRefs: + additionalProperties: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + envVars: + additionalProperties: + type: string + type: object + gpu: + properties: + name: + type: string + quantity: + format: int64 + type: integer + required: + - name + - quantity + type: object + hostNetwork: + type: boolean + image: + type: string + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + instances: + format: int32 + minimum: 1 + type: integer + javaOptions: + type: string + labels: + additionalProperties: + type: string + type: object + memory: + type: string + memoryOverhead: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + schedulerName: + type: string + secrets: + items: + properties: + name: + type: string + path: + type: string + secretType: + type: string + required: + - name + - path + - secretType + type: object + type: array + securityContext: + properties: + fsGroup: + format: int64 + type: integer + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + sidecars: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + failureRetries: + format: int32 + type: integer + hadoopConf: + additionalProperties: + type: string + type: object + hadoopConfigMap: + type: string + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + mainApplicationFile: + type: string + mainClass: + type: string + memoryOverheadFactor: + type: string + mode: + enum: + - cluster + - client + type: string + monitoring: + properties: + exposeDriverMetrics: + type: boolean + exposeExecutorMetrics: + type: boolean + metricsProperties: + type: string + metricsPropertiesFile: + type: string + prometheus: + properties: + configFile: + type: string + configuration: + type: string + jmxExporterJar: + type: string + port: + format: int32 + maximum: 49151 + minimum: 1024 + type: integer + required: + - jmxExporterJar + type: object + required: + - exposeDriverMetrics + - exposeExecutorMetrics + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pythonVersion: + enum: + - "2" + - "3" + type: string + restartPolicy: + properties: + onFailureRetries: + format: int32 + minimum: 0 + type: integer + onFailureRetryInterval: + format: int64 + minimum: 1 + type: integer + onSubmissionFailureRetries: + format: int32 + minimum: 0 + type: integer + onSubmissionFailureRetryInterval: + format: int64 + minimum: 1 + type: integer + type: + enum: + - Never + - Always + - OnFailure + type: string + type: object + retryInterval: + format: int64 + type: integer + sparkConf: + additionalProperties: + type: string + type: object + sparkConfigMap: + type: string + sparkUIOptions: + properties: + ingressAnnotations: + additionalProperties: + type: string + type: object + ingressTLS: + items: + properties: + hosts: + items: + type: string + type: array + secretName: + type: string + type: object + type: array + servicePort: + format: int32 + type: integer + type: object + sparkVersion: + type: string + timeToLiveSeconds: + format: int64 + type: integer + type: + enum: + - Java + - Python + - Scala + - R + type: string + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - 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 + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + required: + - sources + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - driver + - executor + - sparkVersion + - type + type: object + status: + properties: + applicationState: + properties: + errorMessage: + type: string + state: + type: string + required: + - state + type: object + driverInfo: + properties: + podName: + type: string + webUIAddress: + type: string + webUIIngressAddress: + type: string + webUIIngressName: + type: string + webUIPort: + format: int32 + type: integer + webUIServiceName: + type: string + type: object + executionAttempts: + format: int32 + type: integer + executorState: + additionalProperties: + type: string + type: object + lastSubmissionAttemptTime: + format: date-time + nullable: true + type: string + sparkApplicationId: + type: string + submissionAttempts: + format: int32 + type: integer + submissionID: + type: string + terminationTime: + format: date-time + nullable: true + type: string + required: + - driverInfo + type: object + required: + - metadata + - spec + type: object + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (unknown) + api-approved.kubernetes.io: "https://github.com/kubernetes/kubernetes/pull/78458" + creationTimestamp: null + name: scheduledsparkapplications.sparkoperator.k8s.io +spec: + group: sparkoperator.k8s.io + names: + kind: ScheduledSparkApplication + listKind: ScheduledSparkApplicationList + plural: scheduledsparkapplications + shortNames: + - scheduledsparkapp + singular: scheduledsparkapplication + scope: Namespaced + versions: + - name: v1beta2 + served: true + storage: true + subresources: + status: { } + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + concurrencyPolicy: + type: string + failedRunHistoryLimit: + format: int32 + type: integer + schedule: + type: string + successfulRunHistoryLimit: + format: int32 + type: integer + suspend: + type: boolean + template: + properties: + arguments: + items: + type: string + type: array + batchScheduler: + type: string + batchSchedulerOptions: + properties: + priorityClassName: + type: string + queue: + type: string + type: object + deps: + properties: + files: + items: + type: string + type: array + jars: + items: + type: string + type: array + pyFiles: + items: + type: string + type: array + type: object + driver: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + configMaps: + items: + properties: + name: + type: string + path: + type: string + required: + - name + - path + type: object + type: array + coreLimit: + type: string + coreRequest: + type: string + cores: + format: int32 + minimum: 1 + type: integer + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + envSecretKeyRefs: + additionalProperties: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + envVars: + additionalProperties: + type: string + type: object + gpu: + properties: + name: + type: string + quantity: + format: int64 + type: integer + required: + - name + - quantity + type: object + hostNetwork: + type: boolean + image: + type: string + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + javaOptions: + type: string + kubernetesMaster: + type: string + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + memory: + type: string + memoryOverhead: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + podName: + pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*' + type: string + schedulerName: + type: string + secrets: + items: + properties: + name: + type: string + path: + type: string + secretType: + type: string + required: + - name + - path + - secretType + type: object + type: array + securityContext: + properties: + fsGroup: + format: int64 + type: integer + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAnnotations: + additionalProperties: + type: string + type: object + sidecars: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + dynamicAllocation: + properties: + enabled: + type: boolean + initialExecutors: + format: int32 + type: integer + maxExecutors: + format: int32 + type: integer + minExecutors: + format: int32 + type: integer + shuffleTrackingTimeout: + format: int64 + type: integer + type: object + executor: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + configMaps: + items: + properties: + name: + type: string + path: + type: string + required: + - name + - path + type: object + type: array + coreLimit: + type: string + coreRequest: + type: string + cores: + format: int32 + minimum: 1 + type: integer + deleteOnTermination: + type: boolean + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + envSecretKeyRefs: + additionalProperties: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + envVars: + additionalProperties: + type: string + type: object + gpu: + properties: + name: + type: string + quantity: + format: int64 + type: integer + required: + - name + - quantity + type: object + hostNetwork: + type: boolean + image: + type: string + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + instances: + format: int32 + minimum: 1 + type: integer + javaOptions: + type: string + labels: + additionalProperties: + type: string + type: object + memory: + type: string + memoryOverhead: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + schedulerName: + type: string + secrets: + items: + properties: + name: + type: string + path: + type: string + secretType: + type: string + required: + - name + - path + - secretType + type: object + type: array + securityContext: + properties: + fsGroup: + format: int64 + type: integer + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + sidecars: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + failureRetries: + format: int32 + type: integer + hadoopConf: + additionalProperties: + type: string + type: object + hadoopConfigMap: + type: string + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + mainApplicationFile: + type: string + mainClass: + type: string + memoryOverheadFactor: + type: string + mode: + enum: + - cluster + - client + type: string + monitoring: + properties: + exposeDriverMetrics: + type: boolean + exposeExecutorMetrics: + type: boolean + metricsProperties: + type: string + metricsPropertiesFile: + type: string + prometheus: + properties: + configFile: + type: string + configuration: + type: string + jmxExporterJar: + type: string + port: + format: int32 + maximum: 49151 + minimum: 1024 + type: integer + required: + - jmxExporterJar + type: object + required: + - exposeDriverMetrics + - exposeExecutorMetrics + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pythonVersion: + enum: + - "2" + - "3" + type: string + restartPolicy: + properties: + onFailureRetries: + format: int32 + minimum: 0 + type: integer + onFailureRetryInterval: + format: int64 + minimum: 1 + type: integer + onSubmissionFailureRetries: + format: int32 + minimum: 0 + type: integer + onSubmissionFailureRetryInterval: + format: int64 + minimum: 1 + type: integer + type: + enum: + - Never + - Always + - OnFailure + type: string + type: object + retryInterval: + format: int64 + type: integer + sparkConf: + additionalProperties: + type: string + type: object + sparkConfigMap: + type: string + sparkUIOptions: + properties: + ingressAnnotations: + additionalProperties: + type: string + type: object + ingressTLS: + items: + properties: + hosts: + items: + type: string + type: array + secretName: + type: string + type: object + type: array + servicePort: + format: int32 + type: integer + type: object + sparkVersion: + type: string + timeToLiveSeconds: + format: int64 + type: integer + type: + enum: + - Java + - Python + - Scala + - R + type: string + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - 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 + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + required: + - sources + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - driver + - executor + - sparkVersion + - type + type: object + required: + - schedule + - template + type: object + status: + properties: + lastRun: + format: date-time + nullable: true + type: string + lastRunName: + type: string + nextRun: + format: date-time + nullable: true + type: string + pastFailedRunNames: + items: + type: string + type: array + pastSuccessfulRunNames: + items: + type: string + type: array + reason: + type: string + scheduleState: + type: string + type: object + required: + - metadata + - spec + type: object +{{ end }} + +{{- end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/crds-v1beta1.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/crds-v1beta1.yaml new file mode 100755 index 000000000..d5085b370 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/crds-v1beta1.yaml @@ -0,0 +1,8443 @@ +{{- if semverCompare "<1.18-0" .Capabilities.KubeVersion.GitVersion -}} + +{{ if .Values.installCrds }} +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (unknown) + creationTimestamp: null + name: sparkapplications.sparkoperator.k8s.io +spec: + group: sparkoperator.k8s.io + names: + kind: SparkApplication + listKind: SparkApplicationList + plural: sparkapplications + shortNames: + - sparkapp + singular: sparkapplication + scope: Namespaced + validation: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + arguments: + items: + type: string + type: array + batchScheduler: + type: string + batchSchedulerOptions: + properties: + priorityClassName: + type: string + queue: + type: string + type: object + deps: + properties: + files: + items: + type: string + type: array + jars: + items: + type: string + type: array + pyFiles: + items: + type: string + type: array + type: object + driver: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + configMaps: + items: + properties: + name: + type: string + path: + type: string + required: + - name + - path + type: object + type: array + coreLimit: + type: string + coreRequest: + type: string + cores: + format: int32 + minimum: 1 + type: integer + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + envSecretKeyRefs: + additionalProperties: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + envVars: + additionalProperties: + type: string + type: object + gpu: + properties: + name: + type: string + quantity: + format: int64 + type: integer + required: + - name + - quantity + type: object + hostNetwork: + type: boolean + image: + type: string + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + javaOptions: + type: string + kubernetesMaster: + type: string + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + memory: + type: string + memoryOverhead: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + podName: + pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*' + type: string + schedulerName: + type: string + secrets: + items: + properties: + name: + type: string + path: + type: string + secretType: + type: string + required: + - name + - path + - secretType + type: object + type: array + securityContext: + properties: + fsGroup: + format: int64 + type: integer + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAnnotations: + additionalProperties: + type: string + type: object + sidecars: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + dynamicAllocation: + properties: + enabled: + type: boolean + initialExecutors: + format: int32 + type: integer + maxExecutors: + format: int32 + type: integer + minExecutors: + format: int32 + type: integer + shuffleTrackingTimeout: + format: int64 + type: integer + type: object + executor: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + configMaps: + items: + properties: + name: + type: string + path: + type: string + required: + - name + - path + type: object + type: array + coreLimit: + type: string + coreRequest: + type: string + cores: + format: int32 + minimum: 1 + type: integer + deleteOnTermination: + type: boolean + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + envSecretKeyRefs: + additionalProperties: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + envVars: + additionalProperties: + type: string + type: object + gpu: + properties: + name: + type: string + quantity: + format: int64 + type: integer + required: + - name + - quantity + type: object + hostNetwork: + type: boolean + image: + type: string + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + instances: + format: int32 + minimum: 1 + type: integer + javaOptions: + type: string + labels: + additionalProperties: + type: string + type: object + memory: + type: string + memoryOverhead: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + schedulerName: + type: string + secrets: + items: + properties: + name: + type: string + path: + type: string + secretType: + type: string + required: + - name + - path + - secretType + type: object + type: array + securityContext: + properties: + fsGroup: + format: int64 + type: integer + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + sidecars: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + failureRetries: + format: int32 + type: integer + hadoopConf: + additionalProperties: + type: string + type: object + hadoopConfigMap: + type: string + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + mainApplicationFile: + type: string + mainClass: + type: string + memoryOverheadFactor: + type: string + mode: + enum: + - cluster + - client + type: string + monitoring: + properties: + exposeDriverMetrics: + type: boolean + exposeExecutorMetrics: + type: boolean + metricsProperties: + type: string + metricsPropertiesFile: + type: string + prometheus: + properties: + configFile: + type: string + configuration: + type: string + jmxExporterJar: + type: string + port: + format: int32 + maximum: 49151 + minimum: 1024 + type: integer + required: + - jmxExporterJar + type: object + required: + - exposeDriverMetrics + - exposeExecutorMetrics + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pythonVersion: + enum: + - "2" + - "3" + type: string + restartPolicy: + properties: + onFailureRetries: + format: int32 + minimum: 0 + type: integer + onFailureRetryInterval: + format: int64 + minimum: 1 + type: integer + onSubmissionFailureRetries: + format: int32 + minimum: 0 + type: integer + onSubmissionFailureRetryInterval: + format: int64 + minimum: 1 + type: integer + type: + enum: + - Never + - Always + - OnFailure + type: string + type: object + retryInterval: + format: int64 + type: integer + sparkConf: + additionalProperties: + type: string + type: object + sparkConfigMap: + type: string + sparkUIOptions: + properties: + ingressAnnotations: + additionalProperties: + type: string + type: object + ingressTLS: + items: + properties: + hosts: + items: + type: string + type: array + secretName: + type: string + type: object + type: array + servicePort: + format: int32 + type: integer + type: object + sparkVersion: + type: string + timeToLiveSeconds: + format: int64 + type: integer + type: + enum: + - Java + - Python + - Scala + - R + type: string + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - 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 + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + required: + - sources + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - driver + - executor + - sparkVersion + - type + type: object + status: + properties: + applicationState: + properties: + errorMessage: + type: string + state: + type: string + required: + - state + type: object + driverInfo: + properties: + podName: + type: string + webUIAddress: + type: string + webUIIngressAddress: + type: string + webUIIngressName: + type: string + webUIPort: + format: int32 + type: integer + webUIServiceName: + type: string + type: object + executionAttempts: + format: int32 + type: integer + executorState: + additionalProperties: + type: string + type: object + lastSubmissionAttemptTime: + format: date-time + nullable: true + type: string + sparkApplicationId: + type: string + submissionAttempts: + format: int32 + type: integer + submissionID: + type: string + terminationTime: + format: date-time + nullable: true + type: string + required: + - driverInfo + type: object + required: + - metadata + - spec + type: object + subresources: + status: { } + versions: + - name: v1beta2 + served: true + storage: true + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: (unknown) + creationTimestamp: null + name: scheduledsparkapplications.sparkoperator.k8s.io +spec: + group: sparkoperator.k8s.io + names: + kind: ScheduledSparkApplication + listKind: ScheduledSparkApplicationList + plural: scheduledsparkapplications + shortNames: + - scheduledsparkapp + singular: scheduledsparkapplication + scope: Namespaced + validation: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + concurrencyPolicy: + type: string + failedRunHistoryLimit: + format: int32 + type: integer + schedule: + type: string + successfulRunHistoryLimit: + format: int32 + type: integer + suspend: + type: boolean + template: + properties: + arguments: + items: + type: string + type: array + batchScheduler: + type: string + batchSchedulerOptions: + properties: + priorityClassName: + type: string + queue: + type: string + type: object + deps: + properties: + files: + items: + type: string + type: array + jars: + items: + type: string + type: array + pyFiles: + items: + type: string + type: array + type: object + driver: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + configMaps: + items: + properties: + name: + type: string + path: + type: string + required: + - name + - path + type: object + type: array + coreLimit: + type: string + coreRequest: + type: string + cores: + format: int32 + minimum: 1 + type: integer + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + envSecretKeyRefs: + additionalProperties: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + envVars: + additionalProperties: + type: string + type: object + gpu: + properties: + name: + type: string + quantity: + format: int64 + type: integer + required: + - name + - quantity + type: object + hostNetwork: + type: boolean + image: + type: string + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + javaOptions: + type: string + kubernetesMaster: + type: string + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + memory: + type: string + memoryOverhead: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + podName: + pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*' + type: string + schedulerName: + type: string + secrets: + items: + properties: + name: + type: string + path: + type: string + secretType: + type: string + required: + - name + - path + - secretType + type: object + type: array + securityContext: + properties: + fsGroup: + format: int64 + type: integer + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAnnotations: + additionalProperties: + type: string + type: object + sidecars: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + dynamicAllocation: + properties: + enabled: + type: boolean + initialExecutors: + format: int32 + type: integer + maxExecutors: + format: int32 + type: integer + minExecutors: + format: int32 + type: integer + shuffleTrackingTimeout: + format: int64 + type: integer + type: object + executor: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + configMaps: + items: + properties: + name: + type: string + path: + type: string + required: + - name + - path + type: object + type: array + coreLimit: + type: string + coreRequest: + type: string + cores: + format: int32 + minimum: 1 + type: integer + deleteOnTermination: + type: boolean + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + envSecretKeyRefs: + additionalProperties: + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + type: object + envVars: + additionalProperties: + type: string + type: object + gpu: + properties: + name: + type: string + quantity: + format: int64 + type: integer + required: + - name + - quantity + type: object + hostNetwork: + type: boolean + image: + type: string + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + instances: + format: int32 + minimum: 1 + type: integer + javaOptions: + type: string + labels: + additionalProperties: + type: string + type: object + memory: + type: string + memoryOverhead: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + schedulerName: + type: string + secrets: + items: + properties: + name: + type: string + path: + type: string + secretType: + type: string + required: + - name + - path + - secretType + type: object + type: array + securityContext: + properties: + fsGroup: + format: int64 + type: integer + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + sidecars: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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 + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + failureRetries: + format: int32 + type: integer + hadoopConf: + additionalProperties: + type: string + type: object + hadoopConfigMap: + type: string + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + mainApplicationFile: + type: string + mainClass: + type: string + memoryOverheadFactor: + type: string + mode: + enum: + - cluster + - client + type: string + monitoring: + properties: + exposeDriverMetrics: + type: boolean + exposeExecutorMetrics: + type: boolean + metricsProperties: + type: string + metricsPropertiesFile: + type: string + prometheus: + properties: + configFile: + type: string + configuration: + type: string + jmxExporterJar: + type: string + port: + format: int32 + maximum: 49151 + minimum: 1024 + type: integer + required: + - jmxExporterJar + type: object + required: + - exposeDriverMetrics + - exposeExecutorMetrics + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pythonVersion: + enum: + - "2" + - "3" + type: string + restartPolicy: + properties: + onFailureRetries: + format: int32 + minimum: 0 + type: integer + onFailureRetryInterval: + format: int64 + minimum: 1 + type: integer + onSubmissionFailureRetries: + format: int32 + minimum: 0 + type: integer + onSubmissionFailureRetryInterval: + format: int64 + minimum: 1 + type: integer + type: + enum: + - Never + - Always + - OnFailure + type: string + type: object + retryInterval: + format: int64 + type: integer + sparkConf: + additionalProperties: + type: string + type: object + sparkConfigMap: + type: string + sparkUIOptions: + properties: + ingressAnnotations: + additionalProperties: + type: string + type: object + ingressTLS: + items: + properties: + hosts: + items: + type: string + type: array + secretName: + type: string + type: object + type: array + servicePort: + format: int32 + type: integer + type: object + sparkVersion: + type: string + timeToLiveSeconds: + format: int64 + type: integer + type: + enum: + - Java + - Python + - Scala + - R + type: string + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - 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 + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - 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 + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + required: + - sources + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - driver + - executor + - sparkVersion + - type + type: object + required: + - schedule + - template + type: object + status: + properties: + lastRun: + format: date-time + nullable: true + type: string + lastRunName: + type: string + nextRun: + format: date-time + nullable: true + type: string + pastFailedRunNames: + items: + type: string + type: array + pastSuccessfulRunNames: + items: + type: string + type: array + reason: + type: string + scheduleState: + type: string + type: object + required: + - metadata + - spec + type: object + subresources: + status: { } + versions: + - name: v1beta2 + served: true + storage: true +{{ end }} + +{{- end }} \ No newline at end of file diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-operator-deployment.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-operator-deployment.yaml new file mode 100755 index 000000000..713ee1025 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-operator-deployment.yaml @@ -0,0 +1,114 @@ +# If the admission webhook is enabled, then a post-install step is required +# to generate and install the secret in the operator namespace. + +# In the post-install hook, the token corresponding to the operator service account +# is used to authenticate with the Kubernetes API server to install the secret bundle. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "sparkoperator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + app.kubernetes.io/version: {{ .Values.image.tag }} + strategy: + type: Recreate + template: + metadata: + {{- if or .Values.podAnnotations .Values.enableMetrics }} + annotations: + {{- if .Values.enableMetrics }} + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.metricsPort }}" + prometheus.io/path: {{ .Values.metricsEndpoint }} + {{- end }} + {{- if .Values.podAnnotations }} +{{ toYaml .Values.podAnnotations | trim | indent 8 }} + {{- end }} + {{- end }} + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + app.kubernetes.io/version: {{ .Values.image.tag }} + spec: + serviceAccountName: {{ include "sparkoperator.serviceAccountName" . }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | trim | indent 8 }} + {{- if .Values.enableWebhook }} + volumes: + - name: webhook-certs + secret: + secretName: spark-webhook-certs + {{- end }} + containers: + - name: sparkoperator + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy}} + {{- if .Values.securityContext }} + securityContext: + {{- range $securityPolicy, $value := .Values.securityContext }} + {{ $securityPolicy }}: {{ $value }} + {{- end }} + {{- end }} + {{- if .Values.enableWebhook }} + volumeMounts: + - name: webhook-certs + mountPath: /etc/webhook-certs + {{- end }} + {{- if .Values.enableMetrics }} + ports: + - containerPort: {{ .Values.metricsPort }} + {{ end }} + args: + - -v={{ .Values.logLevel }} + - -namespace={{ .Values.sparkJobNamespace }} + - -ingress-url-format={{ .Values.ingressUrlFormat }} + - -controller-threads={{ .Values.controllerThreads }} + - -resync-interval={{ .Values.resyncInterval }} + - -logtostderr + {{- if .Values.enableBatchScheduler }} + - -enable-batch-scheduler={{ .Values.enableBatchScheduler }} + {{- end }} + {{- if .Values.enableMetrics }} + - -enable-metrics=true + - -metrics-labels=app_type + - -metrics-port={{ .Values.metricsPort }} + - -metrics-endpoint={{ .Values.metricsEndpoint }} + - -metrics-prefix={{ .Values.metricsPrefix }} + {{- end }} + {{- if .Values.enableWebhook }} + - -enable-webhook=true + - -webhook-svc-namespace={{ .Release.Namespace }} + - -webhook-port={{ .Values.webhookPort }} + - -webhook-svc-name={{ .Release.Name }}-webhook + - -webhook-config-name={{ include "sparkoperator.fullname" . }}-webhook-config + - -webhook-namespace-selector={{ .Values.webhookNamespaceSelector }} + {{- end }} + {{- if .Values.enableResourceQuotaEnforcement }} + - -enable-resource-quota-enforcement={{ .Values.enableResourceQuotaEnforcement }} + {{- end }} + {{- if .Values.leaderElection.enable }} + - -leader-election={{ .Values.leaderElection.enable }} + - -leader-election-lock-namespace={{ include "sparkoperator.leaderElectionLockNamespace" . }} + - -leader-election-lock-name={{ .Values.leaderElection.lockName }} + {{- end }} + {{- if .Values.resources }} + resources: +{{ toYaml .Values.resources | indent 10 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-operator-rbac.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-operator-rbac.yaml new file mode 100755 index 000000000..53eba0131 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-operator-rbac.yaml @@ -0,0 +1,70 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "sparkoperator.fullname" . }}-cr + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["*"] +- apiGroups: [""] + resources: ["services", "configmaps", "secrets"] + verbs: ["create", "get", "delete", "update"] +- apiGroups: ["extensions"] + resources: ["ingresses"] + verbs: ["create", "get", "delete"] +- apiGroups: [""] + resources: ["nodes"] + verbs: ["get"] +- apiGroups: [""] + resources: ["events"] + verbs: ["create", "update", "patch"] +- apiGroups: [""] + resources: ["resourcequotas"] + verbs: ["get", "list", "watch"] +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "get", "update", "delete"] +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations", "validatingwebhookconfigurations"] + verbs: ["create", "get", "update", "delete"] +- apiGroups: ["sparkoperator.k8s.io"] + resources: ["sparkapplications", "scheduledsparkapplications", "sparkapplications/status", "scheduledsparkapplications/status"] + verbs: ["*"] + {{- if .Values.enableBatchScheduler }} + # This api resources below is configured for the `volcano` batch scheduler. +- apiGroups: ["scheduling.incubator.k8s.io", "scheduling.sigs.dev", "scheduling.volcano.sh"] + resources: ["podgroups"] + verbs: ["*"] + {{- end }} + {{ if .Values.enableWebhook }} + # This permission is granted only if the webhook is enabled +- apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["delete"] + {{- end }} + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "sparkoperator.fullname" . }}-crb + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +subjects: + - kind: ServiceAccount + name: {{ include "sparkoperator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "sparkoperator.fullname" . }}-cr + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-operator-serviceaccount.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-operator-serviceaccount.yaml new file mode 100755 index 000000000..e3874e927 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-operator-serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccounts.sparkoperator.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "sparkoperator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-rbac.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-rbac.yaml new file mode 100755 index 000000000..fa066053d --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-rbac.yaml @@ -0,0 +1,44 @@ +{{- if and (.Values.rbac.create) (ne .Values.sparkJobNamespace "") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: {{ .Values.sparkJobNamespace }} + name: spark-role + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: + - "" # "" indicates the core API group + resources: + - "pods" + verbs: + - "*" +- apiGroups: + - "" # "" indicates the core API group + resources: + - "services" + verbs: + - "*" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: spark-role-binding + namespace: {{ .Values.sparkJobNamespace }} + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +subjects: +- kind: ServiceAccount + name: {{ include "spark.serviceAccountName" . }} + namespace: {{ .Values.sparkJobNamespace }} +roleRef: + kind: Role + name: spark-role + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-serviceaccount.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-serviceaccount.yaml new file mode 100755 index 000000000..bb0e55ea6 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/spark-serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccounts.spark.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "spark.serviceAccountName" . }} + namespace: {{ .Values.sparkJobNamespace }} + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/webhook-cleanup-job.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/webhook-cleanup-job.yaml new file mode 100755 index 000000000..074c440cf --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/webhook-cleanup-job.yaml @@ -0,0 +1,55 @@ +{{ if .Values.enableWebhook }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "sparkoperator.fullname" . }}-webhook-cleanup + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-delete, pre-upgrade + "helm.sh/hook-delete-policy": hook-succeeded + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + template: + metadata: + name: {{ include "sparkoperator.fullname" . }}-webhook-cleanup + {{- if .Values.istio.enabled }} + annotations: + "sidecar.istio.io/inject": "false" + {{- end }} + spec: + serviceAccountName: {{ include "sparkoperator.serviceAccountName" . }} + restartPolicy: OnFailure + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | trim | indent 8 }} + containers: + - name: clean-secret + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy}} + {{- if .Values.securityContext }} + securityContext: + {{- range $securityPolicy, $value := .Values.securityContext }} + {{ $securityPolicy }}: {{ $value }} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-c" + - "curl -ik \ + -X DELETE \ + -H \"Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" \ + -H \"Accept: application/json\" \ + -H \"Content-Type: application/json\" \ + https://kubernetes.default.svc/api/v1/namespaces/{{ .Release.Namespace }}/secrets/spark-webhook-certs \ + && \ + curl -ik \ + -X DELETE \ + -H \"Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\" \ + -H \"Accept: application/json\" \ + -H \"Content-Type: application/json\" \ + --data \"{\\\"kind\\\":\\\"DeleteOptions\\\",\\\"apiVersion\\\":\\\"batch/v1\\\",\\\"propagationPolicy\\\":\\\"Foreground\\\"}\" \ + https://kubernetes.default.svc/apis/batch/v1/namespaces/{{ .Release.Namespace }}/jobs/{{ include "sparkoperator.fullname" . }}-webhook-init" +{{ end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/webhook-init-job.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/webhook-init-job.yaml new file mode 100755 index 000000000..3f760bb46 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/webhook-init-job.yaml @@ -0,0 +1,36 @@ +{{ if .Values.enableWebhook }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "sparkoperator.fullname" . }}-webhook-init + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + template: + metadata: + name: {{ include "sparkoperator.fullname" . }}-webhook-init + {{- if .Values.istio.enabled }} + annotations: + "sidecar.istio.io/inject": "false" + {{- end }} + spec: + serviceAccountName: {{ include "sparkoperator.serviceAccountName" . }} + restartPolicy: OnFailure + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | trim | indent 8 }} + containers: + - name: main + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy}} + {{- if .Values.securityContext }} + securityContext: + {{- range $securityPolicy, $value := .Values.securityContext }} + {{ $securityPolicy }}: {{ $value }} + {{- end }} + {{- end }} + command: ["/usr/bin/gencerts.sh", "-n", "{{ .Release.Namespace }}", "-s", "{{ .Release.Name }}-webhook", "-p"] +{{ end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/webhook-service.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/webhook-service.yaml new file mode 100755 index 000000000..9055f826a --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/templates/webhook-service.yaml @@ -0,0 +1,20 @@ +{{ if .Values.enableWebhook }} +kind: Service +apiVersion: v1 +metadata: + name: {{ .Release.Name }}-webhook + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + helm.sh/chart: {{ include "sparkoperator.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + ports: + - port: 443 + targetPort: {{ .Values.webhookPort }} + name: webhook + selector: + app.kubernetes.io/name: {{ include "sparkoperator.name" . }} + app.kubernetes.io/version: {{ .Values.image.tag }} +{{ end }} diff --git a/deploy/charts/fedlearner-stack/charts/sparkoperator/values.yaml b/deploy/charts/fedlearner-stack/charts/sparkoperator/values.yaml new file mode 100755 index 000000000..6c69b9be1 --- /dev/null +++ b/deploy/charts/fedlearner-stack/charts/sparkoperator/values.yaml @@ -0,0 +1,90 @@ +image: + repository: registry.cn-beijing.aliyuncs.com/fedlearner/spark-operator + pullPolicy: IfNotPresent + tag: v1beta2-1.2.0-3.0.0 + +imagePullSecrets: [] + +rbac: + create: true + +serviceAccounts: + spark: + create: true + name: spark + sparkoperator: + create: true + name: + +sparkJobNamespace: default +installCrds: true +controllerThreads: 10 +resyncInterval: 30 +ingressUrlFormat: "" +logLevel: 6 + +securityContext: {} + +enableWebhook: true +webhookPort: 8080 +## The webhook will only operate on namespaces with this label, specified in the form key1=value1,key2=value2 +## empty string will operate on all namespaces +webhookNamespaceSelector: "" + +enableMetrics: true +metricsPort: 10254 +metricsEndpoint: "/metrics" +metricsPrefix: "" + +## Node labels for pod assignment +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +## +nodeSelector: {} + +## Tolerations for the sparkoperator deployment +## +## Example: +## - key: "toleration=key" +## operator: "Equal" +## value: "value" +## effect: "NoSchedule" +## +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] + +podAnnotations: {} + +## Resources for the sparkoperator deployment +## Ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +## +resources: + limits: + cpu: "1" + memory: "1Gi" + requests: + cpu: "1" + memory: "1Gi" + +## Whether to enable batch scheduler for pod scheduling, +## if enabled, end user can specify batch scheduler name in spark application. +enableBatchScheduler: false + +## Whether to enable the ResourceQuota enforcement for SparkApplication resources. +## Requires the webhook to be enabled by setting enableWebhook to true. +## Ref: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/master/docs/user-guide.md#enabling-resource-quota-enforcement. +enableResourceQuotaEnforcement: false + +## Whether to enable leader election when the operator Deployment has more than one replica. +## Only applicable when `replicas` is set to a value greater than 1. +## Ref: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/master/docs/user-guide.md#enabling-leader-election-for-high-availability. +leaderElection: + enable: true + lockName: "spark-operator-lock" + ## Optionally store the lock in another namespace. Defaults to operator's namespace + # lockNamespace: "" +replicas: 1 + +## When using istio Jobs need to run without a sidecar to properly terminate +istio: + enabled: false diff --git a/deploy/charts/fedlearner-stack/values.yaml b/deploy/charts/fedlearner-stack/values.yaml index cfcd8e9f3..2b096ae60 100644 --- a/deploy/charts/fedlearner-stack/values.yaml +++ b/deploy/charts/fedlearner-stack/values.yaml @@ -1,22 +1,4 @@ -nfs-server-provisioner: - enabled: true - -nfs-client-provisioner: - enabled: false - nfs: - path: / - mountOptions: - - vers=3 - - nolock,tcp,noresvport - - storageClass: - name: nfs - - image: - repository: registry.cn-beijing.aliyuncs.com/fedlearner/nfs-client-provisioner - tag: v3.1.0-k8s1.11 - pullPolicy: IfNotPresent mysql: enabled: true @@ -79,3 +61,34 @@ etcd: enabled: false persistence: storageClass: nfs + +sparkoperator: + enabled: false + + serviceAccounts: + spark: + create: true + name: spark + + image: + repository: registry.cn-beijing.aliyuncs.com/fedlearner/spark-operator + pullPolicy: IfNotPresent + tag: v1beta2-1.2.0-3.0.0_patch2 + + sparkJobNamespace: default + installCrds: true + logLevel: 4 + + enableWebhook: true + webhookPort: 8080 + + resources: + limits: + cpu: "1" + memory: "1Gi" + requests: + cpu: "1" + memory: "1Gi" + + leaderElection: + enable: true diff --git a/deploy/charts/fedlearner/charts/fedlearner-apiserver/templates/deployment.yaml b/deploy/charts/fedlearner/charts/fedlearner-apiserver/templates/deployment.yaml index e6135bcc9..a8f575dee 100644 --- a/deploy/charts/fedlearner/charts/fedlearner-apiserver/templates/deployment.yaml +++ b/deploy/charts/fedlearner/charts/fedlearner-apiserver/templates/deployment.yaml @@ -20,6 +20,10 @@ spec: labels: app: fedlearner-apiserver spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} hostNetwork: {{ .Values.hostNetwork }} containers: - args: @@ -31,6 +35,7 @@ spec: name: fedlearner-apiserver ports: - containerPort: 8101 + protocol: TCP resources: {{- toYaml .Values.resources | nindent 12 }} restartPolicy: Always diff --git a/deploy/charts/fedlearner/charts/fedlearner-operator/templates/deployment.yaml b/deploy/charts/fedlearner/charts/fedlearner-operator/templates/deployment.yaml index 02ecf7074..188973503 100644 --- a/deploy/charts/fedlearner/charts/fedlearner-operator/templates/deployment.yaml +++ b/deploy/charts/fedlearner/charts/fedlearner-operator/templates/deployment.yaml @@ -20,6 +20,10 @@ spec: labels: app: fedlearner-operator spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} containers: - args: - --port=8100 @@ -41,6 +45,7 @@ spec: name: fedlearner-operator ports: - containerPort: 8100 + protocol: TCP resources: {{- toYaml .Values.resources | nindent 12 }} restartPolicy: Always diff --git a/deploy/charts/fedlearner/charts/fedlearner-operator/templates/fedlearner.k8s.io_flapps_v1.yaml b/deploy/charts/fedlearner/charts/fedlearner-operator/templates/fedlearner.k8s.io_flapps_v1.yaml new file mode 100644 index 000000000..7e1cbac25 --- /dev/null +++ b/deploy/charts/fedlearner/charts/fedlearner-operator/templates/fedlearner.k8s.io_flapps_v1.yaml @@ -0,0 +1,6444 @@ +{{- if .Values.installCRD }} +{{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.3.0 + api-approved.kubernetes.io: "https://github.com/kubernetes/kubernetes/pull/78458" + creationTimestamp: null + name: flapps.fedlearner.k8s.io +spec: + group: fedlearner.k8s.io + names: + kind: FLApp + listKind: FLAppList + plural: flapps + singular: flapp + scope: Namespaced + versions: + - name: v1alpha1 + served: true + storage: true + subresources: + status: { } + additionalPrinterColumns: + - jsonPath: .status.appState + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: START + type: date + - jsonPath: .status.completionTime + name: END + type: date + schema: + openAPIV3Schema: + description: FLApp is a specification for a FLApp resource + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec is the spec for FLApp + properties: + activeDeadlineSeconds: + description: Specifies the duration (in seconds) since startTime during + which the job can remain active before it is terminated. Must be a + positive integer. This setting applies only to pods where restartPolicy + is OnFailure or Always. Defaults to infinite + format: int64 + type: integer + backoffLimit: + description: Number of retries before marking this job as failed. Defaults + to 5. + format: int32 + type: integer + cleanPodPolicy: + description: Defines the policy for cleaning up pods after the FLApp + completes. Defaults to All. + type: string + flReplicaSpecs: + additionalProperties: + description: ReplicaSpec is a description of the replica + properties: + chiefResources: + description: ChiefResources describes the resource requirements + of worker0. Default to nil. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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/' + type: object + type: object + pair: + description: Pair, when set to true, controller will try to pair + it with peer controller. Defaults to false. + type: boolean + replicas: + description: Replicas is the desired number of replicas of the + given template. Defaults to 0. + format: int32 + type: integer + restartPolicy: + description: Restart policy for all replicas within the app. One + of Always, OnFailure, Never and ExitCode. Default to OnFailure. + type: string + template: + description: Template is the object that describes the pod that + will be created for this replica. + properties: + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + spec: + description: 'Specification of the desired behavior of the + pod. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' + properties: + activeDeadlineSeconds: + description: Optional duration in seconds the pod may + be active on the node relative to StartTime before the + system will actively try to mark it failed and kill + associated containers. Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a + node that violates one or more of the expressions. + The node that is most preferred is the one with + the greatest sum of weights, i.e. for each node + that meets all of the scheduling requirements + (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by + iterating through the elements of this field + and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) + with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling + term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: Represents a key's + relationship to a set of values. + Valid operators are In, NotIn, + Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: 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. + If the operator is Gt or Lt, + the values array must have a + single element, which will be + interpreted as an integer. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: Represents a key's + relationship to a set of values. + Valid operators are In, NotIn, + Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: 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. + If the operator is Gt or Lt, + the values array must have a + single element, which will be + interpreted as an integer. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in + the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, + the pod will not be scheduled onto the node. + If the affinity requirements specified by this + field cease to be met at some point during pod + execution (e.g. due to an update), the system + may or may not try to eventually evict the pod + from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector + term matches no objects. The requirements + of them are ANDed. The TopologySelectorTerm + type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: Represents a key's + relationship to a set of values. + Valid operators are In, NotIn, + Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: 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. + If the operator is Gt or Lt, + the values array must have a + single element, which will be + interpreted as an integer. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: Represents a key's + relationship to a set of values. + Valid operators are In, NotIn, + Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: 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. + If the operator is Gt or Lt, + the values array must have a + single element, which will be + interpreted as an integer. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a + node that violates one or more of the expressions. + The node that is most preferred is the one with + the greatest sum of weights, i.e. for each node + that meets all of the scheduling requirements + (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by + iterating through the elements of this field + and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; + the node(s) with the highest sum are the most + preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set + of resources, in this case pods. + 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" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where + co-located is defined as running on + a node whose value of the label with + key topologyKey matches that of any + node on which any of the selected + pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in + the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, + the pod will not be scheduled onto the node. + If the affinity requirements specified by this + field cease to be met at some point during pod + execution (e.g. due to a pod label update), + the system may or may not try to eventually + evict the pod from its node. When there are + multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the + given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) + with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on + which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + 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" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity + expressions specified by this field, but it + may choose a node that violates one or more + of the expressions. The node that is most preferred + is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a + sum by iterating through the elements of this + field and adding "weight" to the sum if the + node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest + sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set + of resources, in this case pods. + 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" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where + co-located is defined as running on + a node whose value of the label with + key topologyKey matches that of any + node on which any of the selected + pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in + the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements + specified by this field are not met at scheduling + time, the pod will not be scheduled onto the + node. If the anti-affinity requirements specified + by this field cease to be met at some point + during pod execution (e.g. due to a pod label + update), the system may or may not try to eventually + evict the pod from its node. When there are + multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the + given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) + with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on + which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + 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" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: List of containers belonging to the pod. + Containers cannot currently be added or removed. There + must be at least one container in a Pod. Cannot be updated. + items: + description: A single application container that you + want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker + image''s CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using + the container''s environment. If a variable cannot + be resolved, the reference in the input string + will be unchanged. The $(VAR_NAME) syntax can + be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within + a shell. The docker image''s ENTRYPOINT is used + if this is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. + If a variable cannot be resolved, the reference + in the input string will be unchanged. The $(VAR_NAME) + syntax can be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set + in the container. Cannot be updated. + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined + environment variables in the container and + any service environment variables. If a + variable cannot be resolved, the reference + in the input string will be unchanged. The + $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and + requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment + variables in the container. The keys defined within + a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container + is starting. When a key exists in multiple sources, + the value associated with the last source will + take precedence. Values defined by an Env with + a duplicate key will take precedence. Cannot be + updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a + C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config + management to default or override container images + in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, + Never, IfNotPresent. Defaults to Always if :latest + tag is specified, or IfNotPresent otherwise. Cannot + be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system + should take in response to container lifecycle + events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately + after a container is created. If the handler + fails, the container is terminated and restarted + according to its restart policy. Other management + of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the + action to take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet + supported TODO: implement a realistic + TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately + before a container is terminated due to an + API request or management event such as liveness/startup + probe failure, preemption, resource contention, + etc. The handler is not called if the container + crashes or exits. The reason for termination + is passed to the handler. The Pod''s termination + grace period countdown begins before the PreStop + hooked is executed. Regardless of the outcome + of the handler, the container will eventually + terminate within the Pod''s termination grace + period. Other management of the container + blocks until the hook completes or until the + termination grace period is reached. More + info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the + action to take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet + supported TODO: implement a realistic + TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. + Container will be restarted if the probe fails. + 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. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + 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 + name: + description: Name of the container specified as + a DNS_LABEL. Each container in a pod must have + a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional + information about the network connections a container + uses, but is primarily informational. Not specifying + a port here DOES NOT prevent that port from being + exposed. Any port which is listening on the default + "0.0.0.0" address inside a container will be accessible + from the network. Cannot be updated. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: Number of port to expose on the + pod's IP address. This must be a valid port + number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: Number of port to expose on the + host. If specified, this must be a valid + port number, 0 < x < 65536. If HostNetwork + is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an + IANA_SVC_NAME and unique within the pod. + Each named port in a pod must have a unique + name. Name for the port that can be referred + to by services. + type: string + protocol: + description: Protocol for port. Must be UDP, + TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service + readiness. Container will be removed from service + endpoints if the probe fails. 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. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + 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/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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/' + type: object + type: object + securityContext: + description: 'Security options the pod should run + with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls + whether a process can gain more privileges + than its parent process. This bool directly + controls if the no_new_privs flag will be + set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run + as Privileged 2) has CAP_SYS_ADMIN' + type: boolean + capabilities: + description: The capabilities to add/drop when + running containers. Defaults to the default + set of capabilities granted by the container + runtime. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. + Processes in privileged containers are essentially + equivalent to root on the host. Defaults to + false. + type: boolean + procMount: + description: procMount denotes the type of proc + mount to use for the containers. The default + is DefaultProcMount which uses the container + runtime defaults for readonly paths and masked + paths. This requires the ProcMountType feature + flag to be enabled. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of + the container process. Uses runtime default + if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must + run as a non-root user. If true, the Kubelet + will validate the image at runtime to ensure + that it does not run as UID 0 (root) and fail + to start the container if it does. If unset + or false, no such validation will be performed. + May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of + the container process. Defaults to user specified + in image metadata if unspecified. May also + be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied + to the container. If unspecified, the container + runtime will allocate a random SELinux context + for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options + from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where + the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName + field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + runAsUserName: + description: The UserName in Windows to + run the entrypoint of the container process. + Defaults to the user specified in image + metadata if unspecified. May also be set + in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, + the value specified in SecurityContext + takes precedence. + type: string + 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' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + 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 + stdin: + description: Whether this container should allocate + a buffer for stdin in the container runtime. If + this is not set, reads from stdin in the container + will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should + close the stdin channel after it has been opened + by a single attach. When stdin is true the stdin + stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is + opened on container start, is empty until the + first client attaches to stdin, and then remains + open and accepts data until the client disconnects, + at which time stdin is closed and remains closed + until the container is restarted. If this flag + is false, a container processes that reads from + stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to + which the container''s termination message will + be written is mounted into the container''s filesystem. + Message written is intended to be brief final + status, such as an assertion failure message. + Will be truncated by the node if greater than + 4096 bytes. The total message length across all + containers will be limited to 12kb. Defaults to + /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message + should be populated. File will use the contents + of terminationMessagePath to populate the container + status message on both success and failure. FallbackToLogsOnError + will use the last chunk of container log output + if the termination message file is empty and the + container exited with an error. The log output + is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate + a TTY for itself, also requires 'stdin' to be + true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block + devices to be used by the container. + items: + description: volumeDevice describes a mapping + of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside + of the container that the device will be + mapped to. + type: string + name: + description: name must match the name of a + persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's + filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting + of a Volume within a container. + properties: + mountPath: + description: Path within the container at + which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how + mounts are propagated from the host to container + and the other way around. When not set, + MountPropagationNone is used. This field + is beta in 1.10. + type: string + name: + description: This must match the Name of a + Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults + to false. + type: boolean + subPath: + description: Path within the volume from which + the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume + from which the container's volume should + be mounted. Behaves similarly to SubPath + but environment variable references $(VAR_NAME) + are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not + specified, the container runtime's default will + be used, which might be configured in the container + image. Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: Specifies the DNS parameters of a pod. Parameters + specified here will be merged to the generated DNS configuration + based on DNSPolicy. + properties: + nameservers: + description: A list of DNS name server IP addresses. + This will be appended to the base nameservers generated + from DNSPolicy. Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: A list of DNS resolver options. This + will be merged with the base options generated from + DNSPolicy. Duplicated entries will be removed. Resolution + options given in Options will override those that + appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: A list of DNS search domains for host-name + lookup. This will be appended to the base search + paths generated from DNSPolicy. Duplicated search + paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: Set DNS policy for the pod. Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', + 'Default' or 'None'. DNS parameters given in DNSConfig + will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you + have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: 'EnableServiceLinks indicates whether information + about services should be injected into pod''s environment + variables, matching the syntax of Docker links. Optional: + Defaults to true.' + type: boolean + ephemeralContainers: + description: List of ephemeral containers run in this + pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. + This list cannot be specified when creating a pod, and + it cannot be modified by updating the pod spec. In order + to add an ephemeral container to an existing pod, use + the pod's ephemeralcontainers subresource. This field + is alpha-level and is only honored by servers that enable + the EphemeralContainers feature. + items: + description: An EphemeralContainer is a container that + may be added temporarily to an existing pod for user-initiated + activities such as debugging. Ephemeral containers + have no resource or scheduling guarantees, and they + will not be restarted when they exit or when a pod + is removed or restarted. If an ephemeral container + causes a pod to exceed its resource allocation, the + pod may be evicted. Ephemeral containers may not be + added by directly updating the pod spec. They must + be added via the pod's ephemeralcontainers subresource, + and they will appear in the pod spec once added. This + is an alpha feature enabled by the EphemeralContainers + feature flag. + properties: + args: + description: 'Arguments to the entrypoint. The docker + image''s CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using + the container''s environment. If a variable cannot + be resolved, the reference in the input string + will be unchanged. The $(VAR_NAME) syntax can + be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within + a shell. The docker image''s ENTRYPOINT is used + if this is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. + If a variable cannot be resolved, the reference + in the input string will be unchanged. The $(VAR_NAME) + syntax can be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set + in the container. Cannot be updated. + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined + environment variables in the container and + any service environment variables. If a + variable cannot be resolved, the reference + in the input string will be unchanged. The + $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and + requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment + variables in the container. The keys defined within + a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container + is starting. When a key exists in multiple sources, + the value associated with the last source will + take precedence. Values defined by an Env with + a duplicate key will take precedence. Cannot be + updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a + C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, + Never, IfNotPresent. Defaults to Always if :latest + tag is specified, or IfNotPresent otherwise. Cannot + be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: 'PostStart is called immediately + after a container is created. If the handler + fails, the container is terminated and restarted + according to its restart policy. Other management + of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the + action to take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet + supported TODO: implement a realistic + TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately + before a container is terminated due to an + API request or management event such as liveness/startup + probe failure, preemption, resource contention, + etc. The handler is not called if the container + crashes or exits. The reason for termination + is passed to the handler. The Pod''s termination + grace period countdown begins before the PreStop + hooked is executed. Regardless of the outcome + of the handler, the container will eventually + terminate within the Pod''s termination grace + period. Other management of the container + blocks until the hook completes or until the + termination grace period is reached. More + info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the + action to take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet + supported TODO: implement a realistic + TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + 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 + name: + description: Name of the ephemeral container specified + as a DNS_LABEL. This name must be unique among + all containers, init containers and ephemeral + containers. + type: string + ports: + description: Ports are not allowed for ephemeral + containers. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: Number of port to expose on the + pod's IP address. This must be a valid port + number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: Number of port to expose on the + host. If specified, this must be a valid + port number, 0 < x < 65536. If HostNetwork + is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an + IANA_SVC_NAME and unique within the pod. + Each named port in a pod must have a unique + name. Name for the port that can be referred + to by services. + type: string + protocol: + description: Protocol for port. Must be UDP, + TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + - protocol + type: object + type: array + readinessProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + 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: Resources are not allowed for ephemeral + containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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/' + type: object + type: object + securityContext: + description: SecurityContext is not allowed for + ephemeral containers. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls + whether a process can gain more privileges + than its parent process. This bool directly + controls if the no_new_privs flag will be + set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run + as Privileged 2) has CAP_SYS_ADMIN' + type: boolean + capabilities: + description: The capabilities to add/drop when + running containers. Defaults to the default + set of capabilities granted by the container + runtime. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. + Processes in privileged containers are essentially + equivalent to root on the host. Defaults to + false. + type: boolean + procMount: + description: procMount denotes the type of proc + mount to use for the containers. The default + is DefaultProcMount which uses the container + runtime defaults for readonly paths and masked + paths. This requires the ProcMountType feature + flag to be enabled. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of + the container process. Uses runtime default + if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must + run as a non-root user. If true, the Kubelet + will validate the image at runtime to ensure + that it does not run as UID 0 (root) and fail + to start the container if it does. If unset + or false, no such validation will be performed. + May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of + the container process. Defaults to user specified + in image metadata if unspecified. May also + be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied + to the container. If unspecified, the container + runtime will allocate a random SELinux context + for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options + from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where + the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName + field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + runAsUserName: + description: The UserName in Windows to + run the entrypoint of the container process. + Defaults to the user specified in image + metadata if unspecified. May also be set + in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, + the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + 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 + stdin: + description: Whether this container should allocate + a buffer for stdin in the container runtime. If + this is not set, reads from stdin in the container + will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should + close the stdin channel after it has been opened + by a single attach. When stdin is true the stdin + stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is + opened on container start, is empty until the + first client attaches to stdin, and then remains + open and accepts data until the client disconnects, + at which time stdin is closed and remains closed + until the container is restarted. If this flag + is false, a container processes that reads from + stdin will never receive an EOF. Default is false + type: boolean + targetContainerName: + description: If set, the name of the container from + PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces + (IPC, PID, etc) of this container. If not set + then the ephemeral container is run in whatever + namespaces are shared for the pod. Note that the + container runtime must support this feature. + type: string + terminationMessagePath: + description: 'Optional: Path at which the file to + which the container''s termination message will + be written is mounted into the container''s filesystem. + Message written is intended to be brief final + status, such as an assertion failure message. + Will be truncated by the node if greater than + 4096 bytes. The total message length across all + containers will be limited to 12kb. Defaults to + /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message + should be populated. File will use the contents + of terminationMessagePath to populate the container + status message on both success and failure. FallbackToLogsOnError + will use the last chunk of container log output + if the termination message file is empty and the + container exited with an error. The log output + is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate + a TTY for itself, also requires 'stdin' to be + true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block + devices to be used by the container. + items: + description: volumeDevice describes a mapping + of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside + of the container that the device will be + mapped to. + type: string + name: + description: name must match the name of a + persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's + filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting + of a Volume within a container. + properties: + mountPath: + description: Path within the container at + which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how + mounts are propagated from the host to container + and the other way around. When not set, + MountPropagationNone is used. This field + is beta in 1.10. + type: string + name: + description: This must match the Name of a + Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults + to false. + type: boolean + subPath: + description: Path within the volume from which + the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume + from which the container's volume should + be mounted. Behaves similarly to SubPath + but environment variable references $(VAR_NAME) + are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not + specified, the container runtime's default will + be used, which might be configured in the container + image. Cannot be updated. + type: string + required: + - name + type: object + type: array + hostAliases: + description: HostAliases is an optional list of hosts + and IPs that will be injected into the pod's hosts file + if specified. This is only valid for non-hostNetwork + pods. + items: + description: HostAlias holds the mapping between IP + and hostnames that will be injected as an entry in + the pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + hostIPC: + description: 'Use the host''s ipc namespace. Optional: + Default to false.' + type: boolean + hostNetwork: + description: Host networking requested for this pod. Use + the host's network namespace. If this option is set, + the ports that will be used must be specified. Default + to false. + type: boolean + hostPID: + description: 'Use the host''s pid namespace. Optional: + Default to false.' + type: boolean + hostname: + description: Specifies the hostname of the Pod If not + specified, the pod's hostname will be set to a system-defined + value. + type: string + imagePullSecrets: + description: 'ImagePullSecrets is an optional list of + references to secrets in the same namespace to use for + pulling any of the images used by this PodSpec. If specified, + these secrets will be passed to individual puller implementations + for them to use. For example, in the case of docker, + only DockerConfig type secrets are honored. More info: + https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod' + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the + same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + type: array + initContainers: + description: 'List of initialization containers belonging + to the pod. Init containers are executed in order prior + to containers being started. If any init container fails, + the pod is considered to have failed and is handled + according to its restartPolicy. The name for an init + container or normal container must be unique among all + containers. Init containers may not have Lifecycle actions, + Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken + into account during scheduling by finding the highest + request/limit for each resource type, and then using + the max of of that value or the sum of the normal containers. + Limits are applied to init containers in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/' + items: + description: A single application container that you + want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The docker + image''s CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using + the container''s environment. If a variable cannot + be resolved, the reference in the input string + will be unchanged. The $(VAR_NAME) syntax can + be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within + a shell. The docker image''s ENTRYPOINT is used + if this is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. + If a variable cannot be resolved, the reference + in the input string will be unchanged. The $(VAR_NAME) + syntax can be escaped with a double $$, ie: $$(VAR_NAME). + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set + in the container. Cannot be updated. + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previous defined + environment variables in the container and + any service environment variables. If a + variable cannot be resolved, the reference + in the input string will be unchanged. The + $(VAR_NAME) syntax can be escaped with a + double $$, ie: $$(VAR_NAME). Escaped references + will never be expanded, regardless of whether + the variable exists or not. Defaults to + "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + metadata.labels, metadata.annotations, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and + requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment + variables in the container. The keys defined within + a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container + is starting. When a key exists in multiple sources, + the value associated with the last source will + take precedence. Values defined by an Env with + a duplicate key will take precedence. Cannot be + updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a + C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config + management to default or override container images + in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, + Never, IfNotPresent. Defaults to Always if :latest + tag is specified, or IfNotPresent otherwise. Cannot + be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system + should take in response to container lifecycle + events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately + after a container is created. If the handler + fails, the container is terminated and restarted + according to its restart policy. Other management + of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the + action to take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet + supported TODO: implement a realistic + TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately + before a container is terminated due to an + API request or management event such as liveness/startup + probe failure, preemption, resource contention, + etc. The handler is not called if the container + crashes or exits. The reason for termination + is passed to the handler. The Pod''s termination + grace period countdown begins before the PreStop + hooked is executed. Regardless of the outcome + of the handler, the container will eventually + terminate within the Pod''s termination grace + period. Other management of the container + blocks until the hook completes or until the + termination grace period is reached. More + info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the + action to take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet + supported TODO: implement a realistic + TCP lifecycle hook' + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. + Container will be restarted if the probe fails. + 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. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + 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 + name: + description: Name of the container specified as + a DNS_LABEL. Each container in a pod must have + a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Exposing a port here gives the system additional + information about the network connections a container + uses, but is primarily informational. Not specifying + a port here DOES NOT prevent that port from being + exposed. Any port which is listening on the default + "0.0.0.0" address inside a container will be accessible + from the network. Cannot be updated. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: Number of port to expose on the + pod's IP address. This must be a valid port + number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: Number of port to expose on the + host. If specified, this must be a valid + port number, 0 < x < 65536. If HostNetwork + is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an + IANA_SVC_NAME and unique within the pod. + Each named port in a pod must have a unique + name. Name for the port that can be referred + to by services. + type: string + protocol: + description: Protocol for port. Must be UDP, + TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + - protocol + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service + readiness. Container will be removed from service + endpoints if the probe fails. 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. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + 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/' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - 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/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - 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/' + type: object + type: object + securityContext: + description: 'Security options the pod should run + with. More info: https://kubernetes.io/docs/concepts/policy/security-context/ + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls + whether a process can gain more privileges + than its parent process. This bool directly + controls if the no_new_privs flag will be + set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run + as Privileged 2) has CAP_SYS_ADMIN' + type: boolean + capabilities: + description: The capabilities to add/drop when + running containers. Defaults to the default + set of capabilities granted by the container + runtime. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. + Processes in privileged containers are essentially + equivalent to root on the host. Defaults to + false. + type: boolean + procMount: + description: procMount denotes the type of proc + mount to use for the containers. The default + is DefaultProcMount which uses the container + runtime defaults for readonly paths and masked + paths. This requires the ProcMountType feature + flag to be enabled. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of + the container process. Uses runtime default + if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must + run as a non-root user. If true, the Kubelet + will validate the image at runtime to ensure + that it does not run as UID 0 (root) and fail + to start the container if it does. If unset + or false, no such validation will be performed. + May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of + the container process. Defaults to user specified + in image metadata if unspecified. May also + be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied + to the container. If unspecified, the container + runtime will allocate a random SELinux context + for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options + from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where + the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName + field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + runAsUserName: + description: The UserName in Windows to + run the entrypoint of the container process. + Defaults to the user specified in image + metadata if unspecified. May also be set + in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, + the value specified in SecurityContext + takes precedence. + type: string + 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' + properties: + exec: + description: One and only one of the following + should be specified. Exec specifies the action + to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: 'TCPSocket specifies an action + involving a TCP port. TCP hooks not yet supported + TODO: implement a realistic TCP lifecycle + hook' + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + 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 + stdin: + description: Whether this container should allocate + a buffer for stdin in the container runtime. If + this is not set, reads from stdin in the container + will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should + close the stdin channel after it has been opened + by a single attach. When stdin is true the stdin + stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is + opened on container start, is empty until the + first client attaches to stdin, and then remains + open and accepts data until the client disconnects, + at which time stdin is closed and remains closed + until the container is restarted. If this flag + is false, a container processes that reads from + stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to + which the container''s termination message will + be written is mounted into the container''s filesystem. + Message written is intended to be brief final + status, such as an assertion failure message. + Will be truncated by the node if greater than + 4096 bytes. The total message length across all + containers will be limited to 12kb. Defaults to + /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message + should be populated. File will use the contents + of terminationMessagePath to populate the container + status message on both success and failure. FallbackToLogsOnError + will use the last chunk of container log output + if the termination message file is empty and the + container exited with an error. The log output + is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate + a TTY for itself, also requires 'stdin' to be + true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block + devices to be used by the container. + items: + description: volumeDevice describes a mapping + of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside + of the container that the device will be + mapped to. + type: string + name: + description: name must match the name of a + persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's + filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting + of a Volume within a container. + properties: + mountPath: + description: Path within the container at + which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how + mounts are propagated from the host to container + and the other way around. When not set, + MountPropagationNone is used. This field + is beta in 1.10. + type: string + name: + description: This must match the Name of a + Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults + to false. + type: boolean + subPath: + description: Path within the volume from which + the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume + from which the container's volume should + be mounted. Behaves similarly to SubPath + but environment variable references $(VAR_NAME) + are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not + specified, the container runtime's default will + be used, which might be configured in the container + image. Cannot be updated. + type: string + required: + - name + type: object + type: array + nodeName: + description: NodeName is a request to schedule this pod + onto a specific node. If it is non-empty, the scheduler + simply schedules this pod onto that node, assuming that + it fits resource requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: 'NodeSelector is a selector which must be + true for the pod to fit on a node. Selector which must + match a node''s labels for the pod to be scheduled on + that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - 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: 'Overhead represents the resource overhead + associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by + the RuntimeClass admission controller. If the RuntimeClass + admission controller is enabled, overhead must not be + set in Pod create requests. The RuntimeClass admission + controller will reject Pod create requests which have + the overhead already set. If RuntimeClass is configured + and selected in the PodSpec, Overhead will be set to + the value defined in the corresponding RuntimeClass, + otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/20190226-pod-overhead.md + This field is alpha-level as of Kubernetes v1.16, and + is only honored by servers that enable the PodOverhead + feature.' + type: object + preemptionPolicy: + description: PreemptionPolicy is the Policy for preempting + pods with lower priority. One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. This field + is alpha-level and is only honored by servers that enable + the NonPreemptingPriority feature. + type: string + priority: + description: The priority value. Various system components + use this field to find the priority of the pod. When + Priority Admission Controller is enabled, it prevents + users from setting this field. The admission controller + populates this field from PriorityClassName. The higher + the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: If specified, indicates the pod's priority. + "system-node-critical" and "system-cluster-critical" + are two special keywords which indicate the highest + priorities with the former being the highest priority. + Any other name must be defined by creating a PriorityClass + object with that name. If not specified, the pod priority + will be default or zero if there is no default. + type: string + readinessGates: + description: 'If specified, all readiness gates will be + evaluated for pod readiness. A pod is ready when all + its containers are ready AND all conditions specified + in the readiness gates have status equal to "True" More + info: https://git.k8s.io/enhancements/keps/sig-network/0007-pod-ready%2B%2B.md' + items: + description: PodReadinessGate contains the reference + to a pod condition + properties: + conditionType: + description: ConditionType refers to a condition + in the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + description: 'Restart policy for all containers within + the pod. One of Always, OnFailure, Never. Default to + Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy' + type: string + runtimeClassName: + description: 'RuntimeClassName refers to a RuntimeClass + object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches + the named class, the pod will not be run. If unset or + empty, the "legacy" RuntimeClass will be used, which + is an implicit class with an empty definition that uses + the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md + This is a beta feature as of Kubernetes v1.14.' + type: string + schedulerName: + description: If specified, the pod will be dispatched + by specified scheduler. If not specified, the pod will + be dispatched by default scheduler. + type: string + securityContext: + description: 'SecurityContext holds pod-level security + attributes and common container settings. Optional: + Defaults to empty. See type description for default + values of each field.' + properties: + fsGroup: + description: "A special supplemental group that applies + to all containers in a pod. Some volume types allow + the Kubelet to change the ownership of that volume + to be owned by the pod: \n 1. The owning GID will + be the FSGroup 2. The setgid bit is set (new files + created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n + If unset, the Kubelet will not modify the ownership + and permissions of any volume." + 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".' + 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. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run + as a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not + run as UID 0 (root) and fail to start the container + if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the + container process. Defaults to user specified in + image metadata if unspecified. May also be set in + SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to + all containers. If unspecified, the container runtime + will allocate a random SELinux context for each + container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + supplementalGroups: + description: A list of groups applied to the first + process run in each container, in addition to the + container's primary GID. If unspecified, no groups + will be added to any container. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls + used for the pod. Pods with unsupported sysctls + (by the container runtime) might fail to launch. + items: + description: Sysctl defines a kernel parameter to + be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options within + a container's SecurityContext will be used. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: string + type: object + type: object + serviceAccount: + description: 'DeprecatedServiceAccount is a depreciated + alias for ServiceAccountName. Deprecated: Use serviceAccountName + instead.' + type: string + serviceAccountName: + description: 'ServiceAccountName is the name of the ServiceAccount + to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/' + type: string + shareProcessNamespace: + description: 'Share a single process namespace between + all of the containers in a pod. When this is set containers + will be able to view and signal processes from other + containers in the same pod, and the first process in + each container will not be assigned PID 1. HostPID and + ShareProcessNamespace cannot both be set. Optional: + Default to false.' + type: boolean + subdomain: + description: If specified, the fully qualified Pod hostname + will be "...svc.". 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. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: The pod this Toleration is attached to + tolerates any taint that matches the triple + using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to + match. Empty means match all taint effects. When + specified, allowed values are NoSchedule, PreferNoSchedule + and NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; + this combination means to match all values and + all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints + of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect + NoExecute, otherwise this field is ignored) tolerates + the taint. By default, it is not set, which means + tolerate the taint forever (do not evict). Zero + and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value + should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: TopologySpreadConstraints describes how a + group of pods ought to spread across topology domains. + Scheduler will schedule pods in a way which abides by + the constraints. This field is only honored by clusters + that enable the EvenPodsSpread feature. All topologySpreadConstraints + are ANDed. + items: + description: TopologySpreadConstraint specifies how + to spread matching pods among the given topology. + properties: + labelSelector: + description: LabelSelector is used to find matching + pods. Pods that match this label selector are + counted to determine the number of pods in their + corresponding topology domain. + 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 + maxSkew: + description: 'MaxSkew describes the degree to which + pods may be unevenly distributed. It''s the maximum + permitted difference between the number of matching + pods in any two topology domains of a given topology + type. For example, in a 3-zone cluster, MaxSkew + is set to 1, and pods with the same labelSelector + spread as 1/1/0: | zone1 | zone2 | zone3 | | P | P | | + - if MaxSkew is 1, incoming pod can only be scheduled + to zone3 to become 1/1/1; scheduling it onto zone1(zone2) + would make the ActualSkew(2-0) on zone1(zone2) + violate MaxSkew(1). - if MaxSkew is 2, incoming + pod can be scheduled onto any zone. It''s a required + field. Default value is 1 and 0 is not allowed.' + format: int32 + type: integer + topologyKey: + description: TopologyKey is the key of node labels. + Nodes that have a label with this key and identical + values are considered to be in the same topology. + We consider each as a "bucket", and + try to put balanced number of pods into each bucket. + It's a required field. + type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to + deal with a pod if it doesn''t satisfy the spread + constraint. - DoNotSchedule (default) tells the + scheduler not to schedule it - ScheduleAnyway + tells the scheduler to still schedule it It''s + considered as "Unsatisfiable" if and only if placing + incoming pod on any topology violates "MaxSkew". + For example, in a 3-zone cluster, MaxSkew is set + to 1, and pods with the same labelSelector spread + as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, + incoming pod can only be scheduled to zone2(zone3) + to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) + satisfies MaxSkew(1). In other words, the cluster + can still be imbalanced, but scheduler won''t + make it *more* imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: 'List of volumes that can be mounted by containers + belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes' + items: + description: Volume represents a named volume in a pod + that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'AWSElasticBlockStore represents an + AWS Disk resource that is attached to a kubelet''s + host machine and then exposed to the pod. More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'Filesystem type of the volume + that you want to mount. Tip: Ensure that the + filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'The partition in the volume that + you want to mount. If omitted, the default + is to mount by volume name. Examples: For + volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for + /dev/sda is "0" (or you can leave the property + empty).' + format: int32 + type: integer + readOnly: + description: 'Specify "true" to force and set + the ReadOnly property in VolumeMounts to "true". + If omitted, the default is "false". More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'Unique ID of the persistent disk + resource in AWS (Amazon EBS volume). More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: AzureDisk represents an Azure Data + Disk mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'Host Caching mode: None, Read + Only, Read Write.' + type: string + diskName: + description: The Name of the data disk in the + blob storage + type: string + diskURI: + description: The URI the data disk in the blob + storage + type: string + fsType: + description: Filesystem type to mount. Must + be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'Expected values Shared: multiple + blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: AzureFile represents an Azure File + Service mount on the host and bind mount to the + pod. + properties: + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretName: + description: the name of secret that contains + Azure Storage Account Name and Key + type: string + shareName: + description: Share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: CephFS represents a Ceph FS mount on + the host that shares a pod's lifetime + properties: + monitors: + description: 'Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'Optional: SecretFile is the path + to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'Optional: SecretRef is reference + to the authentication secret for User, default + is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'Optional: User is the rados user + name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'Cinder represents a cinder volume + attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'Filesystem type to mount. Must + be a filesystem type supported by the host + operating system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be "ext4" if + unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'Optional: points to a secret object + containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeID: + description: 'volume id used to identify the + volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: ConfigMap represents a configMap that + should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on + created files by default. Must be a value + between 0 and 0777. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options + that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified + which is not present in the ConfigMap, the + volume setup will error unless it is marked + optional. Paths must be relative and may not + contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits to use + on this file, must be a value between + 0 and 0777. If not specified, the volume + defaultMode will be used. This might + be in conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of the + file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the + string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its keys must be defined + type: boolean + type: object + csi: + description: CSI (Container Storage Interface) represents + storage that is handled by an external CSI driver + (Alpha feature). + properties: + driver: + description: Driver is the name of the CSI driver + that handles this volume. Consult with your + admin for the correct name as registered in + the cluster. + type: string + fsType: + description: Filesystem type to mount. Ex. "ext4", + "xfs", "ntfs". If not provided, the empty + value is passed to the associated CSI driver + which will determine the default filesystem + to apply. + type: string + nodePublishSecretRef: + description: NodePublishSecretRef is a reference + to the secret object containing sensitive + information to pass to the CSI driver to complete + the CSI NodePublishVolume and NodeUnpublishVolume + calls. This field is optional, and may be + empty if no secret is required. If the secret + object contains more than one secret, all + secret references are passed. + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + readOnly: + description: Specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: VolumeAttributes stores driver-specific + properties that are passed to the CSI driver. + Consult your driver's documentation for supported + values. + type: object + required: + - driver + type: object + downwardAPI: + description: DownwardAPI represents downward API + about the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on + created files by default. Must be a value + between 0 and 0777. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options + that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API + volume file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits to use + on this file, must be a value between + 0 and 0777. If not specified, the volume + defaultMode will be used. This might + be in conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. + Must not be absolute or contain the + ''..'' path. Must be utf-8 encoded. + The first item of the relative path + must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and + requests (limits.cpu, limits.memory, + requests.cpu and requests.memory) are + currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'EmptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'What type of storage medium should + back this directory. The default is "" which + means to use the node''s default medium. Must + be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'Total amount of local storage + required for this EmptyDir volume. The size + limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir + would be the minimum value between the SizeLimit + specified here and the sum of memory limits + of all containers in a pod. The default is + nil which means that the limit is undefined. + More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + fc: + description: FC represents a Fibre Channel resource + that is attached to a kubelet's host machine and + then exposed to the pod. + properties: + fsType: + description: 'Filesystem type to mount. Must + be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + lun: + description: 'Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts.' + type: boolean + targetWWNs: + description: 'Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: 'Optional: FC volume world wide + identifiers (wwids) Either wwids or combination + of targetWWNs and lun must be set, but not + both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: FlexVolume represents a generic volume + resource that is provisioned/attached using an + exec based plugin. + properties: + driver: + description: Driver is the name of the driver + to use for this volume. + type: string + fsType: + description: Filesystem type to mount. Must + be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". + The default filesystem depends on FlexVolume + script. + type: string + options: + additionalProperties: + type: string + description: 'Optional: Extra command options + if any.' + type: object + readOnly: + description: 'Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts.' + type: boolean + secretRef: + description: 'Optional: SecretRef is reference + to the secret object containing sensitive + information to pass to the plugin scripts. + This may be empty if no secret object is specified. + If the secret object contains more than one + secret, all secrets are passed to the plugin + scripts.' + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: Flocker represents a Flocker volume + attached to a kubelet's host machine. This depends + on the Flocker control service being running + properties: + datasetName: + description: Name of the dataset stored as metadata + -> name on the dataset for Flocker should + be considered as deprecated + type: string + datasetUUID: + description: UUID of the dataset. This is unique + identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'GCEPersistentDisk represents a GCE + Disk resource that is attached to a kubelet''s + host machine and then exposed to the pod. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'Filesystem type of the volume + that you want to mount. Tip: Ensure that the + filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'The partition in the volume that + you want to mount. If omitted, the default + is to mount by volume name. Examples: For + volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for + /dev/sda is "0" (or you can leave the property + empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'Unique name of the PD resource + in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'GitRepo represents a git repository + at a particular revision. DEPRECATED: GitRepo + is deprecated. To provision a container with a + git repo, mount an EmptyDir into an InitContainer + that clones the repo using git, then mount the + EmptyDir into the Pod''s container.' + properties: + directory: + description: Target directory name. Must not + contain or start with '..'. If '.' is supplied, + the volume directory will be the git repository. Otherwise, + if specified, the volume will contain the + git repository in the subdirectory with the + given name. + type: string + repository: + description: Repository URL + type: string + revision: + description: Commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'Glusterfs represents a Glusterfs mount + on the host that shares a pod''s lifetime. More + info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'EndpointsName is the endpoint + name that details Glusterfs topology. More + info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'Path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'ReadOnly here will force the Glusterfs + volume to be mounted with read-only permissions. + Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'HostPath represents a pre-existing + file or directory on the host machine that is + directly exposed to the container. This is generally + used for system agents or other privileged things + that are allowed to see the host machine. Most + containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can + use host directory mounts and who can/can not + mount host directories as read/write.' + properties: + path: + description: 'Path of the directory on the host. + If the path is a symlink, it will follow the + link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'Type for HostPath Volume Defaults + to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'ISCSI represents an ISCSI Disk resource + that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: whether support iSCSI Discovery + CHAP authentication + type: boolean + chapAuthSession: + description: whether support iSCSI Session CHAP + authentication + type: boolean + fsType: + description: 'Filesystem type of the volume + that you want to mount. Tip: Ensure that the + filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More + info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + initiatorName: + description: Custom iSCSI Initiator Name. If + initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for + the connection. + type: string + iqn: + description: Target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iSCSI Interface Name that uses + an iSCSI transport. Defaults to 'default' + (tcp). + type: string + lun: + description: iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: iSCSI Target Portal List. The portal + is either an IP or ip_addr:port if the port + is other than default (typically TCP ports + 860 and 3260). + items: + type: string + type: array + readOnly: + description: ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: CHAP Secret for iSCSI target and + initiator authentication + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + targetPortal: + description: iSCSI Target Portal. The Portal + is either an IP or ip_addr:port if the port + is other than default (typically TCP ports + 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'Volume''s name. Must be a DNS_LABEL + and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'NFS represents an NFS mount on the + host that shares a pod''s lifetime More info: + https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'Path that is exported by the NFS + server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force the NFS + export to be mounted with read-only permissions. + Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname or IP address + of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'PersistentVolumeClaimVolumeSource + represents a reference to a PersistentVolumeClaim + in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'ClaimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this + volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: PhotonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets + host machine + properties: + fsType: + description: Filesystem type to mount. Must + be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: PortworxVolume represents a portworx + volume attached and mounted on kubelets host machine + properties: + fsType: + description: FSType represents the filesystem + type to mount Must be a filesystem type supported + by the host operating system. Ex. "ext4", + "xfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + volumeID: + description: VolumeID uniquely identifies a + Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: Items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: Mode bits to use on created files + by default. Must be a value between 0 and + 0777. Directories within the path are not + affected by this setting. This might be in + conflict with other options that affect the + file mode, like fsGroup, and the result can + be other mode bits set. + format: int32 + type: integer + sources: + description: list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + configMap: + description: information about the configMap + data to project + properties: + items: + description: If unspecified, each + key-value pair in the Data field + of the referenced ConfigMap will + be projected into the volume as + a file whose name is the key and + content is the value. If specified, + the listed keys will be projected + into the specified paths, and unlisted + keys will not be present. If a key + is specified which is not present + in the ConfigMap, the volume setup + will error unless it is marked optional. + Paths must be relative and may not + contain the '..' path or start with + '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path + of the file to map the key + to. May not be an absolute + path. May not contain the + path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + downwardAPI: + description: information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of + the schema the FieldPath + is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the + field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path + is the relative path name + of the file to be created. + Must not be absolute or contain + the ''..'' path. Must be utf-8 + encoded. The first item of + the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu + and requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container + name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the + output format of the exposed + resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: + resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: information about the secret + data to project + properties: + items: + description: If unspecified, each + key-value pair in the Data field + of the referenced Secret will be + projected into the volume as a file + whose name is the key and content + is the value. If specified, the + listed keys will be projected into + the specified paths, and unlisted + keys will not be present. If a key + is specified which is not present + in the Secret, the volume setup + will error unless it is marked optional. + Paths must be relative and may not + contain the '..' path or start with + '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode + bits to use on this file, + must be a value between 0 + and 0777. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path + of the file to map the key + to. May not be an absolute + path. May not contain the + path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: information about the serviceAccountToken + data to project + properties: + audience: + description: Audience is the intended + audience of the token. A recipient + of a token must identify itself + with an identifier specified in + the audience of the token, and otherwise + should reject the token. The audience + defaults to the identifier of the + apiserver. + type: string + expirationSeconds: + description: ExpirationSeconds is + the requested duration of validity + of the service account token. As + the token approaches expiration, + the kubelet volume plugin will proactively + rotate the service account token. + The kubelet will start trying to + rotate the token if the token is + older than 80 percent of its time + to live or if the token is older + than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: Path is the path relative + to the mount point of the file to + project the token into. + type: string + required: + - path + 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 + properties: + group: + description: Group to map volume access to Default + is no group + type: string + readOnly: + description: ReadOnly here will force the Quobyte + volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: Registry represents a single or + multiple Quobyte Registry services specified + as a string as host:port pair (multiple entries + are separated with commas) which acts as the + central registry for volumes + type: string + tenant: + description: Tenant owning the given Quobyte + volume in the Backend Used with dynamically + provisioned Quobyte volumes, value is set + by the plugin + type: string + user: + description: User to map volume access to Defaults + to serivceaccount user + type: string + volume: + description: Volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'RBD represents a Rados Block Device + mount on the host that shares a pod''s lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'Filesystem type of the volume + that you want to mount. Tip: Ensure that the + filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More + info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + image: + description: 'The rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'Keyring is the path to key ring + for RBDUser. Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'A collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'The rados pool name. Default is + rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'ReadOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'SecretRef is name of the authentication + secret for RBDUser. If provided overrides + keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'The rados user name. Default is + admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: ScaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must + be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: The host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: The name of the ScaleIO Protection + Domain for the configured storage. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: SecretRef references to the secret + for ScaleIO user and other sensitive information. + If this is not provided, Login operation will + fail. + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + sslEnabled: + description: Flag to enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: Indicates whether the storage for + a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: The ScaleIO Storage Pool associated + with the protection domain. + type: string + system: + description: The name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: The name of a volume already created + in the ScaleIO system that is associated with + this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'Secret represents a secret that should + populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'Optional: mode bits to use on + created files by default. Must be a value + between 0 and 0777. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options + that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: If unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified + which is not present in the Secret, the volume + setup will error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits to use + on this file, must be a value between + 0 and 0777. If not specified, the volume + defaultMode will be used. This might + be in conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: The relative path of the + file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the + string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: Specify whether the Secret or its + keys must be defined + type: boolean + secretName: + description: 'Name of the secret in the pod''s + namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: StorageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: Filesystem type to mount. Must + be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: SecretRef specifies the secret + to use for obtaining the StorageOS API credentials. If + not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeName: + description: VolumeName is the human-readable + name of the StorageOS volume. Volume names + are only unique within a namespace. + type: string + volumeNamespace: + description: VolumeNamespace specifies the scope + of the volume within StorageOS. If no namespace + is specified then the Pod's namespace will + be used. This allows the Kubernetes name + scoping to be mirrored within StorageOS for + tighter integration. Set VolumeName to any + name to override the default behaviour. Set + to "default" if you are not using namespaces + within StorageOS. Namespaces that do not pre-exist + within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: VsphereVolume represents a vSphere + volume attached and mounted on kubelets host machine + properties: + fsType: + description: Filesystem type to mount. Must + be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: Storage Policy Based Management + (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: Storage Policy Based Management + (SPBM) profile name. + type: string + volumePath: + description: Path that identifies vSphere volume + vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + type: object + type: object + description: Defines replica spec for replica type + type: object + ingressSpec: + description: IngressSpec defines the ingress created by controller + properties: + clientAuthSecretName: + description: ClientAuthSecretName is the name for Ingress client-auth + type: string + extraHostSuffix: + description: ExtraHostSuffix is the suffix appended to FLApp hostname + type: string + ingressClassName: + description: IngressClassName is the Ingress-class name + type: string + secretName: + description: secretName is the name for Ingress TLS secrets + type: string + required: + - clientAuthSecretName + - extraHostSuffix + - ingressClassName + - secretName + type: object + peerSpecs: + additionalProperties: + description: PeerSpec is a description of a involved controller in + the app + properties: + authority: + description: Authority is the GRPC Authority in the request + type: string + extraHeaders: + additionalProperties: + type: string + description: The extra GRPC header in the request + type: object + peerURL: + description: PeerURL is the url of the involved controller + type: string + required: + - peerURL + type: object + description: Defines all the controllers involved in the app + type: object + role: + description: Defines the role of FLApp + pattern: (^Leader$)|(^Follower\d*$) + type: string + ttlSecondsAfterFinished: + description: 'Defines the TTL for cleaning up finished FLApps (temporary + before kubernetes adds the cleanup controller). It may take extra + ReconcilePeriod seconds for the cleanup, since reconcile gets called + periodically. Defaults to infinite. TODO: CompletionTime is required + for this field' + format: int32 + type: integer + required: + - flReplicaSpecs + - peerSpecs + - role + type: object + status: + description: Status is the status for FLApp + properties: + appState: + description: FLState is the current state of the entire job Defaults + to New. + type: string + completionTime: + description: Represents time when the job was completed. It is not guaranteed + to be set in happens-before order across separate operations. It is + represented in RFC3339 form and is in UTC. + format: date-time + nullable: true + type: string + flReplicaStatus: + additionalProperties: + description: ReplicaStatus is a description of pairing status + properties: + active: + additionalProperties: + description: Empty is public since it is used by some internal + API objects for conversions between external string arrays + and internal sets, and conversion logic requires public types + today. + type: object + description: The actively running pods. + type: object + failed: + additionalProperties: + description: Empty is public since it is used by some internal + API objects for conversions between external string arrays + and internal sets, and conversion logic requires public types + today. + type: object + description: The pods which reached phase Failed. + type: object + local: + additionalProperties: + description: Empty is public since it is used by some internal + API objects for conversions between external string arrays + and internal sets, and conversion logic requires public types + today. + type: object + description: Local is the set of ID allocated locally + type: object + mapping: + additionalProperties: + type: string + description: Mapping is the mapping from a local ID to remote + ID + type: object + remote: + additionalProperties: + description: Empty is public since it is used by some internal + API objects for conversions between external string arrays + and internal sets, and conversion logic requires public types + today. + type: object + description: Remote is the set of ID allocated from the peer side + type: object + succeeded: + additionalProperties: + description: Empty is public since it is used by some internal + API objects for conversions between external string arrays + and internal sets, and conversion logic requires public types + today. + type: object + description: The pods which reached phase Succeeded. + type: object + required: + - active + - failed + - local + - mapping + - remote + - succeeded + type: object + description: A map of FLReplicaType to FLReplicaStatus + type: object + required: + - appState + - completionTime + - flReplicaStatus + type: object + type: object +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end }} +{{- end }} \ No newline at end of file diff --git a/deploy/charts/fedlearner/charts/fedlearner-operator/templates/fedlearner.k8s.io_flapps.yaml b/deploy/charts/fedlearner/charts/fedlearner-operator/templates/fedlearner.k8s.io_flapps_v1beta1.yaml similarity index 99% rename from deploy/charts/fedlearner/charts/fedlearner-operator/templates/fedlearner.k8s.io_flapps.yaml rename to deploy/charts/fedlearner/charts/fedlearner-operator/templates/fedlearner.k8s.io_flapps_v1beta1.yaml index c26eacc3b..313a7f11e 100644 --- a/deploy/charts/fedlearner/charts/fedlearner-operator/templates/fedlearner.k8s.io_flapps.yaml +++ b/deploy/charts/fedlearner/charts/fedlearner-operator/templates/fedlearner.k8s.io_flapps_v1beta1.yaml @@ -1,4 +1,5 @@ {{- if .Values.installCRD }} +{{- if semverCompare "<1.18-0" .Capabilities.KubeVersion.GitVersion -}} apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: @@ -6428,7 +6429,6 @@ spec: - flReplicaStatus type: object type: object - version: v1alpha1 versions: - name: v1alpha1 served: true @@ -6440,3 +6440,4 @@ status: conditions: [] storedVersions: [] {{- end }} +{{- end }} \ No newline at end of file diff --git a/deploy/charts/fedlearner/charts/fedlearner-operator/templates/ingress-v1.yaml b/deploy/charts/fedlearner/charts/fedlearner-operator/templates/ingress-v1.yaml new file mode 100644 index 000000000..7d77326f1 --- /dev/null +++ b/deploy/charts/fedlearner/charts/fedlearner-operator/templates/ingress-v1.yaml @@ -0,0 +1,30 @@ +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} + +{{- if .Values.ingress.enabled -}} +{{- $ingressSuffix := index .Values.extraArgs "ingress-extra-host-suffix" -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: fedlearner-operator + namespace: {{ .Release.Namespace }} + labels: + {{- include "fedlearner-operator.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + - host: {{ printf "%s%s" (.Values.ingress.host | required "host cannot be null") $ingressSuffix | quote }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: fedlearner-operator + port: + number: 8100 +{{- end }} + +{{- end }} diff --git a/deploy/charts/fedlearner/charts/fedlearner-operator/templates/ingress.yaml b/deploy/charts/fedlearner/charts/fedlearner-operator/templates/ingress-v1beta1.yaml similarity index 69% rename from deploy/charts/fedlearner/charts/fedlearner-operator/templates/ingress.yaml rename to deploy/charts/fedlearner/charts/fedlearner-operator/templates/ingress-v1beta1.yaml index 0ed2b6584..6677274b0 100644 --- a/deploy/charts/fedlearner/charts/fedlearner-operator/templates/ingress.yaml +++ b/deploy/charts/fedlearner/charts/fedlearner-operator/templates/ingress-v1beta1.yaml @@ -1,4 +1,7 @@ +{{- if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}} + {{- if .Values.ingress.enabled -}} +{{- $ingressSuffix := index .Values.extraArgs "ingress-extra-host-suffix" -}} {{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} apiVersion: networking.k8s.io/v1beta1 {{- else -}} @@ -15,21 +18,14 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: - {{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} - {{- end }} rules: - - host: {{ .Values.ingress.host | quote }} + - host: {{ printf "%s%s" (.Values.ingress.host | required "host cannot be null") $ingressSuffix | quote }} http: paths: - backend: serviceName: fedlearner-operator servicePort: 8100 {{- end }} + +{{- end }} + diff --git a/deploy/charts/fedlearner/charts/fedlearner-operator/values.yaml b/deploy/charts/fedlearner/charts/fedlearner-operator/values.yaml index 0e3da62a6..4b3ce484e 100644 --- a/deploy/charts/fedlearner/charts/fedlearner-operator/values.yaml +++ b/deploy/charts/fedlearner/charts/fedlearner-operator/values.yaml @@ -6,10 +6,11 @@ replicaCount: 1 image: repository: fedlearner/fedlearner-operator - tag: "v1.5-rc2" + tag: "v2-rc1" pullPolicy: IfNotPresent imagePullSecrets: [] + nameOverride: "" fullnameOverride: "" @@ -28,7 +29,6 @@ ingress: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/backend-protocol: GRPC - tls: [] - host: default.fedlearner.operator + host: fedlearner-operator installCRD: true diff --git a/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/deployment.yaml b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/deployment.yaml index 84f1bfd23..17ba6dc60 100644 --- a/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/deployment.yaml +++ b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/deployment.yaml @@ -53,10 +53,17 @@ spec: protocol: TCP resources: {{- toYaml .Values.resources | nindent 12 }} - {{- if .Values.extraVolumeMounts }} volumeMounts: + {{- if .Values.hook }} + - name: hook-volume + mountPath: /app/api/hooks + {{- end }} + {{- if .Values.extraVolumeMounts }} {{- toYaml .Values.extraVolumeMounts | nindent 12 }} - {{- end }} + {{- end }} + {{- if .Values.userVolumes }} + {{- toYaml .Values.userVolumeMounts | nindent 12 }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} @@ -69,7 +76,18 @@ spec: tolerations: {{- toYaml . | nindent 8 }} {{- end }} - {{- with .Values.extraVolumes }} volumes: + {{- if .Values.hook }} + - name: hook-volume + configMap: + name: "{{ .Release.Name }}-hook" + items: + - key: hook + path: "hook.py" + {{- end }} + {{- with .Values.extraVolumes }} {{- toYaml . | nindent 8 }} - {{- end }} + {{- end }} + {{- with .Values.userVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/hook_config_map.yaml b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/hook_config_map.yaml new file mode 100644 index 000000000..42d312cca --- /dev/null +++ b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/hook_config_map.yaml @@ -0,0 +1,9 @@ +{{- if .Values.hook }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ .Release.Name }}-hook" +data: + hook: | + {{ .Files.Get .Values.hook | nindent 4 }} +{{- end }} \ No newline at end of file diff --git a/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/ingress-v1.yaml b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/ingress-v1.yaml new file mode 100644 index 000000000..30b2d9750 --- /dev/null +++ b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/ingress-v1.yaml @@ -0,0 +1,36 @@ +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} + +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "fedlearner-web-console-v2.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- $ingressPrefix := .Values.ingress.ingressPrefix -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "fedlearner-web-console-v2.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + {{- range .Values.ingress.hosts }} + - host: {{ printf "%s.%s" $ingressPrefix (.domainName | required "http domain name is required") | quote }} + http: + paths: + {{- range .paths }} + - path: {{ . }} + pathType: Prefix + backend: + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- end }} + {{- end }} + +{{- end }} +{{- end }} diff --git a/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/ingress.yaml b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/ingress-v1beta1.yaml similarity index 73% rename from deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/ingress.yaml rename to deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/ingress-v1beta1.yaml index 969ccff53..1595707dc 100644 --- a/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/ingress.yaml +++ b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/ingress-v1beta1.yaml @@ -1,7 +1,10 @@ +{{- if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}} + {{- if .Values.ingress.enabled -}} {{- $fullName := include "fedlearner-web-console-v2.fullname" . -}} {{- $svcPort := .Values.service.port -}} {{- $ingressPrefix := .Values.ingress.ingressPrefix -}} + {{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} apiVersion: networking.k8s.io/v1beta1 {{- else -}} @@ -18,16 +21,6 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: - {{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range (.domainNames | required "tls domain name is required") }} - - {{ printf "%s.%s" $ingressPrefix (. | required "tls domain name cannot be null") | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} - {{- end }} rules: {{- range .Values.ingress.hosts }} - host: {{ printf "%s.%s" $ingressPrefix (.domainName | required "http domain name is required") | quote }} @@ -40,4 +33,6 @@ spec: servicePort: {{ $svcPort }} {{- end }} {{- end }} - {{- end }} + +{{- end }} +{{- end }} diff --git a/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/public_service.yaml b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/public_service.yaml new file mode 100644 index 000000000..c6aaf89e5 --- /dev/null +++ b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/templates/public_service.yaml @@ -0,0 +1,19 @@ +{{- if .Values.publicService.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: "{{ include "fedlearner-web-console-v2.fullname" . }}-http" + namespace: {{ .Release.Namespace }} + labels: + {{- include "fedlearner-web-console-v2.labels" . | nindent 4 }} +spec: + type: NodePort + ports: + - port: {{ .Values.publicService.podPort }} + targetPort: {{ .Values.publicService.podPort }} + protocol: TCP + name: http + nodePort: {{ .Values.publicService.nodePort }} + selector: + {{- include "fedlearner-web-console-v2.selectorLabels" . | nindent 4 }} +{{- end}} diff --git a/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/values.yaml b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/values.yaml index 9abfa9a10..4a65fde35 100644 --- a/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/values.yaml +++ b/deploy/charts/fedlearner/charts/fedlearner-web-console-v2/values.yaml @@ -8,7 +8,7 @@ image: repository: fedlearner/fedlearner-web-console-v2 pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. - tag: "0c1120d" + tag: "v2-rc1" imagePullSecrets: [] nameOverride: "" @@ -42,20 +42,20 @@ service: type: ClusterIP port: 1990 +publicService: + enabled: true + podPort: 1989 + nodePort: 30200 + ingress: enabled: true ingressPrefix: "fedlearner-webconsole-v2" annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/backend-protocol: GRPC - nginx.ingress.kubernetes.io/auth-tls-secret: default/ca-secret - nginx.ingress.kubernetes.io/auth-tls-verify-client: "on" hosts: - - domainName: null + - domainName: demo.com paths: ["/"] - tls: - - secretName: fedlearner-proxy-server - domainNames: null resources: limits: @@ -80,6 +80,8 @@ extraVolumes: persistentVolumeClaim: claimName: pvc-fedlearner-default +hook: "" + cluster: env: KIBANA_HOST: fedlearner-stack-kibana @@ -98,3 +100,4 @@ cluster: DB_HOST: fedlearner-stack-mariadb DB_PORT: 3306 DB_DATABASE: fedlearner + diff --git a/deploy/charts/fedlearner/values.yaml b/deploy/charts/fedlearner/values.yaml index 13a72f845..6f5ddc549 100644 --- a/deploy/charts/fedlearner/values.yaml +++ b/deploy/charts/fedlearner/values.yaml @@ -22,22 +22,12 @@ fedlearner-apiserver: pullPolicy: IfNotPresent fedlearner-web-console: - image: - repository: fedlearner/fedlearner-web-console - tag: "v1.5-rc2" - pullPolicy: IfNotPresent - - ingress: - enabled: true - - extraVolumeMounts: - - name: data - mountPath: /data - - extraVolumes: - - name: data - persistentVolumeClaim: - claimName: pvc-fedlearner-default + enabled: false fedlearner-web-console-v2: - enabled: false + enabled: true + image: + repository: fedlearner/fedlearner-web-console-v2 + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "v2-rc1" diff --git a/deploy/integrated_test/credit_default/default_credit_hetero_guest.csv b/deploy/integrated_test/credit_default/default_credit_hetero_guest.csv new file mode 100644 index 000000000..4e32950ad --- /dev/null +++ b/deploy/integrated_test/credit_default/default_credit_hetero_guest.csv @@ -0,0 +1,1001 @@ +raw_id,example_id,event_time,label,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12 +1,1,20210621,1.0,-1.486041,-0.642501,-0.647399,-0.6679930000000001,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.227086,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +2,2,20210621,1.0,1.992316,-0.659219,-0.666747,-0.639254,-0.621636,-0.606229,-0.597966,-0.341942,-0.213588,-0.24000500000000002,-0.24423000000000003,-0.314136,-0.180878 +3,3,20210621,0.0,0.253137,-0.29856,-0.493899,-0.482408,-0.44973,-0.417188,-0.39163000000000003,-0.250292,-0.191887,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.012121999999999999 +4,4,20210621,0.0,0.253137,-0.057490999999999993,-0.013293000000000001,0.032846,-0.232373,-0.186729,-0.156579,-0.221191,-0.16936099999999998,-0.228645,-0.237846,-0.244166,-0.23713 +5,5,20210621,0.0,0.253137,-0.5786180000000001,-0.611318,-0.161189,-0.346997,-0.348137,-0.331482,-0.221191,1.335034,0.271165,0.266434,-0.269039,-0.255187 +6,6,20210621,0.0,0.253137,0.178947,0.110856,0.152777,-0.371029,-0.340357,-0.31648699999999996,-0.191003,-0.178215,-0.259486,-0.24423000000000003,-0.248683,-0.248381 +7,7,20210621,0.0,0.253137,4.301531,5.098086,5.739063,7.762727000000001,7.281574000000001,7.305617,2.978712,1.479085,1.861472,0.9838520000000001,0.5858479999999999,0.481207 +8,8,20210621,0.0,-0.616452,-0.534359,-0.6856439999999999,-0.669262,-0.6690619999999999,-0.665674,-0.643203,-0.318999,-0.23090500000000003,-0.29680100000000004,-0.270976,-0.203716,-0.20664200000000002 +9,9,20210621,0.0,0.253137,-0.542385,-0.49293000000000003,-0.503332,-0.482684,-0.46908199999999994,-0.590276,-0.140952,-0.25699,-0.27226500000000003,-0.24423000000000003,-0.248683,-0.23713 +10,10,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.677929,-0.672497,-0.449114,-0.41911800000000005,-0.341942,-0.25699,-0.29680100000000004,0.522212,-0.24069699999999997,-0.29338200000000003 +11,11,20210621,0.0,-0.616452,-0.5452640000000001,-0.553473,-0.598114,-0.633434,-0.632991,-0.590074,-0.202716,-0.256469,-0.29396100000000003,-0.28891300000000003,-0.069471,-0.289669 +12,12,20210621,0.0,1.992316,-0.529131,-0.38651199999999997,-0.534219,-0.5401050000000001,-0.296473,-0.42321499999999995,0.975331,0.175553,0.190684,1.115475,-0.314136,-0.088625 +13,13,20210621,0.0,-0.616452,-0.530814,-0.5996560000000001,-0.584199,-0.571459,-0.556144,-0.604532,-0.281566,0.025123,0.072377,0.106851,-0.12628499999999998,-0.29338200000000003 +14,14,20210621,1.0,1.992316,0.197987,0.255575,0.269478,0.36559,-0.068662,-0.03321,-0.14874,-0.25699,-0.126411,-0.11656400000000001,-0.21595599999999998,-0.29338200000000003 +15,15,20210621,0.0,0.253137,0.267044,0.251233,0.23861999999999997,0.255442,0.272445,0.279418,-0.160815,-0.12678399999999998,-0.126411,-0.11656400000000001,-0.117776,-0.124626 +16,16,20210621,0.0,0.253137,-0.008275,-0.281092,-0.272497,-0.225269,-0.17732,-0.145429,-0.341942,-0.191887,-0.234325,-0.231463,-0.22904699999999997,-0.23150500000000002 +17,17,20210621,1.0,1.992316,-0.48682700000000007,-0.43793699999999997,-0.426617,-0.387444,-0.36855,-0.331935,-0.14874,-0.25699,-0.211606,-0.30806300000000003,-0.20613800000000002,-0.29338200000000003 +18,18,20210621,0.0,-0.616452,2.744125,2.772935,2.129108,0.41676199999999997,-0.5667369999999999,2.631722,0.283428,0.177029,4.016337,0.9685959999999999,12.488479,2.519214 +19,19,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +20,20,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +21,21,20210621,0.0,-0.616452,-0.174718,-0.30195700000000003,-0.324798,-0.352034,-0.468934,-0.637108,-0.160815,-0.190281,-0.24000500000000002,-0.180397,-0.253264,1.605908 +22,22,20210621,1.0,-0.616452,-0.69135,-0.6865439999999999,-0.673372,-0.672497,-0.652663,-0.647418,-0.322863,-0.243275,-0.29680100000000004,-0.26771999999999996,-0.293453,-0.29338200000000003 +23,23,20210621,1.0,1.992316,-0.137657,-0.09461599999999999,-0.028741000000000003,0.01155,0.108454,0.119897,-0.220768,-0.101524,-0.29680100000000004,-0.0782,-0.314136,-0.191004 +24,24,20210621,1.0,-1.486041,-0.620786,-0.418126,-0.656688,-0.663792,-0.6630590000000001,-0.652724,0.831034,-0.19305899999999998,-0.264995,-0.30806300000000003,-0.314136,-0.22993000000000002 +25,25,20210621,0.0,0.253137,-0.631216,-0.591647,-0.677929,-0.588589,-0.558447,-0.513487,0.00564,-0.25699,0.009787,-0.231463,-0.180284,-0.180878 +26,26,20210621,0.0,0.253137,-0.048935,-0.103538,-0.158478,-0.22222199999999998,-0.17241900000000002,-0.1482,-0.222821,-0.195098,-0.239948,-0.21665399999999999,-0.244625,-0.23729899999999998 +27,27,20210621,1.0,-0.616452,-0.697122,-0.696955,-0.674194,-0.673383,-0.66097,-0.655898,-0.341942,-0.213588,-0.29680100000000004,-0.276146,-0.314136,-0.23713 +28,28,20210621,0.0,0.253137,-0.389522,-0.464239,-0.430439,-0.394594,-0.351674,-0.323321,-0.263453,-0.200567,-0.24000500000000002,-0.212313,-0.248683,-0.23645500000000003 +29,29,20210621,0.0,-0.616452,-0.686814,-0.643001,-0.62867,-0.640787,-0.16253299999999998,-0.648409,-0.135759,-0.10851199999999998,-0.18070899999999998,1.6343729999999999,-0.297315,-0.29338200000000003 +30,30,20210621,0.0,0.253137,-0.487465,-0.458099,-0.425637,-0.39414299999999997,-0.360819,-0.46129799999999993,-0.25137800000000005,-0.191887,-0.24000500000000002,-0.24423000000000003,-0.209411,-0.29338200000000003 +31,31,20210621,0.0,-0.616452,-0.46958,-0.44840399999999997,-0.486633,-0.434061,-0.42773100000000003,-0.032723,0.7007439999999999,0.319431,0.574403,0.6051949999999999,2.126751,-0.29338200000000003 +32,32,20210621,1.0,0.253137,-0.28119,-0.27484000000000003,-0.359218,-0.31911100000000003,-0.28117600000000004,-0.255096,-0.23821599999999998,-0.191887,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.253106 +33,33,20210621,0.0,0.253137,0.56784,0.49024399999999996,0.517199,0.5859479999999999,0.6314810000000001,0.616546,-0.159426,-0.10460599999999999,-0.109259,-0.10354200000000001,-0.10468499999999999,-0.152527 +34,34,20210621,0.0,-1.486041,-0.5472199999999999,-0.632646,-0.35027800000000003,-0.555588,0.512,-0.501918,-0.091262,0.733745,0.130366,4.252097,-0.249926,2.608205 +35,35,20210621,0.0,-1.486041,-0.509466,-0.6206470000000001,-0.229035,-0.623066,-0.6630590000000001,-0.563846,-0.039702,1.0961940000000001,-0.11618800000000001,-0.30806300000000003,0.032309,-0.250181 +36,36,20210621,0.0,-0.616452,-0.28462600000000005,-0.692824,-0.685528,-0.6868449999999999,-0.687534,-0.6843600000000001,-0.334032,-0.239802,-0.27431,-0.271997,-0.262297,-0.29338200000000003 +37,37,20210621,0.0,0.253137,1.837174,1.856739,1.9237529999999998,1.976427,2.197337,2.326347,0.14263199999999998,0.092829,0.061017999999999996,0.100468,0.10476500000000001,0.085587 +38,38,20210621,0.0,-0.616452,-0.4912,-0.5532060000000001,-0.518328,-0.5788270000000001,-1.129124,-0.33939,-0.25137800000000005,-0.191105,-0.180766,-0.30806300000000003,2.806092,-0.258675 +39,39,20210621,1.0,-1.486041,-0.695642,-0.680024,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.29484899999999997,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +40,40,20210621,0.0,-0.616452,-0.688879,-0.563476,-0.611006,-0.517426,-0.36738200000000004,-0.49358900000000006,0.20596599999999998,-0.25699,0.269802,0.202601,0.309307,-0.24944899999999998 +41,41,20210621,0.0,0.253137,2.273993,2.418304,2.3054930000000002,9.100261,2.56032,2.356757,0.261814,0.046824,0.043979000000000004,11.746145,1.518558,-0.068374 +42,42,20210621,0.0,0.253137,0.22133200000000003,0.25037600000000004,0.24421500000000002,0.317666,0.40145,0.45502600000000004,-0.160815,-0.06168099999999999,-0.067229,-0.14848,-0.130867,-0.152752 +43,43,20210621,0.0,0.253137,-0.670151,-0.646247,-0.591366,-0.6169100000000001,-0.602693,-0.577984,-0.25137800000000005,-0.129952,-0.24000500000000002,-0.28891300000000003,-0.248683,-0.265256 +44,44,20210621,0.0,0.253137,0.112456,0.173732,0.229448,0.326698,0.440284,0.5193720000000001,-0.160815,-0.12678399999999998,-0.126411,-0.05273099999999999,-0.052323,-0.124626 +45,45,20210621,0.0,0.253137,-0.43860200000000005,-0.391781,-0.30414800000000003,-0.280638,-0.224939,-0.162456,-0.160815,-0.03998,-0.29680100000000004,-0.180397,-0.117776,-0.29338200000000003 +46,46,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +47,47,20210621,1.0,0.253137,-0.505134,-0.45937700000000004,-0.450093,-0.41848599999999997,-0.388781,-0.652724,-0.160815,-0.25699,0.654032,-0.286742,-0.314136,-0.29338200000000003 +48,48,20210621,1.0,-1.486041,-0.6350319999999999,-0.648355,-0.661057,-0.6543100000000001,-0.6630590000000001,-0.652724,-0.280781,-0.206209,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +49,49,20210621,0.0,-0.616452,-0.391424,-0.388339,-0.459697,-0.174796,-0.468161,-0.45335600000000004,0.9585469999999999,0.400028,1.10477,0.448421,0.46312299999999995,0.170753 +50,50,20210621,0.0,0.253137,-0.45870200000000005,-0.43134700000000004,-0.39708499999999997,-0.363707,-0.32619499999999996,-0.315832,-0.262367,-0.199916,-0.256816,-0.24882600000000002,-0.254443,-0.23324899999999998 +51,51,20210621,1.0,0.253137,-0.192591,-0.182768,-0.12485,-0.05969,-0.027179000000000002,0.008232,-0.341942,-0.12244400000000001,-0.18320799999999998,-0.30806300000000003,-0.21595599999999998,-0.209004 +52,52,20210621,0.0,0.253137,0.14036400000000002,0.027875,-0.045988,-0.05664299999999999,-0.07483,-0.094265,-0.221191,-0.18728599999999998,-0.211606,-0.180397,-0.21595599999999998,-0.23713 +53,53,20210621,0.0,-1.486041,-0.51278,-0.580449,-0.568337,-0.498633,-0.604765,-0.644933,0.133516,0.072865,0.338469,-0.081839,-0.28376599999999996,-0.29338200000000003 +54,54,20210621,0.0,0.253137,-0.133379,-0.104494,-0.061359000000000004,0.0038399999999999997,0.06758,0.10826,-0.263453,-0.169752,-0.196726,-0.195589,-0.196975,-0.20214100000000002 +55,55,20210621,0.0,0.253137,-0.06789400000000001,-0.199319,-0.22465100000000002,-0.26029,-0.31695100000000004,-0.37498899999999996,-0.24534099999999998,-0.182425,-0.237222,-0.212313,-0.183229,-0.012121999999999999 +56,56,20210621,0.0,-1.486041,-0.669771,-0.63984,-0.675593,-0.672497,-0.660575,-0.610241,-0.122175,-0.24995799999999999,-0.29680100000000004,-0.29842399999999997,-0.148539,-0.29338200000000003 +57,57,20210621,0.0,-0.616452,-0.47311099999999995,-0.46908599999999995,-0.55621,-0.561479,-0.674227,-0.513,0.17125,-0.191887,0.129174,-0.26471999999999996,0.274944,-0.180878 +58,58,20210621,0.0,0.253137,1.6929900000000002,1.7459099999999999,1.8067490000000002,1.948416,1.511454,1.528824,0.146074,0.05967000000000001,0.001552,-0.000771,0.0010869999999999999,-0.079625 +59,59,20210621,0.0,1.992316,-0.674089,-0.675556,-0.666652,-0.6543720000000001,-0.6515449999999999,-0.628981,-0.341942,-0.25699,-0.257044,-0.30806300000000003,-0.235592,-0.29338200000000003 +60,60,20210621,0.0,0.253137,4.738404,4.913099,5.1506989999999995,4.926586,5.203366,5.460961,0.684442,0.39529699999999995,1.4070989999999999,0.45793199999999995,0.471304,1.000412 +61,61,20210621,1.0,0.253137,-0.385353,-0.358861,-0.405708,-0.44031000000000003,-0.435626,-0.39126,-0.25041199999999997,-0.200567,-0.24000500000000002,-0.24423000000000003,-0.183229,-0.180878 +62,62,20210621,0.0,-0.616452,0.265862,0.32148499999999997,0.33057600000000004,-0.415735,-0.43120200000000003,-0.638787,-0.09892999999999999,-0.16606300000000002,-0.24000500000000002,-0.180397,-0.117776,-0.29338200000000003 +63,63,20210621,1.0,1.992316,-0.356304,-0.34956,-0.294487,-0.270441,-0.20798000000000003,-0.178123,-0.341942,-0.13980399999999998,-0.29680100000000004,-0.166034,-0.235592,-0.29338200000000003 +64,64,20210621,1.0,-1.486041,-0.305635,-0.28119099999999997,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.281566,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +65,65,20210621,0.0,-0.616452,-0.694297,-0.690983,-0.677929,-0.672497,-0.624355,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.157864,-0.314136,-0.29338200000000003 +66,66,20210621,1.0,1.992316,1.375653,1.3990209999999998,1.399644,-0.545437,-0.5282140000000001,-0.519767,-0.341942,-0.25699,0.170181,-0.28891300000000003,-0.314136,-0.23713 +67,67,20210621,1.0,0.253137,-0.6671630000000001,-0.63207,-0.620566,-0.609356,-0.5940409999999999,-0.580083,-0.203078,-0.25699,-0.28828200000000004,-0.295296,-0.301045,-0.284382 +68,68,20210621,0.0,-0.616452,-0.6915680000000001,-0.686768,-0.661216,-0.6370560000000001,-0.6581239999999999,-0.581359,-0.323829,-0.20668699999999998,-0.167305,-0.28891300000000003,-0.035959,-0.24224899999999996 +69,69,20210621,0.0,-0.616452,-0.698222,-0.8293790000000001,-0.8199649999999999,-0.512219,-0.49592600000000003,-0.529826,-0.341942,-0.25699,0.848276,-0.30806300000000003,0.164917,0.48846300000000004 +70,70,20210621,0.0,0.253137,-0.44351899999999994,-0.44926099999999997,-0.428679,-0.391377,-0.478754,-0.552276,-0.341942,-0.204907,-0.24000500000000002,-0.276146,-0.248683,-0.29338200000000003 +71,71,20210621,0.0,-0.616452,-0.685049,-0.690983,-0.672305,-0.666435,-0.656644,-0.646175,-0.341942,-0.240063,-0.27465100000000003,-0.283168,-0.288609,-0.271444 +72,72,20210621,1.0,1.992316,0.095657,0.14144400000000001,0.189923,0.238747,0.361793,0.413987,-0.191003,-0.14848499999999998,-0.29680100000000004,-0.0016649999999999998,-0.157048,-0.203379 +73,73,20210621,0.0,-0.616452,-0.572385,-0.6096739999999999,-0.687792,-0.590936,-0.599765,-0.599813,0.009323,-0.256338,0.220162,-0.306977,-0.106976,-0.21491100000000002 +74,74,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.632434,-0.672497,-0.624257,-0.652724,-0.341942,-0.120057,-0.29680100000000004,-0.15748099999999998,-0.314136,-0.29338200000000003 +75,75,20210621,0.0,-0.616452,-0.6542479999999999,-0.613004,-0.34141,-0.605796,0.655331,-0.219162,0.002984,0.760914,-0.05177999999999999,4.833807,1.384314,-0.179978 +76,76,20210621,0.0,0.253137,-0.497108,-0.449093,-0.43795100000000003,-0.408615,-0.377975,-0.341355,-0.169871,-0.25699,-0.262155,-0.267848,-0.21595599999999998,-0.29338200000000003 +77,77,20210621,0.0,0.253137,-0.113878,-0.167959,-0.157555,-0.5227109999999999,-0.505318,-0.484303,-0.23574099999999998,-0.179778,-0.27862600000000004,-0.276146,-0.248683,-0.23713 +78,78,20210621,0.0,-0.616452,-0.6916899999999999,-0.686895,-0.673732,-0.667974,-0.6582720000000001,-0.647838,-0.324372,-0.24436,-0.280273,-0.289487,-0.295089,-0.277013 +79,79,20210621,1.0,0.253137,-0.31013,-0.274924,-0.240628,-0.23719099999999999,-0.228064,-0.545072,-0.240148,-0.19622699999999998,-0.264995,-0.11656400000000001,-0.19861099999999998,-0.29338200000000003 +80,80,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +81,81,20210621,0.0,0.253137,1.5486010000000001,1.525938,1.6682310000000002,0.414415,-0.181597,-0.150836,0.044462,0.071389,-0.126411,-0.246783,-0.248683,-0.124626 +82,82,20210621,0.0,-0.616452,-0.377707,-0.30044,-0.23956100000000002,-0.157977,2.297656,-0.649433,-0.052381,-0.109423,-0.12073199999999999,9.068992999999999,-0.301307,-0.126708 +83,83,20210621,1.0,0.253137,-0.338147,-0.305006,-0.27261199999999997,-0.330629,-0.335752,-0.320735,-0.24679,-0.204343,-0.259997,-0.25903899999999996,-0.239519,-0.29338200000000003 +84,84,20210621,0.0,0.253137,1.091493,1.262859,1.150799,0.9508059999999999,1.06386,0.926673,0.304076,-0.256859,-0.123571,-0.11656400000000001,-0.10468499999999999,-0.135877 +85,85,20210621,0.0,0.253137,-0.03143,-0.018491,-0.368058,-0.355174,-0.344913,-0.325588,-0.240752,-0.20048,-0.257044,-0.263443,-0.25856599999999996,-0.24691799999999997 +86,86,20210621,0.0,0.253137,1.0702120000000002,0.823757,0.359358,1.168241,1.284549,1.3693030000000002,-0.076289,-0.10304300000000001,4.246932,-0.020814,4e-05,-0.040248 +87,87,20210621,1.0,-0.616452,-0.690345,-0.674545,-0.6666810000000001,-0.666435,-0.656644,-0.646175,-0.271302,-0.25699,-0.29680100000000004,-0.283168,-0.288609,-0.271444 +88,88,20210621,0.0,-0.616452,-0.643683,-0.6242300000000001,-0.582699,-0.5387529999999999,-0.5467350000000001,-0.639862,-0.27269099999999996,-0.17018599999999998,-0.18320799999999998,-0.30806300000000003,-0.263999,-0.16383399999999998 +89,89,20210621,0.0,-0.616452,0.40863499999999997,0.965076,-0.42211800000000005,-0.6518229999999999,-0.546357,-0.632742,2.073079,-0.03998,-0.221262,0.144832,-0.23624699999999998,-0.175816 +90,90,20210621,0.0,1.992316,-0.57908,-0.5743229999999999,-0.5387609999999999,-0.509467,-0.460513,-0.45172700000000005,-0.341942,-0.185333,-0.24000500000000002,-0.180397,-0.314136,-0.209004 +91,91,20210621,1.0,1.992316,1.1809209999999999,1.286941,1.376341,1.5674219999999999,1.7568979999999998,1.8581599999999998,0.038424,-0.018279,0.015580000000000002,0.043018,0.013131,-0.012121999999999999 +92,92,20210621,0.0,-1.486041,-0.5934619999999999,-0.690983,-0.62071,-0.612371,-0.6630590000000001,-0.652724,-0.341942,-0.084771,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +93,93,20210621,0.0,-1.486041,-0.722803,-0.612934,-0.677929,-0.672497,-0.6630590000000001,-0.652724,0.114195,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +94,94,20210621,0.0,-1.486041,-0.6836909999999999,-0.668475,-0.665816,-0.6594399999999999,-0.6630590000000001,-0.652724,-0.24522,-0.220532,-0.249092,-0.30806300000000003,-0.314136,0.141783 +95,95,20210621,0.0,0.253137,-0.07571599999999999,-0.032724,0.002896,-0.367904,-0.34710100000000005,-0.328258,-0.224994,-0.200524,-0.25806599999999996,-0.264018,-0.260726,-0.246412 +96,96,20210621,0.0,0.253137,0.441391,0.517291,0.586026,-0.11965999999999999,-0.154112,-0.134951,-0.123322,-0.100873,-0.22983800000000001,-0.23708,-0.24187600000000004,-0.229086 +97,97,20210621,0.0,0.253137,-0.641768,-0.574056,-0.628987,-0.57222,-0.229314,-0.485546,0.16153,-0.10968399999999999,0.435989,1.415426,-0.314136,3.586763 +98,98,20210621,0.0,0.253137,0.472409,0.518864,0.605536,0.723003,0.779878,0.032177,-0.09856799999999999,0.17729,-0.111303,-0.050178,-0.202996,-0.248381 +99,99,20210621,0.0,0.253137,-0.44138599999999995,-0.435829,-0.432832,-0.468088,-0.517227,-0.5200859999999999,-0.256752,-0.205168,-0.275275,-0.290126,-0.293126,-0.2823 +100,100,20210621,1.0,-0.616452,-0.451558,-0.41886999999999996,-0.395888,-0.388967,-0.368171,-0.650205,-0.239364,-0.193623,-0.261247,-0.196355,-0.304318,-0.29338200000000003 +101,101,20210621,0.0,-1.486041,-0.686516,-0.547501,-0.665672,-0.666046,-0.6614140000000001,-0.6287119999999999,0.274613,-0.220098,-0.273231,-0.301679,-0.220538,-0.29338200000000003 +102,102,20210621,0.0,0.253137,-0.696742,-0.695241,-0.20964000000000002,-0.161226,-0.11098399999999999,-0.08086499999999999,-0.32847800000000005,1.1829969999999999,-0.230292,-0.23165500000000003,-0.232319,-0.012121999999999999 +103,103,20210621,0.0,0.253137,5.036294,5.369524,6.235469999999999,6.898658999999999,7.086529,7.238735,0.628776,2.16019,0.6687420000000001,-0.30806300000000003,0.864025,1.067915 +104,104,20210621,1.0,0.253137,-0.08861799999999999,-0.0973,-0.12496600000000001,-0.16736600000000001,-0.27689899999999995,-0.248144,-0.235258,-0.197876,-0.239891,-0.254443,-0.24900999999999998,-0.24253000000000002 +105,105,20210621,0.0,0.253137,0.074173,0.084709,0.175374,0.263556,0.248957,0.275943,-0.341942,-0.03998,-0.154185,-0.30768,-0.117776,-0.124626 +106,106,20210621,0.0,-0.616452,-0.619862,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.207256,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,1.422276,-0.180878 +107,107,20210621,0.0,-0.616452,-0.612692,-0.6507850000000001,-0.630674,-0.620905,-0.644143,-0.633414,-0.169207,-0.114675,-0.108293,-0.23465500000000003,-0.23886500000000002,-0.235161 +108,108,20210621,0.0,-0.616452,-0.685959,-0.659061,-0.667517,-0.6590199999999999,-0.644143,-0.564349,-0.204768,-0.22565300000000002,-0.247559,-0.23465500000000003,0.030345,-0.011504 +109,109,20210621,0.0,-0.616452,1.632583,1.815347,-0.101995,1.2003409999999999,0.062761,1.472572,0.316635,-0.25699,7.29447,-0.016600999999999998,8.446209,-0.023597999999999997 +110,110,20210621,0.0,-1.486041,-0.697041,-0.692431,-0.6794140000000001,-0.674098,-0.6647529999999999,-0.654454,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +111,111,20210621,0.0,0.253137,0.742255,0.8325110000000001,0.844735,0.9735940000000001,1.088549,1.148844,0.21713600000000002,-0.25699,-0.092731,-0.046348,0.719634,-0.29338200000000003 +112,112,20210621,0.0,0.253137,-0.515781,-0.484134,-0.45901899999999995,-0.42490600000000006,-0.388847,-0.360666,-0.221191,-0.213588,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.23713 +113,113,20210621,0.0,2.861905,1.146874,1.25544,1.2660719999999999,1.5721319999999999,1.8399619999999999,1.8562130000000001,0.050499,-0.25699,0.512778,0.6398560000000001,-0.314136,-0.012121999999999999 +114,114,20210621,0.0,0.253137,0.012286,0.049358,0.107628,0.19917100000000001,0.325491,0.349961,-0.221191,-0.14080299999999998,-0.12209500000000001,0.016209,-0.117776,-0.17902200000000001 +115,115,20210621,0.0,0.253137,-0.437407,-0.419896,-0.385794,-0.35735,-0.328975,-0.317612,-0.261038,-0.20035,-0.257044,-0.262231,-0.266748,-0.254906 +116,116,20210621,1.0,1.992316,-0.448489,-0.44344399999999995,-0.40926999999999997,-0.341106,-0.322708,-0.296723,-0.341942,-0.200046,-0.126411,-0.30806300000000003,-0.248683,-0.23713 +117,117,20210621,0.0,-0.616452,-0.6912149999999999,-0.686403,-0.6732279999999999,-0.584267,-0.655229,-0.64725,-0.322259,-0.24284099999999997,0.025577000000000003,-0.27767800000000004,-0.292798,-0.26379400000000003 +118,118,20210621,1.0,0.253137,-0.50512,-0.473301,-0.43812399999999996,-0.407387,-0.373089,-0.34735,-0.221191,-0.183206,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.23713 +119,119,20210621,0.0,-0.616452,-0.428648,-0.5551729999999999,-0.506807,-0.5506449999999999,-0.419013,-0.519079,0.242312,0.25806,0.148428,0.639026,0.20680700000000002,0.027929000000000002 +120,120,20210621,0.0,-0.616452,-0.013163999999999999,0.031837,0.086546,0.143258,-0.64156,-0.632524,-0.221191,-0.12678399999999998,-0.126411,-0.224633,-0.235396,-0.261712 +121,121,20210621,1.0,1.992316,-0.070881,-0.045004,0.027973,0.086863,0.148144,0.20605500000000002,-0.281566,-0.081863,-0.24000500000000002,-0.218696,-0.130867,-0.29338200000000003 +122,122,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +123,123,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +124,124,20210621,1.0,0.253137,3.446309,3.6820910000000002,3.7391129999999997,3.3474440000000003,3.3913269999999995,2.6869669999999997,0.444087,0.22598600000000002,0.18068800000000002,0.240837,0.133107,0.043398 +125,125,20210621,0.0,0.253137,-0.43604899999999996,-0.42456099999999997,-0.399652,-0.371278,-0.33874499999999996,-0.39026900000000003,-0.25717399999999996,-0.207945,-0.262723,-0.253102,-0.293649,-0.29338200000000003 +126,126,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +127,127,20210621,0.0,0.253137,0.800271,0.707448,0.748943,0.8961520000000001,1.0335290000000001,1.11029,-0.126522,-0.10139400000000001,-0.09222000000000001,-0.062433,-0.073988,-0.080525 +128,128,20210621,1.0,0.253137,1.527986,0.944787,0.7536579999999999,0.816129,0.944823,0.9580559999999999,-0.060894000000000004,-0.140239,-0.179403,-0.17133199999999998,-0.169026,-0.23713 +129,129,20210621,1.0,0.253137,-0.650188,-0.636201,-0.612996,-0.589381,-0.5582,-0.5338890000000001,-0.281566,-0.210723,-0.222966,-0.212313,-0.235592,-0.285844 +130,130,20210621,0.0,0.253137,0.12626800000000002,0.17241099999999998,0.147529,-0.223994,-0.17766600000000002,-0.206954,-0.190761,-0.256686,-0.228645,-0.231463,-0.242137,-0.209004 +131,131,20210621,0.0,-0.616452,-0.64132,-0.6116689999999999,-0.627343,-0.672917,-0.436992,-0.553552,-0.0011220000000000002,-0.104736,-0.295268,0.5709810000000001,0.072759,-0.123276 +132,132,20210621,0.0,-0.616452,-0.6943520000000001,-0.654143,-0.630328,-0.623315,-0.657137,-0.6235569999999999,-0.183637,-0.11372,-0.29680100000000004,-0.285083,-0.200444,-0.241405 +133,133,20210621,0.0,0.253137,2.746407,2.789893,2.624953,2.762057,2.8010759999999997,2.505935,0.24635700000000002,0.157628,0.135024,0.191749,0.160597,0.343727 +134,134,20210621,0.0,0.253137,2.39243,2.5226,2.6335330000000003,2.86521,3.083479,3.1792,0.15374100000000002,0.094349,0.158992,0.213772,0.235083,0.167884 +135,135,20210621,0.0,0.253137,-0.309248,-0.323637,-0.292742,-0.278446,-0.373517,-0.665822,-0.221191,-0.19622699999999998,-0.29680100000000004,-0.276146,-0.314136,-0.205629 +136,136,20210621,0.0,1.992316,-0.550683,-0.521887,-0.480649,-0.466238,-0.43018199999999995,-0.41947,-0.25137800000000005,-0.178866,-0.29680100000000004,-0.24423000000000003,-0.314136,-0.274988 +137,137,20210621,0.0,0.253137,-0.458742,-0.419221,-0.360689,-0.289887,-0.215662,-0.145127,-0.191003,-0.12678399999999998,-0.126411,-0.11656400000000001,-0.085049,-0.012121999999999999 +138,138,20210621,0.0,0.253137,-0.5983229999999999,-0.578623,-0.551148,-0.52966,-0.59062,-0.5568770000000001,-0.25137800000000005,-0.191887,-0.24000500000000002,-0.276146,-0.183229,-0.262669 +139,139,20210621,1.0,-1.486041,-0.685429,-0.686768,-0.5931390000000001,-0.672497,-0.6630590000000001,-0.652724,-0.323829,-0.0017870000000000002,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +140,140,20210621,0.0,0.253137,-0.0057350000000000005,0.013543000000000001,0.0371,-0.370469,-0.344371,-0.33376500000000003,-0.199455,-0.183206,-0.24000500000000002,-0.25061300000000003,-0.25719200000000003,-0.173565 +141,141,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +142,142,20210621,0.0,-0.616452,-0.670762,-0.690983,-0.665931,-0.667337,-0.656216,-0.6457390000000001,-0.341942,-0.238934,-0.277945,-0.276146,-0.085049,-0.24658000000000002 +143,143,20210621,0.0,0.253137,-0.558057,-0.538776,-0.38112199999999996,-0.361671,-0.336081,-0.349382,-0.281566,0.177029,-0.27408299999999997,-0.26338,-0.261773,-0.259631 +144,144,20210621,0.0,-1.486041,-0.530516,-0.55048,-0.533729,-0.517053,-0.498854,-0.386642,0.261814,0.177029,0.271165,0.329181,0.724151,0.269137 +145,145,20210621,0.0,-0.616452,-0.679359,-0.471995,-0.672968,-0.636123,-0.552821,-0.6470319999999999,0.599071,-0.24205900000000002,-0.16389700000000001,-0.00792,-0.29194699999999996,-0.274819 +146,146,20210621,0.0,2.861905,-0.627753,-0.607904,-0.572447,-0.529566,-0.48831099999999994,-0.48249,-0.281566,-0.191887,-0.18320799999999998,-0.207015,-0.242137,-0.29338200000000003 +147,147,20210621,1.0,0.253137,-0.433958,-0.405579,-0.377243,-0.399537,-0.368336,-0.49991899999999995,-0.24165799999999998,-0.204907,-0.276866,-0.28520999999999996,-0.302224,-0.29338200000000003 +148,148,20210621,0.0,0.253137,1.982935,1.784577,0.6641239999999999,1.436383,1.5119639999999999,0.352681,0.14106300000000002,-0.03998,2.855414,0.011101999999999999,0.013131,0.18475899999999998 +149,149,20210621,0.0,0.253137,-0.5711350000000001,-0.543146,-0.5307729999999999,-0.5186390000000001,-0.496551,-0.45065299999999997,-0.24232199999999998,-0.25699,-0.29680100000000004,-0.28386999999999996,-0.17727300000000001,-0.29332600000000003 +150,150,20210621,0.0,-0.616452,-0.71058,-0.706439,-0.369341,-0.672497,-0.64712,-0.6381319999999999,-0.341942,0.7195520000000001,-0.29680100000000004,-0.24620799999999998,-0.248683,-0.29338200000000003 +151,151,20210621,0.0,0.253137,0.48080200000000006,0.406939,0.307475,0.332418,0.296196,0.275036,-0.13334400000000002,-0.12201,-0.012818000000000001,-0.30806300000000003,-0.17668399999999998,-0.147015 +152,152,20210621,0.0,0.253137,-0.119228,0.09224,-0.051006,-0.033824,0.026969,-0.11831099999999999,1.469324,-0.12678399999999998,0.043979000000000004,0.202601,-0.183229,0.494145 +153,153,20210621,0.0,-1.486041,-0.692817,-0.650153,-0.663509,-0.662704,-0.6630590000000001,-0.652724,-0.16649,-0.213588,-0.261019,-0.30806300000000003,-0.314136,-0.29338200000000003 +154,154,20210621,0.0,0.253137,2.139641,1.871099,1.229214,0.90966,2.250695,2.190301,0.143598,0.033803,-0.005037,6.075229,0.144038,0.062186 +155,155,20210621,0.0,0.253137,-0.573227,-0.544775,-0.513152,-0.486975,-0.44784799999999997,-0.414181,-0.23930300000000002,-0.191887,-0.24000500000000002,-0.212313,-0.21595599999999998,-0.209004 +156,156,20210621,0.0,0.253137,-0.370469,-0.296885,-0.215437,-0.002082,0.11143099999999999,0.165016,-0.040063999999999995,-0.03998,0.378227,0.011101999999999999,-0.117776,0.016229 +157,157,20210621,0.0,0.253137,0.736021,0.7543770000000001,0.614721,0.741081,0.8585020000000001,0.926219,-0.10044,-0.115933,-0.11221199999999999,-0.084647,-0.081122,-0.012121999999999999 +158,158,20210621,0.0,0.253137,1.9665700000000002,2.064895,2.0550029999999997,1.9259540000000002,1.754447,1.401308,0.0988,0.051511,0.139397,0.087702,0.013131,-0.040248 +159,159,20210621,1.0,5.470672,0.876784,1.0358610000000001,1.1944620000000001,1.461394,1.7307279999999998,1.934966,0.290673,0.197775,0.332392,0.39907800000000004,0.45022799999999996,0.296026 +160,160,20210621,0.0,0.253137,-0.521077,-0.517293,-0.484023,-0.46378199999999997,-0.43753400000000003,-0.416246,-0.341942,-0.187547,-0.268403,-0.276146,-0.274864,-0.259631 +161,161,20210621,0.0,0.253137,-0.36486,-0.305259,-0.29265599999999997,-0.23464200000000002,-0.20942800000000003,-0.17716600000000002,-0.130627,-0.25699,-0.171849,-0.30806300000000003,-0.235592,-0.22306700000000002 +162,162,20210621,0.0,1.992316,-0.690345,-0.685504,-0.6666810000000001,-0.66914,-0.6452939999999999,-0.6436569999999999,-0.318395,-0.223136,-0.284533,-0.252911,-0.314136,-0.271444 +163,163,20210621,0.0,-0.616452,-0.678883,-0.685419,-0.672218,-0.6601859999999999,-0.6565449999999999,-0.645621,-0.318033,-0.239802,-0.251818,-0.30806300000000003,-0.28644899999999995,-0.272625 +164,164,20210621,0.0,0.253137,1.222246,1.5129270000000001,1.511615,1.702736,1.902844,2.037647,0.744455,-0.25699,0.013819999999999999,0.052976,0.131667,-0.072875 +165,165,20210621,0.0,0.253137,-0.40844,-0.356543,-0.318756,-0.267814,-0.22462600000000002,-0.18665299999999999,-0.160815,-0.191887,-0.211606,-0.24423000000000003,-0.21595599999999998,-0.209004 +166,166,20210621,0.0,0.253137,0.6846869999999999,0.781423,0.8340780000000001,0.489246,0.587975,0.644504,-0.009876000000000001,-0.08772200000000001,-0.126411,-0.122947,-0.117776,-0.135877 +167,167,20210621,0.0,-1.486041,-0.612895,-0.47840200000000005,-0.5596270000000001,-0.433144,-0.584238,-0.426825,0.586815,0.099079,0.5786060000000001,-0.002175,0.566408,-0.029054000000000003 +168,168,20210621,0.0,0.253137,0.6943159999999999,0.669751,0.170312,-0.216486,-0.28509,-0.656855,-0.150793,-0.25699,-0.221262,-0.218824,-0.31335100000000005,2.519214 +169,169,20210621,0.0,1.992316,0.28368000000000004,0.34669099999999997,0.411155,0.52935,0.749071,0.8298180000000001,-0.130627,-0.105083,-0.08938,0.33026700000000003,-0.052323,-0.29338200000000003 +170,170,20210621,0.0,0.253137,-0.314843,-0.282231,-0.254472,-0.241342,-0.197272,-0.169022,-0.250775,-0.194404,-0.241027,-0.243144,-0.230552,-0.26148699999999997 +171,171,20210621,0.0,0.253137,-0.183722,-0.221744,-0.237629,-0.243502,-0.229742,-0.238959,-0.040063999999999995,-0.17018599999999998,-0.126411,-0.05273099999999999,-0.117776,-0.180878 +172,172,20210621,0.0,-0.616452,-0.686298,-0.644898,-0.677929,-0.605035,-0.619108,-0.6392909999999999,-0.143427,-0.25699,-0.050304,-0.137501,-0.261773,-0.251418 +173,173,20210621,0.0,0.253137,-0.5792970000000001,-0.476392,-0.509936,-0.5565829999999999,-0.611822,-0.523008,0.5636909999999999,-0.213588,-0.288339,-0.30806300000000003,0.013131,0.269137 +174,174,20210621,1.0,-1.486041,-0.70527,-0.7009449999999999,-0.6881520000000001,-0.717545,-0.716878,-0.707667,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +175,175,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.676818,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.253648,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +176,176,20210621,1.0,2.861905,0.181894,0.236031,0.29227600000000004,0.393181,0.53432,0.5452819999999999,-0.160815,-0.12678399999999998,-0.126411,0.043018,-0.314136,-0.29338200000000003 +177,177,20210621,0.0,0.253137,-0.6116189999999999,-0.689578,-0.669277,-0.6501439999999999,-0.631494,-0.562385,-0.311512,-0.235289,-0.24000500000000002,-0.276146,-0.085049,-0.29338200000000003 +178,178,20210621,0.0,1.992316,-0.032095,-0.019362,0.019465,-0.202729,-0.28676799999999997,-0.277244,-0.341942,-0.191887,-0.24000500000000002,-0.180397,-0.314136,-0.180878 +179,179,20210621,0.0,0.253137,-0.478339,-0.51364,-0.487282,-0.46839899999999995,-0.43222200000000005,-0.402427,-0.268766,-0.204864,-0.268403,-0.212313,-0.21595599999999998,-0.23713 +180,180,20210621,0.0,0.253137,0.362053,0.45848999999999995,0.479275,0.28297100000000003,-0.48768599999999995,-0.459854,0.008236,-0.213588,-0.262723,-0.282529,-0.248683,-0.29338200000000003 +181,181,20210621,0.0,-0.616452,-0.529796,-0.31755300000000003,-0.312656,-0.258938,-0.23081100000000002,-0.631634,0.5636909999999999,-0.25699,-0.18320799999999998,-0.30806300000000003,-0.231927,3.4155889999999998 +182,182,20210621,0.0,0.253137,-0.021937,-0.51659,-0.46346000000000004,-0.402584,-0.37077,-0.359541,0.41275200000000006,0.025123,-0.126411,-0.180397,-0.117776,-0.180878 +183,183,20210621,0.0,0.253137,0.070601,0.8632110000000001,0.913172,1.238953,1.1270879999999999,0.523772,3.8849489999999998,1.060561,1.4070989999999999,0.9685959999999999,3.1014169999999996,0.831656 +184,184,20210621,1.0,0.253137,0.09235700000000001,0.122406,0.026329,-0.377604,-0.34522600000000003,-0.327049,-0.191003,-0.187547,-0.126411,-0.24423000000000003,-0.265897,-0.180878 +185,185,20210621,0.0,-0.616452,-0.551117,-0.526917,-0.48946000000000006,-0.481612,-0.636494,-0.625522,-0.269491,-0.18785,-0.262666,-0.29944499999999996,-0.194749,-0.29338200000000003 +186,186,20210621,1.0,0.253137,-0.498954,-0.49482600000000004,-0.456971,-0.419621,-0.402055,-0.37653400000000004,-0.341942,-0.187547,-0.211606,-0.30806300000000003,-0.248683,-0.209004 +187,187,20210621,0.0,-0.616452,-0.660115,0.11096900000000001,-0.60169,0.39144,-0.434738,-0.38002600000000003,3.104716,-0.027177,3.591158,0.578513,0.7494810000000001,1.861798 +188,188,20210621,1.0,1.992316,2.012812,2.160494,2.118624,2.3770990000000003,2.629289,2.536278,0.15398299999999998,0.046824,0.089416,0.147321,-0.314136,0.091156 +189,189,20210621,0.0,0.253137,-0.695642,-0.615168,-0.5298350000000001,-0.461466,-0.435018,-0.40696,-0.016155000000000003,-0.03998,-0.098013,-0.276082,-0.248683,-0.180878 +190,190,20210621,0.0,1.992316,-0.400903,-0.394704,-0.368462,-0.348629,-0.330488,-0.308712,-0.341942,-0.213588,-0.29680100000000004,-0.30806300000000003,-0.264392,-0.29338200000000003 +191,191,20210621,0.0,0.253137,0.11784800000000001,0.182204,0.217581,0.351491,0.330212,0.07482799999999999,0.263021,0.004767,0.274403,0.012889,0.017058,-0.05583 +192,192,20210621,1.0,0.253137,-0.429123,-0.40510100000000004,-0.365462,-0.314898,-0.292986,-0.26864699999999997,-0.260918,-0.18476900000000002,-0.18320799999999998,-0.30806300000000003,-0.255228,-0.24579299999999998 +193,193,20210621,0.0,0.253137,-0.541014,-0.688187,-0.677929,-0.672497,-0.379702,-0.36656,-0.329927,-0.25699,-0.29680100000000004,0.791587,-0.291817,-0.00571 +194,194,20210621,0.0,-1.486041,-0.49641499999999994,-0.380653,-0.37104299999999996,-0.513944,-0.6630590000000001,-0.652724,1.9442979999999999,-0.25699,-0.28544200000000003,-0.30806300000000003,-0.314136,-0.29338200000000003 +195,195,20210621,0.0,-0.616452,-0.046626999999999995,-0.436475,-0.414764,-0.672715,-0.661874,-0.641675,-0.221191,-0.213588,-0.18320799999999998,-0.276146,-0.248683,0.832275 +196,196,20210621,1.0,1.992316,-0.204487,-0.168479,-0.13458399999999998,-0.074628,-0.01782,0.019533000000000002,-0.227228,-0.19622699999999998,-0.200247,-0.210271,-0.209411,-0.29338200000000003 +197,197,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.670694,-0.6630590000000001,-0.627537,-0.341942,-0.25699,-0.290213,-0.30806300000000003,-0.21595599999999998,-0.29338200000000003 +198,198,20210621,0.0,0.253137,-0.44368199999999997,-0.41776,-0.403012,-0.542981,-0.35270999999999997,-0.329534,-0.25137800000000005,-0.21219899999999997,-0.266074,0.9685959999999999,-0.268777,-0.23713 +199,199,20210621,0.0,-0.616452,-0.6900470000000001,-0.689044,-0.644777,-0.653051,-0.6432220000000001,-0.633397,-0.33361,-0.157209,-0.22574899999999998,-0.23108,-0.23879899999999998,0.596298 +200,200,20210621,1.0,0.253137,-0.30167,-0.279926,-0.27241,-0.20871399999999998,-0.6362479999999999,-0.652724,-0.281566,-0.2533,-0.199452,-0.30142399999999997,-0.314136,-0.29338200000000003 +201,201,20210621,0.0,-1.486041,-0.6854560000000001,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +202,202,20210621,0.0,1.992316,-0.32729600000000003,-0.307423,-0.41858500000000004,-0.358111,-0.21225700000000003,-0.470819,1.167446,-0.25699,-0.126411,0.189834,-0.314136,-0.152752 +203,203,20210621,0.0,-0.616452,-0.513336,-0.43807700000000005,-0.49045500000000003,-0.58206,-0.440906,-0.644547,0.261814,0.307278,0.034948,0.5540649999999999,-0.28226,0.100606 +204,204,20210621,0.0,0.253137,0.7617430000000001,0.862677,0.962142,1.130655,1.296457,1.398134,-0.040063999999999995,-0.03998,-0.06098200000000001,0.011101999999999999,0.013131,-0.012121999999999999 +205,205,20210621,0.0,0.253137,2.379406,2.566985,2.699115,2.284222,2.191679,1.807449,0.20747600000000002,0.05984400000000001,0.032619,0.049402,0.052403,-0.062749 +206,206,20210621,0.0,0.253137,-0.692559,-0.405045,-0.386112,-0.371884,-0.34313699999999997,-0.328022,1.007995,-0.20035,-0.22535100000000002,-0.21493,-0.087864,-0.19775399999999999 +207,207,20210621,0.0,-0.616452,-0.690345,-0.670287,-0.672305,-0.666435,-0.656644,-0.652724,-0.253008,-0.240063,-0.27465100000000003,-0.283168,-0.314136,-0.159502 +208,208,20210621,1.0,-0.616452,-0.653705,-0.6687,-0.672983,-0.614004,-0.648633,-0.652724,-0.24618600000000002,-0.242103,-0.083075,-0.252081,-0.314136,-0.269813 +209,209,20210621,1.0,0.253137,0.412872,0.454879,0.469887,0.09776,0.151286,0.179608,-0.14874,-0.12678399999999998,-0.18105,-0.180397,-0.19632,-0.192129 +210,210,20210621,0.0,-1.486041,-0.575155,-0.630047,-0.636774,-0.646227,-0.6630590000000001,-0.624027,-0.07961,-0.13312100000000002,-0.200133,-0.30806300000000003,-0.202276,-0.278869 +211,211,20210621,0.0,-0.616452,0.7385609999999999,0.839339,0.9301870000000001,-0.543432,-0.6630590000000001,0.785185,-0.040063999999999995,-0.03781,0.174781,-0.30806300000000003,5.290767,-0.29338200000000003 +212,212,20210621,1.0,-0.616452,-0.695642,-0.690983,-0.6743239999999999,-0.670585,-0.650081,-0.632205,-0.341942,-0.246139,-0.29680100000000004,-0.257698,-0.234152,0.247536 +213,213,20210621,0.0,0.253137,-0.17609,-0.14441099999999998,-0.128484,-0.109681,-0.11799100000000001,-0.12648800000000002,-0.23930300000000002,-0.19171300000000002,-0.228645,-0.212313,-0.21595599999999998,-0.23713 +214,214,20210621,0.0,0.253137,-0.310674,-0.296056,-0.412774,-0.47054399999999996,-0.535814,-0.517853,-0.158642,-0.156775,-0.29680100000000004,-0.24423000000000003,-0.183229,-0.285057 +215,215,20210621,0.0,0.253137,3.3319870000000003,3.5707699999999996,3.761161,6.78848,4.356091999999999,4.552025,0.44293999999999994,0.22047399999999998,-0.29680100000000004,0.361162,0.395248,0.28978200000000004 +216,216,20210621,0.0,1.992316,-0.690345,-0.685504,-0.672305,-0.668767,-0.641347,-0.6396270000000001,-0.318395,-0.240063,-0.28317,-0.21422800000000003,-0.314136,-0.29338200000000003 +217,217,20210621,1.0,-1.486041,-0.708489,-0.704275,-0.69157,-0.6872020000000001,-0.678619,-0.668609,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +218,218,20210621,0.0,0.253137,0.380998,0.411983,0.45453000000000005,0.5713050000000001,0.590886,0.661145,-0.154778,-0.105083,-0.10369300000000001,-0.11656400000000001,-0.085049,-0.124626 +219,219,20210621,0.0,0.253137,0.52646,0.492464,0.46540299999999996,0.467142,0.386646,0.408648,-0.10044,-0.03998,-0.126411,-0.11656400000000001,-0.117776,0.210298 +220,220,20210621,0.0,-1.486041,-0.676303,-0.627167,-0.6761119999999999,-0.672497,-0.6630590000000001,-0.652724,-0.067716,-0.251521,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +221,221,20210621,1.0,0.253137,0.732586,0.931383,0.9393729999999999,1.110292,1.275305,1.36628,0.382565,-0.25699,0.038299,0.011101999999999999,-0.019596000000000002,-0.028998000000000003 +222,222,20210621,0.0,0.253137,3.8565099999999997,4.015239,4.160362999999999,4.517161,4.85966,4.890579,0.40599,0.28023899999999996,0.391347,0.48665699999999995,0.485246,0.363528 +223,223,20210621,0.0,0.253137,3.264709,3.4857370000000003,2.2872369999999997,2.682407,2.765843,2.915653,0.383712,0.133888,0.6687420000000001,0.45793199999999995,0.311402,0.550397 +224,224,20210621,0.0,0.253137,0.549058,0.63027,0.8880379999999999,0.352082,0.057464,-0.094181,0.264349,0.560354,-0.176563,-0.175545,0.016076,-0.08221200000000001 +225,225,20210621,1.0,0.253137,0.019049,0.03313,0.031606,-0.20004,-0.165511,-0.149694,-0.341942,-0.255948,-0.211606,-0.24423000000000003,-0.235527,1.427477 +226,226,20210621,0.0,0.253137,1.074857,1.152409,1.180807,1.278545,1.430495,1.5107059999999999,0.052311,-0.046056,0.981124,-0.000388,0.0050799999999999994,-0.01426 +227,227,20210621,0.0,-1.486041,-0.651301,-0.6532439999999999,-0.65105,-0.663652,-0.6630590000000001,-0.652724,-0.179773,-0.17608800000000002,-0.264484,-0.30806300000000003,-0.314136,-0.29338200000000003 +228,228,20210621,0.0,0.253137,-0.472174,-0.45899799999999996,-0.405362,-0.38076,-0.356296,-0.330743,-0.244797,-0.12678399999999998,-0.25914499999999996,-0.264912,-0.259548,-0.24939299999999998 +229,229,20210621,1.0,0.253137,-0.0199,-0.010159,-0.041777,-0.342225,-0.333005,-0.336066,-0.19698,-0.159162,-0.182981,-0.26312399999999997,-0.267861,-0.236905 +230,230,20210621,0.0,0.253137,-0.43551999999999996,-0.435759,-0.429429,-0.5538930000000001,-0.634603,-0.652724,-0.341942,-0.19913499999999998,-0.268403,-0.301679,-0.314136,-0.113376 +231,231,20210621,0.0,0.253137,-0.219181,-0.18803699999999998,-0.231818,-0.370625,-0.492242,-0.630761,-0.215757,-0.170099,-0.239891,-0.29286999999999996,-0.24796300000000002,-0.2715 +232,232,20210621,1.0,0.253137,-0.420839,-0.450273,-0.434866,-0.410185,-0.441762,-0.48306099999999996,-0.341942,-0.204907,-0.24000500000000002,-0.30806300000000003,-0.248683,0.269137 +233,233,20210621,0.0,0.253137,0.70044,-0.690983,-0.677929,-0.631709,0.08644600000000001,0.129048,-0.341942,-0.25699,-0.147767,2.600612,-0.19978900000000002,-0.180878 +234,234,20210621,1.0,1.992316,1.067129,1.154994,1.259814,1.539831,1.641693,1.866909,-0.040063999999999995,-0.03998,0.271165,-0.30806300000000003,0.47902799999999995,-0.13762 +235,235,20210621,0.0,0.253137,0.094788,-0.180014,-0.37606100000000003,-0.350821,-0.331212,-0.326612,-0.25101599999999996,-0.200654,-0.24000500000000002,-0.26203899999999997,-0.26105300000000004,-0.259687 +236,236,20210621,0.0,-0.616452,-0.58716,-0.635105,-0.5791810000000001,-0.645776,-0.640393,-0.317863,-0.101466,0.040443,-0.199168,-0.22010100000000002,0.991135,-0.157365 +237,237,20210621,0.0,0.253137,1.034549,0.855258,0.06537799999999999,0.017426,-0.056112,-0.157418,-0.070252,-0.181253,-0.207858,-0.230952,-0.24364299999999997,-0.151121 +238,238,20210621,0.0,-0.616452,-0.676086,-0.690983,-0.570904,-0.658616,-0.5630189999999999,-0.614221,-0.341942,0.065139,-0.24608200000000002,0.080169,-0.164052,-0.107807 +239,239,20210621,1.0,0.253137,2.484995,2.564048,2.417204,2.555176,2.7972759999999997,2.9523599999999997,0.26881700000000003,0.140138,0.158026,0.202601,0.21008000000000002,0.140545 +240,240,20210621,1.0,0.253137,-0.43291199999999996,-0.38597800000000004,-0.347134,-0.376096,-0.39315700000000003,-0.377625,-0.160815,-0.17018599999999998,-0.17196199999999998,-0.24423000000000003,-0.117776,-0.158434 +241,241,20210621,0.0,-0.616452,-0.403646,-0.400844,-0.677929,-0.672497,-0.6630590000000001,-0.614355,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.164575,-0.29338200000000003 +242,242,20210621,0.0,0.253137,-0.054992,-0.016932,0.023315,0.11720599999999999,-0.156628,-0.38617199999999996,-0.23326599999999997,-0.17018599999999998,-0.126411,-0.180397,-0.183229,-0.180878 +243,243,20210621,0.0,0.253137,-0.333652,-0.301451,-0.264421,-0.237409,-0.18950899999999998,-0.159064,-0.23326599999999997,-0.181036,-0.245684,-0.231463,-0.235592,-0.23150500000000002 +244,244,20210621,0.0,-0.616452,-0.653012,-0.608747,-0.63725,-0.672497,-0.616658,-0.652724,-0.171622,-0.25699,-0.29680100000000004,-0.12799000000000002,-0.314136,-0.283482 +245,245,20210621,0.0,1.992316,-0.693713,-0.687963,-0.675924,-0.6722020000000001,-0.6627460000000001,-0.6513979999999999,-0.320508,-0.251781,-0.29680100000000004,-0.30806300000000003,-0.310209,-0.290007 +246,246,20210621,0.0,-1.486041,-0.426529,-0.404412,-0.388058,-0.368215,-0.6630590000000001,-0.652724,-0.24528000000000003,-0.161375,-0.176733,-0.30806300000000003,-0.314136,-0.29338200000000003 +247,247,20210621,0.0,-0.616452,0.022417,-0.668067,-0.65578,-0.6567970000000001,-0.571408,-0.639392,-0.24346900000000002,-0.190324,-0.23943699999999998,0.047614,-0.262166,-0.22678 +248,248,20210621,0.0,0.253137,-0.182745,-0.20685,-0.24481,-0.200926,-0.15320699999999998,-0.100209,-0.23399,-0.17890999999999999,-0.234325,-0.23465500000000003,-0.15554300000000001,-0.29338200000000003 +249,249,20210621,0.0,0.253137,-0.069035,-0.047744,0.016235,0.122398,-0.014169,-0.226919,-0.190761,-0.083078,-0.009637,-0.30333899999999997,-0.247177,-0.14904 +250,250,20210621,0.0,0.253137,-0.210639,-0.47472,-0.44578100000000004,-0.417289,-0.387301,-0.359138,-0.24769499999999997,-0.201956,-0.263462,-0.269061,-0.248683,-0.180878 +251,251,20210621,0.0,0.253137,-0.004839,0.032413,0.026761,-0.204377,-0.177386,-0.149006,-0.23869899999999997,-0.251087,-0.228304,-0.180269,-0.182902,-0.124458 +252,252,20210621,0.0,0.253137,-0.298519,-0.2764,-0.25751399999999997,-0.279923,-0.301177,-0.652724,-0.039702,-0.202998,-0.248467,-0.247102,-0.314136,-0.29338200000000003 +253,253,20210621,1.0,0.253137,0.683478,0.78776,0.8330110000000001,0.964858,1.108419,1.141103,-0.017967,-0.036204,-0.092049,-0.059497,-0.06639500000000001,-0.107526 +254,254,20210621,0.0,0.253137,0.258298,-0.019672,-0.273419,-0.560235,0.9763379999999999,0.764935,0.083223,-0.17018599999999998,-0.24000500000000002,6.0541,0.510576,0.269137 +255,255,20210621,0.0,-0.616452,-0.430386,-0.63873,-0.656976,-0.595646,-0.631872,-0.61098,-0.153147,-0.193232,-0.014634999999999999,-0.186461,-0.150895,-0.24489299999999997 +256,256,20210621,0.0,0.253137,-0.319474,-0.290366,-0.254832,-0.20728400000000002,-0.177288,-0.173522,-0.247454,-0.19653099999999998,-0.241141,-0.244613,-0.247112,-0.24354299999999998 +257,257,20210621,0.0,-0.616452,-0.67997,-0.673659,-0.665499,-0.651435,-0.644472,-0.294036,-0.267499,-0.210333,-0.219842,-0.235931,1.084013,-0.217611 +258,258,20210621,0.0,-0.616452,-0.5867939999999999,-0.656518,-0.539151,0.144704,-0.542442,-0.615614,-0.19384,0.171821,2.6891130000000003,-0.209377,-0.169484,-0.29338200000000003 +259,259,20210621,0.0,-1.486041,0.148662,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +260,260,20210621,1.0,0.253137,2.161438,2.3090759999999997,2.232773,1.9562970000000002,2.168848,2.074287,0.261814,0.134495,0.043979000000000004,0.043018,0.078584,0.016004 +261,261,20210621,0.0,0.253137,0.368137,0.7058180000000001,0.874901,0.9406399999999999,0.772312,-0.035813,2.0736830000000004,0.6151270000000001,-0.012818000000000001,0.011165999999999999,1.3460889999999999,3.362993 +262,262,20210621,0.0,0.253137,-0.026445999999999997,-0.19781600000000002,-0.208371,-0.24000500000000002,-0.183916,-0.177367,-0.24522,-0.19622699999999998,-0.126411,-0.10826600000000002,-0.244625,0.062018 +263,263,20210621,0.0,-0.616452,-0.634896,-0.6254529999999999,-0.591856,-0.37806999999999996,-0.390377,-0.440275,-0.06035,0.002076,0.778984,-0.30806300000000003,0.51398,-0.185603 +264,264,20210621,0.0,-1.486041,-0.664637,0.022985,-0.677929,-0.672497,-0.65814,-0.647049,2.7562279999999997,-0.25699,-0.29680100000000004,-0.288977,-0.292013,-0.29338200000000003 +265,265,20210621,0.0,-0.616452,-0.5582739999999999,-0.687485,-0.591611,-0.669575,-0.636017,-0.36941399999999996,-0.326365,0.0032049999999999995,-0.286124,-0.203121,0.790193,-0.068374 +266,266,20210621,0.0,-0.616452,-0.6120399999999999,-0.690983,-0.677929,-0.667585,-0.6578609999999999,-0.647418,-0.341942,-0.25699,-0.278854,-0.287891,-0.293453,-0.275606 +267,267,20210621,0.0,1.992316,-0.600931,-0.580857,-0.5481199999999999,-0.529768,-0.5030319999999999,-0.494697,-0.273476,-0.200654,-0.269652,-0.253996,-0.314136,-0.283538 +268,268,20210621,1.0,0.253137,0.513069,0.592685,0.363151,0.099345,-0.201434,-0.190952,-0.094402,-0.12266099999999999,-0.20422300000000002,-0.272252,-0.274864,-0.29338200000000003 +269,269,20210621,0.0,0.253137,-0.22207399999999997,-0.206963,-0.192927,-0.134878,-0.091279,-0.053713,-0.24534099999999998,-0.187547,-0.211606,-0.212313,-0.21595599999999998,-0.209004 +270,270,20210621,1.0,-0.616452,-0.50967,-0.481914,-0.472559,-0.45537299999999997,-0.427534,-0.608831,-0.23930300000000002,-0.25699,-0.272606,-0.276082,-0.143041,-0.215192 +271,271,20210621,0.0,0.253137,0.25503899999999996,-0.247765,-0.37548400000000004,-0.36607,-0.33659,-0.348357,-0.219077,-0.170012,-0.261815,-0.17995,-0.248094,-0.180034 +272,272,20210621,0.0,0.253137,-0.680948,-0.682104,-0.658462,-0.658507,-0.6556569999999999,-0.652724,-0.341942,-0.198397,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.268069 +273,273,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +274,274,20210621,0.0,0.253137,-0.54282,-0.510408,-0.475703,-0.446917,-0.394538,-0.45281899999999997,-0.221191,-0.19961199999999998,-0.18320799999999998,-0.180397,-0.235592,-0.124626 +275,275,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +276,276,20210621,0.0,0.253137,0.23732899999999998,0.280177,0.308052,-0.203631,-0.42768199999999995,-0.399421,-0.071278,0.28536,-0.11119000000000001,-0.11656400000000001,-0.117776,-0.180878 +277,277,20210621,1.0,-0.616452,-0.6933199999999999,-0.652837,-0.6781159999999999,-0.631444,-0.663223,-0.274323,-0.17723699999999998,-0.25699,-0.146063,-0.30806300000000003,1.16151,-0.29338200000000003 +278,278,20210621,0.0,-0.616452,-0.6799430000000001,-0.6865439999999999,-0.673372,-0.667585,-0.6578609999999999,-0.647418,-0.322863,-0.243275,-0.278854,-0.287891,-0.293453,-0.275606 +279,279,20210621,0.0,0.253137,-0.004947999999999999,0.018026,0.052501,-0.360894,-0.332988,-0.321877,-0.220768,-0.161549,-0.25755500000000003,-0.262933,-0.26812199999999997,-0.25417399999999996 +280,280,20210621,0.0,0.253137,0.704637,0.750499,0.722381,0.866851,0.996109,1.048262,-0.10044,-0.06168099999999999,-0.012818000000000001,-0.05273099999999999,0.013131,-0.045874 +281,281,20210621,0.0,-1.486041,-0.675108,-0.6564479999999999,-0.668354,-0.6443,-0.6630590000000001,-0.652724,-0.281566,-0.228171,-0.211606,-0.30806300000000003,-0.314136,-0.29338200000000003 +282,282,20210621,0.0,-0.616452,1.036464,0.843161,0.657794,0.410467,0.063122,0.076272,0.265617,-0.032949,0.279685,2.519672,2.533675,1.4521709999999999 +283,283,20210621,0.0,0.253137,1.5306879999999998,1.460856,1.4422700000000002,1.226968,1.04251,0.526123,0.124278,0.007370999999999999,-0.094435,-0.077945,-0.117776,-0.112757 +284,284,20210621,0.0,0.253137,0.030837,0.048852,0.080562,0.141035,0.255273,0.292063,-0.089995,-0.12678399999999998,-0.181788,0.011101999999999999,-0.117776,-0.124626 +285,285,20210621,0.0,0.253137,1.95428,0.555887,0.651521,0.801331,0.9518790000000001,1.0005389999999998,-0.040063999999999995,-0.03998,-0.012818000000000001,0.011101999999999999,-0.052323,-0.012121999999999999 +286,286,20210621,0.0,-0.616452,0.8029189999999999,-0.101065,-0.362506,-0.360428,-0.397071,-0.642884,2.1929849999999997,0.692383,0.843449,0.72418,-0.27578,0.819112 +287,287,20210621,0.0,0.253137,0.12600999999999998,0.191435,0.22719899999999998,0.301873,0.38409699999999997,0.128914,-0.144151,-0.16905699999999999,-0.18320799999999998,-0.180397,-0.183229,-0.15264 +288,288,20210621,0.0,0.253137,1.757565,1.8599569999999999,1.484261,1.08612,1.06863,0.986518,0.177892,0.042787,-0.08512,-0.065497,-0.052257000000000005,-0.14144600000000002 +289,289,20210621,1.0,0.253137,0.26716599999999996,0.316118,0.33327199999999996,0.41337299999999993,0.483692,0.209783,-0.13231800000000002,-0.166193,-0.18320799999999998,-0.17229,-0.185848,-0.20568499999999998 +290,290,20210621,0.0,0.253137,-0.5767979999999999,-0.5518850000000001,-0.525005,-0.505162,-0.46954300000000004,-0.580335,-0.263755,-0.213588,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.23713 +291,291,20210621,1.0,-0.616452,-0.683446,-0.678366,-0.673242,-0.658538,-0.657713,-6.355247,-0.287724,-0.24288400000000002,-0.245798,-0.287317,-0.314136,19.130014000000003 +292,292,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +293,293,20210621,0.0,1.992316,-0.672555,-0.654312,-0.650329,-0.638579,-0.630162,-0.609637,-0.275529,-0.25699,-0.279762,-0.30806300000000003,-0.274864,-0.29338200000000003 +294,294,20210621,1.0,0.253137,-0.600374,-0.5472899999999999,-0.5400739999999999,-0.518592,-0.499183,-0.48175100000000004,-0.130205,-0.25699,-0.268403,-0.28444400000000003,-0.28841300000000003,-0.254006 +295,295,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.209004 +296,296,20210621,0.0,0.253137,1.943782,2.08177,2.008398,1.4002729999999999,1.535009,1.5972,0.201438,0.067005,-0.029005,-0.0014089999999999999,0.022359999999999998,0.004753 +297,297,20210621,0.0,-0.616452,-0.6727449999999999,-0.681752,-0.646508,-0.650378,-0.6630590000000001,-0.622163,-0.302275,-0.156341,-0.21598,-0.30806300000000003,-0.195011,-0.152977 +298,298,20210621,0.0,0.253137,1.249435,1.3181610000000001,1.404533,1.63103,1.771191,1.557555,0.049473,-0.036420999999999995,0.043979000000000004,0.068552,-0.016715999999999998,-0.028998000000000003 +299,299,20210621,0.0,0.253137,0.10538099999999999,0.16310999999999998,0.23377399999999998,-0.210813,-0.166777,-0.136026,-0.17560699999999999,-0.106689,-0.222966,-0.237846,-0.242137,-0.180878 +300,300,20210621,1.0,-0.616452,-0.695642,-0.690983,-0.49045500000000003,-0.47662200000000005,-0.340752,-0.649315,-0.341942,0.307278,-0.29680100000000004,0.942743,-0.300849,-0.29338200000000003 +301,301,20210621,0.0,0.253137,0.651673,0.68907,0.290878,0.36782800000000004,0.43563,0.43056099999999997,-0.131231,-0.155776,-0.165374,-0.15709800000000002,-0.150699,-0.163721 +302,302,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,10.289311,-0.29338200000000003 +303,303,20210621,0.0,0.253137,-0.017415,0.028576999999999998,-0.5033890000000001,-0.472005,-0.437929,-0.40994899999999995,-0.19704000000000002,-0.204647,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.23713 +304,304,20210621,1.0,0.253137,-0.5331100000000001,-0.486354,-0.276765,-0.426522,-0.40381500000000004,-0.44266000000000005,-0.17289000000000002,-0.25699,-0.069615,-0.199547,-0.248683,-0.180878 +305,305,20210621,0.0,0.253137,-0.683813,-0.6816399999999999,-0.664085,-0.606558,-0.5958829999999999,-0.52823,-0.301792,-0.215324,-0.07484,-0.24333600000000002,-0.085049,-0.131377 +306,306,20210621,0.0,-1.486041,-0.689775,-0.645741,-0.595677,-0.6529729999999999,-0.632662,-0.646008,-0.147532,-0.000745,-0.29680100000000004,-0.11656400000000001,-0.314136,-0.29338200000000003 +307,307,20210621,0.0,-0.616452,-0.553277,-0.35439299999999996,-0.677929,-0.54037,-0.5875600000000001,-0.652724,1.1047770000000001,-0.25699,0.18597,-0.015068999999999999,-0.314136,-0.29338200000000003 +308,308,20210621,0.0,-1.486041,-0.695642,-0.617711,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.027083,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +309,309,20210621,1.0,3.731494,-0.563639,-0.541867,-0.514421,-0.472891,-0.435478,-0.409009,-0.269491,-0.204907,-0.18320799999999998,-0.212313,-0.21595599999999998,-0.209004 +310,310,20210621,0.0,-0.616452,-0.41252799999999995,-0.49707399999999996,-0.470771,-0.5965010000000001,-0.658568,-0.45565600000000006,0.491784,0.37594,-0.019122,-0.290636,0.5732149999999999,-0.29338200000000003 +311,311,20210621,0.0,-0.616452,-0.6454340000000001,-0.640402,-0.658404,-0.58977,-0.579122,-0.617848,-0.281566,-0.198223,0.005471,-0.30768,-0.15796400000000002,0.217667 +312,312,20210621,0.0,0.253137,1.250467,1.365047,1.4424139999999999,1.3142969999999998,1.480679,1.577974,0.080687,-0.03998,-0.012818000000000001,0.004719,0.013131,-0.006497 +313,313,20210621,0.0,0.253137,-0.5471520000000001,-0.49796,-0.439033,-0.510664,-0.448292,-0.41193100000000005,-0.160815,-0.12244400000000001,-0.29680100000000004,-0.11656400000000001,-0.21595599999999998,-0.29338200000000003 +314,314,20210621,1.0,0.253137,0.016509,0.026147000000000004,0.132546,0.17814000000000002,0.30175599999999997,0.35449400000000003,-0.341942,0.0034219999999999997,-0.29680100000000004,0.011101999999999999,-0.16451,-0.124626 +315,315,20210621,0.0,0.253137,0.061257000000000006,0.047461,-0.19608499999999998,-0.22519099999999997,-0.373895,-0.544569,-0.24346900000000002,-0.201175,-0.28544200000000003,-0.26689,-0.254639,-0.282132 +316,316,20210621,1.0,0.253137,-0.023309,-0.22336,-0.18315,-0.403936,-0.370145,-0.327871,-0.223002,-0.17018599999999998,-0.261701,-0.256422,-0.183229,-0.258731 +317,317,20210621,0.0,0.253137,-0.046232999999999996,-0.003261,0.047829,0.11862,0.19513699999999998,0.24818600000000002,-0.209115,-0.14848499999999998,-0.18320799999999998,-0.174013,-0.150503,-0.169628 +318,318,20210621,0.0,-0.616452,-0.695642,-0.688665,-0.6703439999999999,-0.665471,-0.656529,-0.64458,-0.33198,-0.23415999999999998,-0.271129,-0.282721,-0.282391,-0.26756199999999997 +319,319,20210621,0.0,0.253137,-0.036686,0.024952000000000002,-0.252309,-0.210175,-0.171284,-0.234896,-0.115292,-0.256946,-0.236029,-0.242315,-0.25765,-0.25659299999999996 +320,320,20210621,0.0,-1.486041,-0.695669,-0.691012,-0.677958,-0.672528,-0.663091,-0.652758,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +321,321,20210621,1.0,0.253137,0.096947,0.10423900000000001,0.07058400000000001,0.083692,0.124195,0.152758,-0.191003,-0.25699,-0.18320799999999998,-0.180397,-0.19278599999999999,-0.180878 +322,322,20210621,0.0,0.253137,1.6426599999999998,1.8400470000000002,1.71984,1.7466490000000001,1.7325700000000002,1.08124,0.932284,-0.019972,-0.012818000000000001,0.065296,-0.13531700000000002,2.519214 +323,323,20210621,0.0,0.253137,-0.676643,-0.656687,-0.6221949999999999,-0.556287,-0.525155,-0.5169630000000001,-0.27734000000000003,-0.191887,-0.088585,-0.149948,-0.228654,-0.23713 +324,324,20210621,1.0,-0.616452,-0.337645,-0.426471,-0.662067,-0.639854,-0.650443,-0.5490689999999999,-0.23869899999999997,-0.209247,-0.24000500000000002,-0.259103,0.089908,-0.23713 +325,325,20210621,0.0,0.253137,0.5677449999999999,0.630509,0.646316,0.8140310000000001,0.983806,1.038841,0.261814,0.046824,0.271165,0.33026700000000003,0.340398,0.269137 +326,326,20210621,0.0,0.253137,-0.695642,-0.690983,-0.12978199999999998,-0.042093,0.078354,-0.030489999999999996,-0.341942,1.392845,-0.126411,0.011101999999999999,-0.117776,-0.124626 +327,327,20210621,1.0,-0.616452,-0.686814,-0.681851,-0.673242,-0.65773,-0.655246,-0.647267,-0.32232,-0.25699,-0.242844,-0.30806300000000003,-0.292864,-0.2751 +328,328,20210621,1.0,0.253137,-0.357513,-0.29791100000000004,-0.285229,-0.20330499999999999,-0.176745,-0.14519400000000002,-0.112515,-0.25699,-0.085518,-0.30806300000000003,-0.22904699999999997,-0.220761 +329,329,20210621,0.0,-1.486041,-0.011236,-0.063424,-0.558243,-0.638455,-0.258444,-0.528197,2.354731,0.104157,-0.17241700000000001,1.262163,0.171266,4.048985 +330,330,20210621,0.0,1.992316,0.660446,0.750386,0.764992,0.9592780000000001,1.0993389999999998,1.184762,-0.027989,-0.25699,0.163252,-0.05273099999999999,-0.039231999999999996,-0.057124 +331,331,20210621,1.0,-0.616452,-0.6980729999999999,-0.683888,-0.675203,-0.5672149999999999,-0.28130700000000003,-0.36906100000000003,-0.281566,-0.25699,0.095096,1.223927,0.798571,-0.152752 +332,332,20210621,1.0,0.253137,-0.565825,-0.516843,-0.506576,-0.5197579999999999,-0.495828,-0.43972100000000003,-0.160815,-0.25699,-0.268403,-0.276146,-0.13741199999999998,-0.265256 +333,333,20210621,0.0,0.253137,-0.552503,-0.5472199999999999,-0.515891,-0.494871,-0.31808600000000004,-0.11779,-0.341942,-0.192625,-0.258577,0.33026700000000003,0.441196,0.100381 +334,334,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.677929,-0.672497,-0.636741,0.663546,-0.341942,-0.25699,-0.29680100000000004,-0.20593000000000003,4.816623,-0.29338200000000003 +335,335,20210621,0.0,0.253137,-0.41627600000000003,-0.42277600000000004,-0.394461,-0.370112,-0.348762,-0.335898,-0.262065,-0.187547,-0.24966,-0.26338,-0.270021,-0.272231 +336,336,20210621,0.0,0.253137,1.25268,1.373618,1.512538,1.714161,1.913815,2.0400150000000004,0.007935,0.06453099999999999,0.023816,0.059168,0.102802,0.036535000000000005 +337,337,20210621,0.0,0.253137,1.4349049999999999,1.56053,1.6290950000000002,1.7852919999999999,1.9483240000000002,2.018975,0.261814,0.090225,0.043979000000000004,0.138768,0.144038,0.044129 +338,338,20210621,0.0,-1.486041,-0.690345,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +339,339,20210621,1.0,0.253137,-0.063983,-0.020557,0.038383999999999995,-0.191724,-0.168323,-0.162909,-0.22275999999999999,-0.065761,-0.23654,-0.23956999999999998,-0.24567199999999997,-0.234486 +340,340,20210621,0.0,-0.616452,-0.683664,-0.599221,-0.586895,-0.6553979999999999,-0.6411819999999999,-0.638787,0.07464900000000001,-0.038374,-0.234325,-0.223165,-0.065413,-0.178797 +341,341,20210621,0.0,-1.486041,-0.694392,-0.6896909999999999,-0.676602,-0.672497,-0.6615449999999999,-0.652724,-0.336387,-0.25299699999999997,-0.29680100000000004,-0.30219,-0.314136,-0.18746 +342,342,20210621,0.0,0.253137,-0.6152989999999999,-0.6042649999999999,-0.618475,-0.661927,-0.646972,-0.636302,-0.268766,-0.204907,-0.29680100000000004,-0.24563400000000002,-0.314136,-0.29338200000000003 +343,343,20210621,0.0,1.992316,-0.663144,-0.688412,-0.608035,-0.35876399999999997,-0.254891,-0.245558,-0.341942,-0.045536,0.849526,0.011101999999999999,-0.314136,-0.23713 +344,344,20210621,0.0,-0.616452,3.035361,3.267184,2.812615,1.228507,-0.679589,-0.635849,0.322189,6.0362800000000005,1.179912,-0.30806300000000003,6.296982,-0.186616 +345,345,20210621,0.0,0.253137,1.279013,1.251225,1.2046430000000001,0.973563,1.117449,1.135881,-0.013499,-0.037767,-0.078986,-0.045965,-0.035959,-0.066799 +346,346,20210621,0.0,0.253137,-0.653583,-0.700917,-0.716819,-0.636698,-0.5613739999999999,-0.624951,-0.341942,-0.25699,-0.012818000000000001,0.011101999999999999,-0.21595599999999998,0.43789300000000003 +347,347,20210621,0.0,0.253137,-0.677036,-0.632084,-0.6179560000000001,-0.6174390000000001,-0.630491,-0.585893,-0.087761,-0.076481,-0.24000500000000002,-0.239123,-0.183229,-0.207598 +348,348,20210621,1.0,0.253137,-0.05625499999999999,0.001924,0.048968,0.035473000000000005,-0.005731,0.038172000000000005,-0.160815,-0.17018599999999998,-0.18320799999999998,-0.180397,-0.183229,-0.180878 +349,349,20210621,0.0,0.253137,1.180092,1.247263,1.344531,1.498731,1.6684709999999998,1.7346240000000002,0.056537000000000004,0.025123,-0.007137999999999999,0.030251999999999998,0.078584,-0.012121999999999999 +350,350,20210621,1.0,0.253137,-0.45264499999999996,-0.423858,-0.387755,-0.358158,-0.320997,-0.319509,-0.256752,-0.190932,-0.261531,-0.257315,-0.267337,-0.23713 +351,351,20210621,0.0,-0.616452,-0.164261,-0.403331,-0.649954,-0.6423409999999999,-0.6630590000000001,-0.264818,-0.248903,-0.074702,-0.29680100000000004,-0.30806300000000003,1.197902,-0.124626 +352,352,20210621,0.0,-0.616452,-0.891012,-0.881267,-0.6284390000000001,-0.729763,-0.6630590000000001,-0.629451,0.268938,1.783549,-0.29680100000000004,-0.05273099999999999,6.231201,0.269137 +353,353,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +354,354,20210621,0.0,0.253137,0.35083600000000004,0.406377,0.165654,0.120921,-0.34994699999999995,-0.32673,-0.15012899999999998,-0.144145,-0.126411,-0.200121,-0.268646,-0.24376799999999998 +355,355,20210621,0.0,1.992316,-0.479724,-0.427961,-0.41661000000000004,-0.384459,-0.349075,-0.336099,-0.136665,-0.25699,-0.24000500000000002,-0.244166,-0.27263899999999996,-0.25749299999999997 +356,356,20210621,1.0,0.253137,-0.319745,-0.291644,-0.25037600000000004,-0.20646,-0.162714,-0.130048,-0.252525,-0.17018599999999998,-0.234325,-0.231463,-0.21595599999999998,-0.209004 +357,357,20210621,0.0,0.253137,1.223496,1.1206690000000001,1.113408,1.0860889999999999,1.211501,1.082869,0.041382999999999996,-0.003783,-0.076998,-0.05273099999999999,-0.063777,-0.095375 +358,358,20210621,0.0,0.253137,1.943252,1.8269240000000002,2.1194319999999998,2.042724,2.153781,2.1871099999999997,0.202042,1.262076,-0.012818000000000001,0.074935,0.013131,-0.045874 +359,359,20210621,0.0,0.253137,0.44179799999999997,0.39695,0.461884,0.580865,0.691189,0.7655390000000001,-0.160815,-0.131124,-0.13209100000000001,-0.11656400000000001,-0.085049,-0.068374 +360,360,20210621,0.0,-0.616452,-0.021272,-0.686895,0.058327,-0.6359520000000001,-0.103171,-0.647838,-0.324372,1.959023,1.7306119999999998,1.864746,-0.295089,-0.277013 +361,361,20210621,1.0,0.253137,6.199565,6.463864,6.531137999999999,7.185314,7.308039,6.393809,0.261814,-0.25699,0.498352,0.7451810000000001,0.733118,0.775405 +362,362,20210621,0.0,0.253137,0.27271999999999996,0.308713,0.360728,0.459898,0.560276,0.600107,-0.185629,-0.145534,-0.150834,-0.138203,-0.13210999999999998,-0.152752 +363,363,20210621,0.0,0.253137,-0.074548,-0.062357,-0.049766000000000005,0.012062999999999999,0.077252,-0.219917,-0.341942,-0.25699,-0.225124,-0.221377,-0.230683,-0.203941 +364,364,20210621,1.0,-0.616452,-0.695642,-0.690983,-0.648137,-0.641408,-0.659506,-0.649097,-0.341942,-0.167321,-0.29680100000000004,-0.294275,-0.299998,-0.289669 +365,365,20210621,0.0,-1.486041,-0.685307,-0.686768,-0.672175,-0.6621600000000001,-0.653584,-0.6424310000000001,-0.323829,-0.23967199999999997,-0.259031,-0.271295,-0.274013,-0.264131 +366,366,20210621,0.0,-0.616452,-0.695764,-0.6696270000000001,-0.656472,-0.672497,-0.597841,-0.507039,-0.249627,-0.191583,-0.29680100000000004,-0.054965,0.253737,-0.271781 +367,367,20210621,0.0,0.253137,-0.055101,0.003048,0.049934,-0.310017,-0.281932,-0.23672600000000002,-0.160815,-0.1599,-0.241425,-0.24423000000000003,-0.183229,-0.234936 +368,368,20210621,0.0,0.253137,-0.656435,-0.6639649999999999,-0.634827,-0.628771,-0.63003,-0.616924,-0.341942,-0.191887,-0.29680100000000004,-0.30806300000000003,-0.304318,-0.29338200000000003 +369,369,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +370,370,20210621,1.0,0.253137,-0.41546099999999997,-0.409836,-0.393812,-0.500203,-0.483475,-0.468267,-0.341942,-0.206296,-0.274991,-0.283168,-0.27276999999999996,-0.258731 +371,371,20210621,1.0,-1.486041,0.43885100000000005,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +372,372,20210621,0.0,-0.616452,-0.694297,-0.6491560000000001,-0.46038900000000005,-0.539157,-0.448769,-0.288142,-0.162204,0.397771,0.22135500000000002,0.5235529999999999,1.630615,2.519214 +373,373,20210621,0.0,1.992316,-0.22980100000000003,-0.197971,-0.051395,-0.012620999999999999,0.154724,0.166158,-0.24292600000000003,0.133627,-0.29680100000000004,0.202601,-0.314136,-0.180878 +374,374,20210621,0.0,0.253137,-0.383465,-0.377689,-0.355613,-0.31154,-0.262721,-0.217096,-0.191003,-0.17018599999999998,-0.211606,-0.05273099999999999,-0.183229,-0.29338200000000003 +375,375,20210621,0.0,0.253137,1.6574220000000002,1.762068,1.848927,0.9796879999999999,-0.20103900000000002,2.348277,0.1471,-0.027002999999999996,-0.109088,0.013655,10.205465,0.100381 +376,376,20210621,0.0,0.253137,-0.435669,-0.407616,-0.371807,-0.33837,-0.304483,-0.275968,-0.24292600000000003,-0.183206,-0.24483200000000002,-0.256996,-0.248683,-0.183072 +377,377,20210621,0.0,1.992316,-0.416996,-0.411367,-0.376479,-0.338152,-0.248838,-0.24565900000000002,-0.341942,-0.198744,-0.24307199999999998,-0.039964,-0.314136,-0.23713 +378,378,20210621,0.0,-0.616452,-0.548524,-0.488012,-0.568207,-0.594915,-0.6071340000000001,-0.589839,0.503316,-0.089675,-0.013328999999999999,-0.078264,0.045857,-0.068374 +379,379,20210621,0.0,0.253137,0.25414200000000003,0.319321,-0.053427999999999996,0.020534999999999998,0.123866,0.18498199999999998,-0.130627,-0.12678399999999998,-0.18320799999999998,-0.05273099999999999,-0.117776,0.269137 +380,380,20210621,1.0,0.253137,-0.416887,-0.478416,-0.46028800000000003,-0.523628,-0.47984,-0.443046,-0.221191,-0.12678399999999998,-0.278229,-0.11656400000000001,-0.117776,-0.012121999999999999 +381,381,20210621,0.0,0.253137,0.513775,0.584508,0.34512600000000004,0.452405,0.552068,0.612617,-0.088364,-0.14523,-0.14912999999999998,-0.137373,-0.137347,0.030067 +382,382,20210621,1.0,0.253137,-0.66992,-0.646022,-0.629175,-0.617175,-0.631017,-0.612172,-0.25137800000000005,-0.239629,-0.28544200000000003,-0.276146,-0.281409,-0.270881 +383,383,20210621,0.0,0.253137,0.670482,0.410171,0.641528,0.739853,0.794534,0.8325049999999999,-0.160815,1.045066,-0.069615,-0.05273099999999999,-0.09159500000000001,-0.107751 +384,384,20210621,1.0,0.253137,-0.655606,-0.636918,-0.596513,-0.5875630000000001,-0.571326,-0.553838,-0.275227,-0.174396,-0.29680100000000004,-0.289168,-0.281409,-0.288038 +385,385,20210621,0.0,-1.486041,-0.388463,-0.24939499999999998,-0.27528,-0.279534,-0.6630590000000001,-0.652724,0.262417,-0.204517,-0.263916,-0.30806300000000003,-0.314136,0.061286 +386,386,20210621,0.0,0.253137,3.896029,4.126939,4.289235,3.0716080000000003,3.201315,3.3802470000000002,0.5636909999999999,0.350637,0.214369,0.234517,0.274944,0.173509 +387,387,20210621,0.0,-1.486041,-0.695642,0.43304499999999996,-0.677929,-0.672497,-0.6630590000000001,-0.652724,4.4881,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +388,388,20210621,1.0,1.992316,0.161889,0.23115500000000003,0.315247,0.425654,0.535537,0.606958,-0.130627,-0.06905900000000001,-0.098013,-0.084647,-0.085049,-0.006497 +389,389,20210621,0.0,0.253137,1.385566,1.47346,1.57913,1.8092150000000002,2.015829,1.9963229999999998,0.135025,0.025123,0.02694,0.055785,0.058948,0.006666 +390,390,20210621,1.0,-0.616452,-0.6802819999999999,-0.686895,-0.669536,-0.667974,-0.6630590000000001,-0.647838,-0.324372,-0.23173000000000002,-0.29680100000000004,-0.30806300000000003,8.21385,-0.256762 +391,391,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +392,392,20210621,1.0,0.253137,-0.71346,-0.186323,-0.14010699999999998,-0.09496,-0.127153,-0.093291,1.9898209999999998,-0.17018599999999998,-0.232621,-0.249209,-0.24796300000000002,-0.012121999999999999 +393,393,20210621,0.0,0.253137,0.7139800000000001,0.601495,0.586992,0.512267,0.5227069999999999,0.5499,-0.076289,-0.08281799999999999,-0.12578699999999998,-0.11656400000000001,-0.117711,-0.144146 +394,394,20210621,0.0,0.253137,-0.422537,-0.450694,-0.405939,-0.361671,-0.31412199999999996,-0.298671,-0.160815,-0.12678399999999998,-0.126411,-0.084647,-0.183229,-0.180878 +395,395,20210621,0.0,-1.486041,-0.17958,-0.339725,-0.677929,-0.672497,-0.6630590000000001,-0.652724,1.167446,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +396,396,20210621,0.0,0.253137,1.2386110000000001,1.3337430000000001,1.397856,1.543981,1.6833069999999999,1.742113,0.261814,0.177029,0.043979000000000004,0.074935,0.078584,0.021629 +397,397,20210621,0.0,0.253137,-0.14141900000000002,-0.09169400000000001,-0.067228,-0.003915999999999999,0.044404,-0.166654,-0.190882,-0.204907,-0.24795599999999998,-0.30806300000000003,-0.276239,-0.29338200000000003 +398,398,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.659316,-0.6630590000000001,-0.642112,-0.341942,-0.25699,-0.248638,-0.30806300000000003,-0.27276999999999996,-0.29338200000000003 +399,399,20210621,0.0,0.253137,0.7262569999999999,0.800237,0.8855290000000001,0.744267,0.697768,0.591963,-0.100319,-0.03998,-0.098013,-0.11656400000000001,-0.13741199999999998,-0.012121999999999999 +400,400,20210621,0.0,1.992316,0.9380729999999999,1.006608,0.906639,1.13552,1.299418,1.314713,-0.100017,-0.25699,0.173021,0.011101999999999999,-0.314136,-0.045874 +401,401,20210621,0.0,-0.616452,1.427843,1.167597,0.752158,0.343672,-0.189394,2.4524369999999998,-0.025997000000000003,-0.11424100000000001,-0.179119,-0.115415,11.789633,0.049755 +402,402,20210621,0.0,0.253137,-0.134466,-0.28224499999999997,-0.272771,-0.226917,-0.189871,-0.164689,-0.252103,-0.196487,-0.24216300000000002,-0.212313,-0.147819,-0.180878 +403,403,20210621,1.0,1.992316,-0.67576,-0.661702,-0.672391,-0.672497,-0.6245029999999999,-0.638921,-0.215696,-0.240323,-0.29680100000000004,-0.15843800000000002,-0.314136,-0.266831 +404,404,20210621,0.0,0.253137,-0.317029,-0.28535,-0.276967,-0.28168000000000004,-0.240877,-0.213133,-0.234835,-0.182772,-0.23739200000000002,-0.23918699999999998,-0.24285700000000002,-0.167153 +405,405,20210621,1.0,1.992316,1.4831159999999999,1.6120940000000001,1.624596,1.921757,2.134783,1.929844,0.110875,-0.25699,0.359655,0.062167999999999994,-0.314136,0.024666 +406,406,20210621,0.0,-1.486041,-0.6432479999999999,-0.653188,-0.628757,-0.672497,-0.6630590000000001,0.7267170000000001,-0.179531,-0.105647,-0.29680100000000004,-0.30806300000000003,5.3083089999999995,-0.271106 +407,407,20210621,0.0,-1.486041,-0.33608299999999997,-0.390404,-0.677929,-0.672497,-0.6630590000000001,-0.652724,0.020312,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +408,408,20210621,0.0,0.253137,6.1905470000000005,6.221173,5.531848,5.182416,5.203037,4.443735,-0.32232,0.406885,0.39254,0.47784799999999994,0.609607,0.29872600000000005 +409,409,20210621,0.0,0.253137,0.059533,0.192686,0.17286400000000002,0.284495,0.315754,0.464614,0.346581,0.10029500000000001,0.296724,0.310925,0.764339,0.344571 +410,410,20210621,0.0,0.253137,1.591081,1.776905,1.92704,2.167032,2.106838,2.168001,0.261814,0.090225,0.06505,0.088787,0.075115,0.060329999999999995 +411,411,20210621,1.0,1.992316,-0.297297,-0.289466,-0.233721,-0.181278,-0.130969,-0.099185,-0.341942,-0.139414,-0.205927,-0.218696,-0.22904699999999997,-0.22588000000000003 +412,412,20210621,0.0,-1.486041,-0.693062,-0.690983,-0.677929,-0.666792,-0.6655260000000001,-0.655243,-0.341942,-0.25699,-0.275957,-0.29848800000000003,-0.314136,-0.29338200000000003 +413,413,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.637423,-0.601071,-0.650031,-0.595565,-0.341942,-0.135074,-0.035196,-0.25750700000000004,-0.091333,-0.29338200000000003 +414,414,20210621,1.0,0.253137,-0.510023,-0.513289,-0.488522,-0.507789,-0.511437,-0.567624,-0.341942,-0.21081,-0.272776,-0.288083,-0.248683,-0.032317 +415,415,20210621,0.0,-1.486041,-0.49373999999999996,-0.316331,2.20549,-0.532085,-0.344436,-0.27334899999999995,1.272138,8.422602000000001,0.216243,0.9284450000000001,1.164652,-0.180878 +416,416,20210621,0.0,-1.486041,-0.390079,-0.620732,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.040063999999999995,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.25738099999999997 +417,417,20210621,0.0,-1.486041,-0.598079,-0.48240600000000006,-0.6621100000000001,-0.672497,-0.6630590000000001,-0.650038,0.7150529999999999,-0.209161,-0.29680100000000004,-0.30806300000000003,-0.303664,-0.231336 +418,418,20210621,0.0,1.992316,-0.4945,-0.46249700000000005,-0.42866499999999996,-0.39433,-0.34313699999999997,-0.33384899999999995,-0.221191,-0.187547,-0.228645,-0.180397,-0.314136,-0.23713 +419,419,20210621,0.0,0.253137,-0.093507,-0.08614400000000001,-0.16401500000000002,-0.38099299999999997,-0.349042,-0.324479,-0.122839,-0.112375,-0.18320799999999998,-0.180397,-0.183229,-0.152752 +420,420,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +421,421,20210621,0.0,1.992316,-0.352529,-0.3207,-0.278351,-0.237891,-0.169573,-0.15953399999999998,-0.25137800000000005,-0.178866,-0.23960700000000001,-0.14848,-0.314136,-0.192129 +422,422,20210621,0.0,0.253137,1.608451,1.658222,1.607926,1.7676180000000001,1.935182,1.8985450000000001,0.145349,0.13453900000000002,0.101514,0.075765,0.080417,0.044692 +423,423,20210621,0.0,-0.616452,-0.5566180000000001,-0.651713,-0.658462,-0.66673,-0.614042,-0.652724,-0.173192,-0.198397,-0.27573000000000003,-0.11784000000000001,-0.314136,-0.168897 +424,424,20210621,1.0,0.253137,0.730019,0.7972859999999999,0.80247,0.8367100000000001,0.949626,1.1146559999999999,-0.070252,-0.25699,-0.098013,-0.084647,0.274944,-0.29338200000000003 +425,425,20210621,0.0,0.253137,1.9197849999999999,2.090523,2.230091,2.526512,2.572311,2.542843,0.261814,0.053029999999999994,0.118155,0.094276,0.10666400000000001,0.044129 +426,426,20210621,0.0,-1.486041,-0.542697,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +427,427,20210621,1.0,0.253137,-0.565934,-0.521241,-0.48921400000000004,-0.47690200000000005,-0.410954,-0.377105,-0.160815,-0.191887,-0.29680100000000004,-0.10871199999999999,-0.21595599999999998,-0.23713 +428,428,20210621,1.0,-0.616452,-0.6929390000000001,-0.688187,-0.675059,-0.666311,-0.6597850000000001,-0.649383,-0.329927,-0.24835300000000002,-0.274196,-0.30806300000000003,-0.301111,-0.270994 +429,429,20210621,0.0,0.253137,0.256614,0.271972,0.282456,-0.21547600000000003,-0.186893,-0.15241500000000002,-0.12459,-0.18555,-0.262723,1.509133,-0.227279,-0.23713 +430,430,20210621,0.0,0.253137,2.1916,1.809221,1.043269,1.1581059999999999,0.46844399999999997,0.458334,0.020312,-0.06168099999999999,-0.012818000000000001,-0.11656400000000001,-0.117776,-0.124626 +431,431,20210621,0.0,0.253137,0.552331,0.316877,0.378205,0.48438000000000003,0.588172,0.65112,-0.14874,-0.11376300000000002,-0.126411,-0.1165,-0.117776,-0.119001 +432,432,20210621,1.0,0.253137,3.444625,3.5240949999999995,3.654208,3.87998,4.154434999999999,4.079623000000001,0.443363,0.20359100000000002,0.273494,0.3941,0.37390999999999996,0.100381 +433,433,20210621,0.0,0.253137,-0.042104,0.005029,0.049155000000000004,0.12011199999999998,0.19248900000000002,0.24069699999999997,-0.191003,-0.14848499999999998,-0.18320799999999998,-0.180397,-0.179499,-0.152752 +434,434,20210621,0.0,0.253137,1.473989,1.5878290000000002,1.7176189999999998,1.9601830000000002,2.112693,2.167682,0.04579,0.027944,0.041195999999999997,0.075318,0.071646,0.041092000000000004 +435,435,20210621,0.0,-1.486041,-0.570565,-0.571766,-0.429458,-0.644984,-0.6630590000000001,-0.652724,0.021217,0.5005470000000001,-0.195987,-0.30806300000000003,-0.314136,-0.29338200000000003 +436,436,20210621,1.0,1.992316,2.492423,2.583255,2.62837,2.710652,3.0162869999999997,3.065184,0.261814,0.090225,-0.29680100000000004,0.713264,0.20949099999999998,-0.29338200000000003 +437,437,20210621,0.0,-0.616452,-0.504536,-0.690983,-0.677929,-0.667834,-0.660591,-0.650205,-0.341942,-0.25699,-0.279762,-0.30806300000000003,-0.304318,-0.282132 +438,438,20210621,0.0,0.253137,0.143732,0.18715,0.218446,0.269572,0.32832,0.357215,-0.203078,-0.16150499999999998,-0.166169,-0.16763,-0.16359300000000002,-0.164003 +439,439,20210621,0.0,0.253137,-0.002435,0.014780000000000001,-0.004847,0.026722000000000003,-0.311079,-0.302465,-0.191003,-0.126437,-0.24000500000000002,-0.259486,-0.261773,-0.253781 +440,440,20210621,1.0,0.253137,0.35038800000000003,0.33864099999999997,0.155633,-0.08737400000000001,0.097434,0.13833399999999998,-0.148015,-0.187547,-0.242504,2.245254,-0.19632,-0.19775399999999999 +441,441,20210621,0.0,0.253137,-0.6908890000000001,-0.686066,-0.672161,-0.646149,-0.45506800000000003,-0.441417,-0.32081,-0.239629,-0.200531,0.413249,-0.282391,-0.158377 +442,442,20210621,0.0,1.992316,0.44283100000000003,0.51153,0.5807770000000001,0.749055,0.8729110000000001,0.850505,-0.10044,-0.081776,0.072377,-0.084647,-0.314136,-0.113376 +443,443,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.6643020000000001,-0.672497,-0.659818,-0.602433,-0.341942,-0.215975,-0.29680100000000004,-0.295487,-0.118103,-0.29338200000000003 +444,444,20210621,0.0,0.253137,0.973722,1.060435,1.144108,1.113261,1.264909,1.442767,0.00244,0.000384,-0.069615,-0.052538999999999995,0.342558,-0.045874 +445,445,20210621,1.0,0.253137,2.647011,2.560873,2.7043779999999997,2.446381,2.534677,2.686429,0.38413400000000003,0.13406099999999999,0.123494,0.202601,0.20949099999999998,0.100381 +446,446,20210621,0.0,0.253137,-0.189032,-0.22305,-0.256087,-0.28583000000000003,-0.328679,-0.39074000000000003,-0.24534099999999998,-0.191887,-0.234325,-0.24423000000000003,-0.274864,-0.265256 +447,447,20210621,0.0,0.253137,1.293001,0.820891,0.618456,0.74178,0.689906,0.75758,-0.070252,-0.06602100000000001,-0.126411,-0.154864,-0.150503,-0.152752 +448,448,20210621,0.0,-0.616452,-0.069279,-0.67328,-0.254472,-0.588557,-0.6630590000000001,-0.6258739999999999,-0.265868,1.01755,-0.293734,-0.30806300000000003,-0.20947600000000002,-0.29338200000000003 +449,449,20210621,0.0,0.253137,-0.171921,-0.153614,-0.21284099999999997,-0.200196,-0.154803,-0.652724,-0.040063999999999995,-0.19253800000000001,-0.18570699999999998,-0.212313,-0.314136,-0.17514100000000002 +450,450,20210621,0.0,0.253137,0.612221,0.68605,0.507783,0.33789,0.337794,0.335973,-0.06995,0.303155,-0.29680100000000004,-0.166992,-0.16359300000000002,-0.000872 +451,451,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +452,452,20210621,1.0,0.253137,5.6485199999999995,5.75619,6.095178,6.277876999999999,6.590395,6.6468940000000005,-0.341942,0.5242439999999999,0.611945,0.713264,1.0603850000000001,0.831656 +453,453,20210621,0.0,0.253137,2.776787,3.00055,-0.14961,1.229953,1.432502,1.548235,0.503316,-0.039025,7.086765,0.138768,0.078584,0.044129 +454,454,20210621,0.0,-1.486041,1.4336010000000001,-0.6884680000000001,-0.657121,-0.6500670000000001,-0.639323,-0.638099,-0.33113400000000004,-0.19436099999999998,-0.214844,-0.215952,-0.257126,-0.180034 +455,455,20210621,0.0,0.253137,0.365394,-0.29473499999999997,0.454804,0.09446399999999999,0.14158099999999998,0.160718,-0.191003,1.975255,-0.19456700000000002,-0.193163,-0.19632,-0.19775399999999999 +456,456,20210621,0.0,-0.616452,-0.15195699999999998,-0.177457,-0.42657399999999995,-0.438849,-0.488705,-0.563476,-0.21955999999999998,-0.204603,-0.27970500000000004,-0.29453,0.033749,-0.012853999999999999 +457,457,20210621,0.0,1.992316,0.26904,0.283114,0.391673,0.452654,0.607038,0.620425,-0.341942,0.0034219999999999997,-0.29680100000000004,0.074935,-0.314136,0.044129 +458,458,20210621,0.0,-1.486041,-0.37006100000000003,-0.351934,-0.312728,-0.27184,-0.6630590000000001,-0.652724,-0.23326599999999997,-0.174526,-0.222966,-0.30806300000000003,-0.314136,-0.29338200000000003 +459,459,20210621,0.0,-0.616452,-0.684519,-0.435787,-0.599008,-0.545624,-0.5481659999999999,-0.49941599999999997,0.754659,-0.011595000000000001,0.435137,0.13781,0.283453,0.075293 +460,460,20210621,1.0,-0.616452,-0.004024,-0.130613,-0.216244,-0.398449,-0.503015,-0.545257,-0.215153,-0.20416900000000002,-0.268403,-0.30806300000000003,0.10476500000000001,-0.035186 +461,461,20210621,0.0,0.253137,1.37553,1.439767,1.615122,1.239808,1.410675,1.466712,-0.000397,0.193175,-0.012818000000000001,0.011101999999999999,0.013131,-0.012121999999999999 +462,462,20210621,0.0,-0.616452,-0.672704,-0.569616,-0.5957060000000001,-0.626175,-0.642334,-0.5206069999999999,0.179582,-0.008601000000000001,-0.127547,-0.227633,0.200851,-0.16974 +463,463,20210621,0.0,0.253137,-0.413071,0.7120850000000001,0.764069,-0.625631,-0.276965,-0.62841,4.4881,-0.12678399999999998,-0.125559,1.190287,-0.23899600000000001,-0.017748 +464,464,20210621,0.0,0.253137,-0.28631,1.1531959999999999,0.915522,0.870799,0.94229,0.9612299999999999,6.908736,0.091701,-0.125673,-0.052092999999999993,0.07086100000000001,-0.124626 +465,465,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.6492180000000001,-0.672497,-0.6630590000000001,-0.650205,-0.341942,-0.170576,-0.29680100000000004,-0.30806300000000003,-0.304318,-0.258843 +466,466,20210621,1.0,0.253137,2.135349,2.20804,2.26105,2.457076,2.610159,2.565764,0.113048,0.058846,0.106455,0.146428,0.133827,0.097288 +467,467,20210621,1.0,0.253137,2.194235,2.274245,2.390052,2.724595,2.096047,2.122949,0.195944,0.068524,0.214369,0.12146900000000001,0.078584,0.100888 +468,468,20210621,0.0,0.253137,-0.313838,-0.297489,-0.317429,-0.329805,-0.336393,-0.319727,-0.24473699999999998,-0.20386600000000002,-0.25959899999999997,-0.26803899999999997,-0.273555,-0.265256 +469,469,20210621,0.0,0.253137,0.11066400000000001,0.006996,0.036077,-0.010803,0.130873,0.211731,0.263383,0.05728300000000001,2.5482,1.28776,0.018236000000000002,-0.173453 +470,470,20210621,0.0,-0.616452,-0.6119859999999999,-0.644983,-0.588669,-0.667725,-0.6158520000000001,-0.641474,-0.144151,0.014099,-0.27936500000000003,-0.12486199999999999,-0.270282,-0.21676700000000002 +471,471,20210621,1.0,0.253137,4.128379,4.413862,4.703333,3.2477270000000003,3.572342,3.763804,0.491361,0.460226,0.20829099999999998,0.281051,0.340398,0.237355 +472,472,20210621,0.0,0.253137,4.277466,4.545584,4.743233,2.374068,1.839189,1.95305,0.5045229999999999,0.333059,0.05778,0.075382,0.082577,0.044805000000000005 +473,473,20210621,0.0,-0.616452,-0.655892,-0.651783,-0.6614899999999999,-0.63917,-0.643649,-0.629518,-0.173494,-0.207511,-0.175029,-0.23274,-0.22368000000000002,-0.156127 +474,474,20210621,0.0,1.992316,-0.297799,-0.264963,-0.23065,-0.172076,-0.10030900000000001,-0.06498,-0.23326599999999997,-0.191887,-0.18320799999999998,-0.135714,-0.21595599999999998,-0.29338200000000003 +475,475,20210621,0.0,-0.616452,-0.639174,-0.6533,-0.677929,-0.572391,-0.6630590000000001,-0.553149,-0.180014,-0.25699,0.068969,-0.30806300000000003,0.074002,-0.005372 +476,476,20210621,0.0,0.253137,-0.326264,-0.292543,-0.260658,-0.21216500000000002,-0.163175,-0.263844,-0.227228,-0.19622699999999998,-0.24000500000000002,-0.237846,-0.248683,-0.269756 +477,477,20210621,0.0,0.253137,-0.0044859999999999995,-0.290169,-0.256274,-0.22927899999999998,-0.184311,-0.155051,-0.23326599999999997,-0.191887,-0.228645,-0.23127199999999998,-0.237817,-0.23713 +478,478,20210621,0.0,0.253137,0.210983,0.267251,0.37432600000000005,0.435011,0.169396,0.20044700000000001,-0.189916,0.0012519999999999999,-0.29680100000000004,-0.19431199999999998,-0.18421099999999999,-0.141502 +479,479,20210621,0.0,0.253137,-0.687493,-0.686768,-0.670704,-0.667834,-0.653189,-0.6451680000000001,-0.341942,-0.23524499999999998,-0.279762,-0.26976300000000003,-0.2945,-0.259631 +480,480,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +481,481,20210621,0.0,1.992316,-0.085467,1.235334,0.63142,-0.672497,-0.645475,-0.637293,6.905596000000001,-0.064502,-0.29680100000000004,-0.239825,-0.314136,3.5103169999999997 +482,482,20210621,1.0,1.992316,1.088396,1.3630799999999998,1.343781,1.566443,1.646611,1.5347520000000001,0.684442,-0.25699,0.350681,-0.272954,0.032767000000000004,0.010378 +483,483,20210621,0.0,1.992316,-0.13525299999999998,-0.10369300000000001,-0.131599,-0.083737,-0.552262,-0.5828369999999999,-0.214429,-0.204907,-0.253749,0.12191600000000001,-0.314136,-0.29338200000000003 +484,484,20210621,0.0,1.992316,0.35826399999999997,0.339146,0.350706,0.369118,0.376942,0.344335,-0.23930300000000002,-0.08338200000000001,-0.205927,-0.20593000000000003,-0.21595599999999998,-0.063537 +485,485,20210621,0.0,-0.616452,-0.661813,-0.666971,-0.669652,-0.663855,-0.625128,-0.609704,-0.23876,-0.232077,-0.26522199999999996,-0.160864,-0.146445,-0.17463399999999998 +486,486,20210621,0.0,0.253137,1.715642,1.8469740000000001,1.8154869999999999,1.350437,1.236634,1.319717,0.11691199999999999,0.016572,-0.061833000000000006,-0.08452,-0.050555,-0.095544 +487,487,20210621,0.0,-0.616452,-0.6024109999999999,-0.47866899999999996,-0.48808999999999997,-0.672497,-0.49035,-0.535316,0.570393,0.314396,-0.29680100000000004,0.362183,0.143514,-0.29338200000000003 +488,488,20210621,0.0,0.253137,0.577781,0.594947,0.6426390000000001,0.745045,0.8639629999999999,0.9479139999999999,-0.141676,-0.104823,-0.057233000000000006,0.011101999999999999,0.08382,-0.24061799999999997 +489,489,20210621,1.0,-0.616452,-0.690264,-0.667828,-0.666508,-0.666342,-0.6565449999999999,-0.646075,-0.242443,-0.222615,-0.29680100000000004,-0.282785,-0.288217,-0.248831 +490,490,20210621,0.0,-0.616452,-0.472567,-0.605445,-0.610688,-0.612107,-0.5904550000000001,-0.61051,0.037036,-0.054607,-0.061663,-0.026304,-0.14094600000000002,0.141164 +491,491,20210621,0.0,-1.486041,-0.68786,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.332463,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +492,492,20210621,0.0,0.253137,-0.30583899999999997,-0.31693499999999997,-0.331532,-0.293711,-0.319961,-0.323052,-0.263453,-0.256903,-0.205472,-0.30806300000000003,-0.255228,-0.248381 +493,493,20210621,0.0,0.253137,0.6428590000000001,0.727821,2.524777,1.017554,0.463658,0.508827,-0.10044,0.259493,-0.285044,-0.180205,-0.183033,-0.18070899999999998 +494,494,20210621,0.0,-1.486041,-0.311257,-0.44347200000000003,-0.673487,-0.672497,-0.6630590000000001,-0.652724,-0.10044,-0.24362199999999998,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +495,495,20210621,1.0,0.253137,-0.579202,-0.5584319999999999,-0.533181,-0.5164310000000001,-0.49199499999999996,-0.476579,-0.26931,-0.211548,-0.28271599999999997,-0.282019,-0.29489299999999996,-0.277857 +496,496,20210621,0.0,-0.616452,-0.688743,-0.681542,-0.67467,-0.666435,-0.6594399999999999,-0.647351,-0.281566,-0.240063,-0.24000500000000002,-0.29401900000000003,-0.272246,-0.23713 +497,497,20210621,0.0,0.253137,2.063698,2.160691,2.1260220000000003,2.386861,2.6352759999999997,2.684079,0.112143,0.046824,0.100775,0.146938,0.20949099999999998,0.10600699999999999 +498,498,20210621,0.0,0.253137,-0.47237700000000005,-0.404117,-0.413567,-0.37951599999999996,-0.166481,-0.32253200000000004,0.105018,-0.25699,-0.250228,-0.24263400000000002,-0.241287,-0.287532 +499,499,20210621,0.0,-0.616452,-0.694746,-0.690983,-0.677929,-0.670632,-0.663157,-0.625203,-0.341942,-0.25699,-0.289986,-0.30768,-0.206465,-0.29338200000000003 +500,500,20210621,0.0,0.253137,-0.479548,-0.44830600000000004,-0.381382,-0.35065,-0.329896,-0.318015,-0.243952,-0.087028,-0.254204,-0.30806300000000003,-0.261773,-0.24556799999999998 +501,501,20210621,0.0,1.992316,-0.41935900000000004,-0.38602,-0.352946,-0.296929,-0.249743,-0.24005100000000001,-0.221191,-0.191887,-0.18320799999999998,-0.212313,-0.314136,-0.22588000000000003 +502,502,20210621,0.0,1.992316,-0.381496,-0.375216,-0.27320300000000003,-0.247824,-0.149885,-0.13977,-0.341942,0.0034219999999999997,-0.29680100000000004,-0.020814,-0.314136,-0.180878 +503,503,20210621,0.0,0.253137,2.3136759999999996,2.504025,2.643021,2.2286349999999997,2.460429,2.5939740000000002,0.261814,0.133627,0.157572,0.202601,0.176764,0.100381 +504,504,20210621,1.0,0.253137,-0.435425,-0.402333,-0.350537,-0.325795,-0.296193,-0.652724,-0.221191,-0.12678399999999998,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +505,505,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +506,506,20210621,0.0,-0.616452,-0.690264,-0.685419,-0.672218,-0.672497,-0.650031,-0.632238,-0.318033,-0.239802,-0.29680100000000004,-0.257443,-0.234283,-0.29338200000000003 +507,507,20210621,0.0,-0.616452,-0.641876,-0.690983,3.433755,3.20498,3.002158,-0.649366,-0.341942,12.11853,-0.013443,-0.301679,-0.301045,29.445097999999998 +508,508,20210621,0.0,1.992316,-0.122026,-0.14665899999999998,-0.148773,-0.11580499999999999,-0.039779,-0.07070599999999999,-0.191003,-0.17018599999999998,-0.232735,-0.14848,-0.314136,-0.180878 +509,509,20210621,0.0,1.992316,-0.403565,-0.50542,-0.476092,-0.502846,-0.487307,-0.560118,-0.23930300000000002,-0.19622699999999998,-0.28544200000000003,-0.24423000000000003,-0.314136,-0.265256 +510,510,20210621,0.0,-1.486041,-0.6836369999999999,-0.690983,-0.677929,-0.51012,-0.6630590000000001,-0.652724,-0.341942,-0.25699,0.29649699999999996,-0.30806300000000003,-0.314136,-0.29338200000000003 +511,511,20210621,0.0,1.992316,-0.678517,-0.673266,-0.659745,-0.650564,-0.647762,-0.646175,-0.265808,-0.20226,-0.21666100000000002,-0.248698,-0.314136,-0.249506 +512,512,20210621,1.0,-0.616452,-0.6923819999999999,-0.687611,-0.6744680000000001,-0.668767,-0.659111,-0.648694,-0.32745100000000005,-0.24657300000000001,-0.28317,-0.292743,-0.298427,-0.279882 +513,513,20210621,0.0,-0.616452,-0.42100200000000004,0.053151,-0.620566,-0.645403,-0.616542,0.19588,2.871727,-0.083512,-0.197407,-0.125947,3.02667,-0.11230699999999999 +514,514,20210621,1.0,1.992316,-0.29489299999999996,-0.259061,-0.224593,-0.176257,-0.1274,-0.097237,-0.221191,-0.191887,-0.222966,-0.22508000000000003,-0.235592,-0.209004 +515,515,20210621,0.0,0.253137,-0.446371,-0.406337,-0.39624899999999996,-0.41652700000000004,-0.404062,-0.43030100000000004,-0.166853,-0.25655500000000003,-0.26403000000000004,-0.280614,-0.24756999999999998,-0.293157 +516,516,20210621,0.0,0.253137,0.58453,0.05896799999999999,0.559118,0.551812,0.6450670000000001,0.69624,-0.197946,3.5918010000000002,-0.17360899999999999,-0.139927,-0.109136,-0.252206 +517,517,20210621,0.0,0.253137,0.237873,0.259228,0.319761,0.39061599999999996,0.486422,0.544258,-0.157193,-0.11376300000000002,-0.148562,-0.132522,-0.134139,0.016004 +518,518,20210621,0.0,0.253137,-0.506641,-0.456413,-0.37049499999999996,-0.383154,-0.350489,-0.32631,-0.160815,-0.03998,-0.18320799999999998,-0.26861399999999996,-0.26969299999999996,-0.265256 +519,519,20210621,0.0,0.253137,-0.556441,-0.5707399999999999,-0.526158,-0.5162760000000001,-0.50017,-0.485076,-0.341942,-0.164717,-0.27465100000000003,-0.287125,-0.28298,-0.22098600000000002 +520,520,20210621,0.0,0.253137,0.578813,0.6818489999999999,0.808281,0.9575520000000001,1.14875,1.283312,0.020312,0.046824,-0.012818000000000001,0.138768,0.144038,0.100381 +521,521,20210621,0.0,0.253137,-0.471617,-0.44479300000000005,-0.41071199999999997,-0.381133,-0.345752,-0.319946,-0.245522,-0.18728599999999998,-0.250285,-0.24423000000000003,-0.248683,-0.202085 +522,522,20210621,0.0,0.253137,-0.69643,-0.227448,-0.152104,0.016276,0.363454,0.37862399999999996,1.653409,0.43743999999999994,0.19733,0.8904,0.667665,0.007566 +523,523,20210621,1.0,-0.616452,-0.6792090000000001,-0.679462,0.254236,1.28585,1.090079,1.455595,-0.318395,3.029399,3.254126,0.777097,8.3388,9.100689 +524,524,20210621,1.0,0.253137,0.818537,0.884525,0.324678,0.42811000000000005,0.5011770000000001,0.467872,0.02164,-0.125872,-0.012136,0.018251,-0.117776,-0.012121999999999999 +525,525,20210621,0.0,0.253137,0.219335,0.285362,0.344981,0.442986,0.545982,0.603751,-0.14874,-0.118104,-0.14912999999999998,-0.122947,-0.13741199999999998,-0.124626 +526,526,20210621,0.0,-0.616452,-0.672664,-0.5048159999999999,-0.6716850000000001,-0.644035,-0.6630590000000001,-0.604179,0.458034,-0.238197,-0.192807,-0.30806300000000003,-0.12491,8.341513 +527,527,20210621,0.0,1.992316,-0.442378,-0.43715,-0.40337199999999995,-0.370221,-0.321606,-0.312843,-0.341942,-0.187807,-0.24000500000000002,-0.20554699999999998,-0.314136,-0.276506 +528,528,20210621,1.0,0.253137,1.488616,1.5126600000000001,1.635613,1.8733830000000002,2.086442,2.216882,-0.341942,0.012102,0.043979000000000004,0.074935,0.111311,0.044129 +529,529,20210621,0.0,-0.616452,-0.69575,-0.691096,-0.678044,-0.672622,-0.635475,-0.609066,-0.341942,-0.25699,-0.29680100000000004,-0.200504,-0.14310599999999998,-0.29338200000000003 +530,530,20210621,0.0,-0.616452,-0.44083,-0.488518,-0.479351,-0.66687,-0.57575,-0.652724,0.5280699999999999,-0.25699,-0.295211,1.1009209999999998,-0.314136,-0.29338200000000003 +531,531,20210621,0.0,0.253137,-0.22644699999999998,-0.430321,-0.399133,-0.390133,-0.345242,-0.32402600000000004,-0.170717,-0.204907,0.44155500000000003,-0.212313,0.274944,-0.23713 +532,532,20210621,0.0,0.253137,0.628979,0.00011100000000000001,-0.42531899999999995,-0.397206,-0.365688,-0.345402,-0.19378,-0.188067,-0.2525,-0.256805,-0.270086,-0.25755 +533,533,20210621,1.0,0.253137,-0.640328,-0.6011449999999999,-0.5893470000000001,-0.565116,-0.5536439999999999,-0.538792,-0.19704000000000002,-0.25699,-0.247331,-0.30806300000000003,-0.298165,-0.279263 +534,534,20210621,1.0,1.992316,0.035657999999999995,0.082208,0.20996700000000001,0.298562,0.343551,0.397162,-0.21817199999999998,0.068524,-0.15481,-0.30806300000000003,-0.150503,-0.152752 +535,535,20210621,0.0,-1.486041,-0.662899,-0.648003,-0.6442869999999999,-0.644517,-0.636412,-0.652724,-0.15671,-0.151089,-0.19417,-0.167375,-0.314136,-0.29338200000000003 +536,536,20210621,0.0,0.253137,-0.6891229999999999,-0.667449,-0.625584,-0.663513,-0.583695,-0.548615,-0.240813,-0.14848499999999998,-0.263973,-6.9e-05,-0.183229,-0.156409 +537,537,20210621,0.0,0.253137,3.796253,4.055142,3.274227,3.253773,2.898796,2.356707,0.448978,0.220431,0.271165,0.266434,0.150583,0.016004 +538,538,20210621,0.0,0.253137,0.5538649999999999,0.5445909999999999,0.505865,0.24625500000000003,0.21597800000000003,0.132709,-0.014887000000000001,-0.133424,-0.17945899999999998,-0.185567,-0.170139,-0.29338200000000003 +539,539,20210621,0.0,-0.616452,-0.65141,-0.63245,-0.677929,-0.672497,-0.657828,-0.652724,-0.281566,-0.25699,-0.29680100000000004,-0.28776399999999996,-0.314136,-0.29338200000000003 +540,540,20210621,0.0,1.992316,0.562435,0.586264,0.703044,0.8353729999999999,0.9654159999999999,1.046817,-0.305716,0.05984400000000001,-0.086654,-0.071881,-0.052323,-0.079625 +541,541,20210621,0.0,-0.616452,-0.6902229999999999,-0.690983,-0.677929,-0.672497,-0.659473,-0.6481899999999999,-0.341942,-0.25699,-0.29680100000000004,-0.294147,-0.296464,-0.27555 +542,542,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.647384,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.29332199999999997,-0.29338200000000003 +543,543,20210621,1.0,0.253137,-0.30482,-0.297026,-0.270045,-0.244513,-0.19939400000000002,-0.16903800000000002,-0.341942,-0.213588,-0.29680100000000004,-0.237846,-0.242137,-0.209004 +544,544,20210621,0.0,-0.616452,-0.286975,-0.262644,-0.242763,-0.21028400000000003,-0.420971,-0.158594,-0.248178,-0.03998,-0.29186,0.634175,1.6176549999999998,-0.274819 +545,545,20210621,0.0,-0.616452,-0.528071,-0.548541,-0.33311799999999997,-0.5203949999999999,-0.660328,-0.6167560000000001,0.261814,0.346817,0.258954,-0.30806300000000003,-0.17393499999999998,-0.055436 +546,546,20210621,0.0,0.253137,-0.008194,-0.083727,-0.040032,0.05024,0.12237,0.219455,-0.040063999999999995,-0.12678399999999998,-0.126411,-0.180397,0.013131,-0.012121999999999999 +547,547,20210621,1.0,-1.486041,-0.696525,-0.691897,-0.678866,-0.673508,-0.6641279999999999,-0.656083,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +548,548,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +549,549,20210621,0.0,0.253137,-0.663008,-0.587615,-0.537305,-0.476513,-0.485465,-0.307839,0.102241,-0.14562,-0.126411,-0.24423000000000003,0.340398,-0.180878 +550,550,20210621,0.0,0.253137,0.016482,0.01818,-0.027775,-0.121852,-0.140657,-0.12858699999999998,-0.038615,-0.03998,-0.012818000000000001,-0.05273099999999999,0.013131,-0.0965 +551,551,20210621,1.0,0.253137,-0.632397,-0.605726,-0.585381,-0.567091,-0.561999,-0.524469,-0.25137800000000005,-0.213588,-0.24000500000000002,-0.30806300000000003,-0.183229,-0.180878 +552,552,20210621,1.0,-0.616452,-0.312616,-0.690983,-0.439999,-0.672497,-0.22135300000000002,-0.643422,-0.341942,0.45914099999999997,-0.29680100000000004,1.406107,-0.281409,-0.29338200000000003 +553,553,20210621,1.0,0.253137,-0.006903,0.02661,-0.271502,-0.224165,-0.163043,-0.149358,-0.191003,-0.191887,-0.234325,-0.180397,-0.21595599999999998,-0.23617399999999997 +554,554,20210621,0.0,-1.486041,-0.695642,-0.601483,-0.677929,-0.672497,-0.6630590000000001,-0.652724,0.04265,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +555,555,20210621,0.0,-1.486041,-0.216452,-0.17513900000000002,-0.139256,-0.078949,-0.02611,-0.027148000000000002,-0.221191,-0.187547,-0.217229,-0.205483,-0.19632,-0.194885 +556,556,20210621,0.0,-1.486041,-0.181617,0.26706799999999997,-0.660524,-0.631584,-0.520714,-0.652724,1.963618,-0.204603,-0.147312,0.24434699999999998,-0.314136,-0.013191 +557,557,20210621,0.0,-1.486041,-0.624575,-0.61521,-0.6516270000000001,-0.667057,-0.660591,-0.649383,-0.015853,-0.177608,-0.276922,-0.29848800000000003,-0.301111,-0.22897399999999998 +558,558,20210621,0.0,1.992316,0.191156,0.35668099999999997,0.45427,0.568398,0.679181,0.744449,0.322189,-0.005259000000000001,-0.115052,-0.103797,-0.111231,-0.124626 +559,559,20210621,0.0,-1.486041,-0.46194700000000005,-0.43218999999999996,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.21786999999999998,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +560,560,20210621,0.0,0.253137,0.081058,0.13056900000000002,0.182338,0.267411,0.350049,0.441475,-0.17289000000000002,-0.137504,-0.16048900000000002,-0.16411900000000001,-0.00212,-0.29338200000000003 +561,561,20210621,0.0,-0.616452,-0.617146,-0.522295,-0.451016,-0.569578,-0.622645,-0.40214099999999997,0.382927,-0.008036,0.079249,-0.151225,0.662625,-0.197079 +562,562,20210621,0.0,-1.486041,-0.68695,-0.661295,-0.6780149999999999,-0.656968,-0.6475310000000001,-0.652775,-0.207244,-0.25699,-0.23972100000000002,-0.247549,-0.314136,-0.24899899999999997 +563,563,20210621,0.0,-0.616452,-0.687072,-0.651783,-0.652578,-0.666031,-0.656216,-0.5916020000000001,-0.173494,-0.18068900000000002,-0.273174,-0.281508,-0.075886,-0.252318 +564,564,20210621,0.0,0.253137,0.775826,0.8714299999999999,0.23263499999999998,0.31804,0.40786500000000003,0.45683999999999997,0.14136400000000002,0.09039900000000001,-0.012818000000000001,0.011101999999999999,0.013131,5.652446 +565,565,20210621,0.0,1.992316,-0.684316,-0.688806,-0.702298,-0.606589,-0.6080220000000001,-0.60742,-0.341881,-0.18350999999999998,0.097368,-0.307616,-0.23362800000000003,-0.293213 +566,566,20210621,0.0,-1.486041,-0.597264,-0.5719489999999999,-0.652867,-0.5682560000000001,-0.62373,-0.466638,0.172096,-0.18099300000000001,0.085951,-0.154672,0.414818,0.460787 +567,567,20210621,1.0,0.253137,-0.51718,-0.486888,-0.454679,-0.38929400000000003,-0.289071,-0.26001599999999997,-0.24534099999999998,-0.191887,-0.126411,0.011101999999999999,-0.24737399999999998,-0.250406 +568,568,20210621,0.0,-0.616452,-0.599614,-0.685349,-0.6268100000000001,-0.508659,-0.496403,-0.54828,-0.250775,-0.101828,0.30371,0.340161,0.094293,0.610643 +569,569,20210621,0.0,0.253137,-0.214496,-0.260677,-0.24185399999999999,-0.357194,-0.347808,-0.32416,-0.249144,-0.172486,-0.251364,-0.24423000000000003,-0.26714099999999996,-0.25496199999999997 +570,570,20210621,0.0,-1.486041,-0.440993,-0.610812,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.281566,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +571,571,20210621,0.0,-0.616452,0.061991,-0.573522,-0.607314,-0.593765,-0.342841,-0.652724,0.16485,-0.043149,-0.007763,0.940573,-0.314136,-0.286351 +572,572,20210621,0.0,0.253137,-0.019207,0.016649,-0.12378299999999999,-0.380029,-0.36196999999999996,-0.333463,-0.21877600000000003,-0.13694,-0.20081500000000002,-0.24423000000000003,-0.248683,-0.23713 +573,573,20210621,0.0,-0.616452,-0.547614,-0.543764,-0.678246,-0.6728390000000001,-0.66342,-0.576624,0.293813,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.016061000000000002,-0.29338200000000003 +574,574,20210621,1.0,-0.616452,-0.653162,-0.61854,-0.662225,-0.664896,-0.6108020000000001,-0.635781,-0.030645,-0.209725,-0.29680100000000004,-0.10526500000000001,-0.248094,-0.29338200000000003 +575,575,20210621,0.0,-0.616452,-0.6499159999999999,-0.625776,-0.644907,-0.649818,-0.551801,-0.52509,-0.061738999999999995,-0.157599,-0.213935,0.123703,0.183375,0.15607100000000002 +576,576,20210621,1.0,0.253137,3.10162,3.271554,3.395831,3.7523760000000004,3.545959,3.348175,0.44293999999999994,0.18570899999999999,0.28621599999999997,0.253859,0.229127,0.187347 +577,577,20210621,0.0,0.253137,-0.689191,-0.6843100000000001,-0.595865,-0.089178,0.168655,0.16819,-0.313263,-0.00999,1.634285,0.585598,0.20949099999999998,0.550397 +578,578,20210621,0.0,-0.616452,-0.61424,-0.23823899999999998,-0.558127,-0.609045,-0.654209,-0.58413,0.48200299999999996,0.103854,-0.064957,-0.30806300000000003,-0.046758999999999995,-0.29338200000000003 +579,579,20210621,0.0,0.253137,-0.6250640000000001,-0.606471,-0.582541,-0.56165,-0.548133,-0.535518,-0.263453,-0.209247,-0.24000500000000002,-0.276146,-0.281409,-0.23713 +580,580,20210621,0.0,-1.486041,-0.589754,-0.65323,-0.551581,-0.620004,-0.630162,-0.652724,-0.179713,0.123428,-0.10426099999999999,-0.177843,-0.314136,-0.29338200000000003 +581,581,20210621,1.0,-1.486041,-0.695642,-0.680024,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.29484899999999997,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +582,582,20210621,0.0,0.253137,-0.20966100000000001,-0.28134499999999996,-0.281596,-0.217574,-0.077528,-0.007098999999999999,0.573049,-0.018930000000000002,0.00212,0.24077300000000001,0.042519,0.074337 +583,583,20210621,0.0,-0.616452,-0.676181,-0.638351,-0.24160900000000002,-0.656393,-0.308233,-0.492733,-0.11511099999999999,1.06017,-0.237506,1.073026,0.311336,0.047842 +584,584,20210621,0.0,0.253137,0.360464,0.404298,0.45421300000000003,0.267194,0.34944000000000003,0.254399,-0.10044,-0.153953,-0.18281,-0.14848,-0.117776,-0.180878 +585,585,20210621,0.0,0.253137,-0.012539,0.024152,0.030251,0.088293,0.08986799999999999,-0.652724,-0.209115,-0.187547,-0.200247,-0.199547,-0.314136,-0.29338200000000003 +586,586,20210621,0.0,1.992316,-0.497325,-0.470941,-0.441528,-0.41254799999999997,-0.366066,-0.356887,-0.24534099999999998,-0.200567,-0.262723,-0.20593000000000003,-0.314136,-0.248381 +587,587,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +588,588,20210621,1.0,-0.616452,-0.575902,-0.358917,-0.363919,-0.5227890000000001,-0.637383,-0.619309,1.0935469999999998,-0.25699,0.250207,-0.208419,-0.183884,0.154777 +589,589,20210621,0.0,0.253137,1.091221,1.148644,1.239481,0.036079,0.102056,0.144127,0.062574,0.0034219999999999997,-0.223477,-0.223867,-0.22669,-0.216598 +590,590,20210621,0.0,-0.616452,-0.616318,-0.3651,0.22131599999999998,0.369865,-0.38304099999999996,-0.339407,1.058408,1.9131040000000001,0.35636,0.778629,0.907158,1.8961119999999998 +591,591,20210621,0.0,0.253137,-0.283594,-0.325941,-0.330523,0.35094699999999995,0.266902,0.212419,-0.040063999999999995,-0.03998,3.4426910000000004,-0.180397,-0.183229,0.269137 +592,592,20210621,0.0,0.253137,0.435008,0.48801000000000005,0.550091,0.659892,0.76422,0.8169890000000001,-0.10044,-0.086681,-0.115052,-0.097414,-0.08995800000000001,-0.123895 +593,593,20210621,0.0,0.253137,-0.220648,-0.606428,-0.477058,-0.5620390000000001,-0.5640390000000001,-0.501414,-0.273898,-0.21037600000000004,-0.28459,-0.292168,-0.027254,-0.28370700000000004 +594,594,20210621,0.0,0.253137,-0.03363,-0.045299,-0.029188,-0.029611000000000002,0.034009,-0.013765000000000001,-0.212436,-0.176956,-0.182697,0.012187,-0.183229,-0.01201 +595,595,20210621,0.0,0.253137,0.074376,0.122181,0.173485,0.256375,0.34036,0.39194,-0.180075,-0.138763,-0.166907,-0.157289,-0.15875,-0.15534 +596,596,20210621,0.0,0.253137,1.269167,1.2873629999999998,1.28949,1.429932,1.551375,1.602557,-0.03463,-0.039373000000000005,-0.012306999999999998,0.001144,0.013262000000000001,-0.017634999999999998 +597,597,20210621,0.0,0.253137,2.945471,3.00943,3.0708189999999997,3.3042620000000005,3.374402,3.5493059999999996,0.22733899999999999,0.12225599999999999,0.101741,0.148598,0.148816,0.117257 +598,598,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +599,599,20210621,0.0,0.253137,0.380523,0.36636199999999997,0.16827899999999998,0.242851,0.324422,0.308838,-0.145782,-0.12678399999999998,-0.012818000000000001,-0.14848,-0.16359300000000002,-0.169628 +600,600,20210621,1.0,-0.616452,-0.7020930000000001,-0.6180479999999999,-0.61151,-0.636698,-0.617529,0.44500200000000006,0.261814,-0.25699,-0.29680100000000004,-0.131373,3.964747,0.313014 +601,601,20210621,0.0,0.253137,-0.377911,-0.351218,-0.315483,-0.28241,-0.245993,-0.2243,-0.255846,-0.197138,-0.247559,-0.250741,-0.25306799999999996,-0.24798699999999999 +602,602,20210621,1.0,-0.616452,-0.690345,-0.685504,-0.672305,-0.666435,-0.656644,-0.630559,-0.318395,-0.240063,-0.27465100000000003,-0.283168,-0.22773800000000002,-0.29338200000000003 +603,603,20210621,0.0,0.253137,-0.45306599999999997,-0.43910299999999997,-0.406833,-0.398185,-0.36674,-0.43560699999999997,-0.262065,-0.20508099999999999,-0.265904,-0.272125,-0.272966,-0.273075 +604,604,20210621,0.0,1.992316,-0.336436,-0.28601,-0.27170300000000003,-0.22575100000000003,-0.162139,-0.150148,-0.160392,-0.25699,-0.244321,-0.175928,-0.314136,-0.124626 +605,605,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.204729 +606,606,20210621,0.0,1.992316,-0.386738,-0.380485,-0.330104,-0.308183,-0.250187,-0.240504,-0.341942,-0.13980399999999998,-0.29680100000000004,-0.16763,-0.314136,-0.23544299999999999 +607,607,20210621,0.0,-1.486041,-0.5705100000000001,-0.5454359999999999,-0.5719420000000001,-0.555914,-0.6630590000000001,-0.652724,-0.260374,-0.191887,-0.28828200000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +608,608,20210621,0.0,0.253137,-0.140441,-0.193207,-0.105744,0.012965,0.036706,-0.09542300000000001,-0.221191,-0.03998,-0.012818000000000001,-0.30806300000000003,-0.183229,-0.124626 +609,609,20210621,0.0,-1.486041,-0.641374,-0.562844,-0.554955,-0.672497,-0.558315,-0.602349,0.20868299999999998,0.113142,-0.29680100000000004,0.098425,-0.117776,-0.11123800000000002 +610,610,20210621,0.0,-0.616452,-0.690345,-0.685504,-0.672305,-0.6637770000000001,-0.656644,-0.646175,-0.318395,-0.240063,-0.264938,-0.283168,-0.288609,-0.271444 +611,611,20210621,0.0,-0.616452,-0.095693,-0.329384,-0.39973800000000004,-0.378708,-0.43968900000000005,-0.096078,-0.281204,1.171192,0.776656,0.5587880000000001,1.855643,-0.29338200000000003 +612,612,20210621,1.0,-0.616452,-0.651098,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.608226,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.140685,-0.29338200000000003 +613,613,20210621,0.0,0.253137,-0.040705,-0.006352,-0.011322,0.054282000000000004,0.05550700000000001,0.095734,-0.221191,-0.183901,-0.20586999999999997,-0.180397,-0.183229,-0.180878 +614,614,20210621,0.0,0.253137,-0.197914,-0.275922,-0.300269,-0.257306,-0.21444499999999997,-0.15651199999999998,-0.341942,-0.194708,-0.24256,-0.24467600000000003,-0.135187,-0.29338200000000003 +615,615,20210621,0.0,1.992316,0.8667889999999999,0.964935,1.046268,1.13507,1.368781,1.454269,0.020312,-0.03998,-0.29680100000000004,0.266434,-0.052323,-0.012121999999999999 +616,616,20210621,0.0,0.253137,-0.400618,-0.365465,-0.34165500000000004,-0.29811,-0.265846,-0.596925,-0.215153,-0.204907,-0.241992,-0.303977,-0.28081999999999996,0.179078 +617,617,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.677929,-0.672497,-0.6532720000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.270082,-0.314136,-0.160065 +618,618,20210621,0.0,0.253137,1.1758549999999999,1.048015,0.8271850000000001,0.9853299999999999,1.134654,1.045776,-0.040063999999999995,-0.03998,-0.072284,-0.020814,-0.052323,-0.07400000000000001 +619,619,20210621,0.0,0.253137,0.103425,0.056987,-0.12228399999999999,-0.05633200000000001,-0.011389,0.004504,-0.220104,-0.174526,-0.18320799999999998,-0.212313,-0.189775,-0.180878 +620,620,20210621,0.0,0.253137,0.402116,0.4204,0.342487,0.440934,0.501571,0.534754,-0.141797,-0.122965,-0.15072,-0.144714,-0.148801,-0.146002 +621,621,20210621,0.0,0.253137,-0.204759,-0.182585,-0.137021,-0.158288,-0.165938,-0.12276,-0.160815,-0.12678399999999998,-0.126411,-0.14848,-0.183229,-0.180878 +622,622,20210621,0.0,-0.616452,-0.691024,-0.692669,-0.671872,-0.665347,-0.655492,-0.6424810000000001,-0.341942,-0.213588,-0.268403,-0.278699,-0.27421,-0.267506 +623,623,20210621,0.0,-1.486041,-0.592104,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +624,624,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.677929,-0.672497,-0.660328,-0.64364,-0.341942,-0.25699,-0.29680100000000004,-0.297466,-0.278595,-0.053299 +625,625,20210621,0.0,-1.486041,-0.688974,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +626,626,20210621,0.0,0.253137,-0.516813,-0.49585200000000007,-0.463071,-0.425092,-0.407796,-0.386928,-0.267257,-0.202781,-0.22495300000000001,-0.30806300000000003,-0.276959,-0.218736 +627,627,20210621,0.0,0.253137,0.119735,0.085636,0.068536,0.13203499999999999,0.159576,0.18595599999999998,-0.18496500000000002,-0.178866,-0.18320799999999998,-0.107627,-0.183229,-0.192129 +628,628,20210621,0.0,-0.616452,-0.686679,-0.68171,-0.668411,-0.662238,-0.652203,-0.641642,-0.30209400000000003,-0.22834400000000002,-0.259315,-0.265933,-0.270937,-0.256256 +629,629,20210621,0.0,0.253137,-0.29591100000000004,-0.284085,-0.259432,-0.218585,-0.176959,-0.154127,-0.25349099999999997,-0.17018599999999998,-0.23813,-0.231463,-0.245083,-0.263569 +630,630,20210621,0.0,-0.616452,-0.63548,-0.590074,-0.62234,-0.619475,-0.551407,-0.486133,0.092339,-0.089675,-0.103068,0.12523499999999999,0.335227,-0.011222 +631,631,20210621,0.0,-1.486041,-0.676086,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +632,632,20210621,0.0,1.992316,-0.331751,-0.29678699999999997,-0.255654,-0.198595,-0.106592,-0.09627999999999999,-0.221191,-0.17018599999999998,-0.18320799999999998,-0.05273099999999999,-0.314136,-0.180878 +633,633,20210621,0.0,-1.486041,-0.47032700000000005,-0.45996800000000004,-0.585626,-0.6056560000000001,-0.64161,-0.652724,-0.272208,-0.213588,-0.29680100000000004,-0.22482399999999997,-0.314136,-0.29338200000000003 +634,634,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +635,635,20210621,0.0,0.253137,-0.064336,-0.18857100000000002,-0.18299200000000002,-0.199139,-0.290864,-0.258656,-0.095247,-0.195012,-0.22194299999999997,-0.169481,-0.104816,-0.013472 +636,636,20210621,0.0,-1.486041,-0.6881729999999999,-0.6877800000000001,-0.677929,-0.668953,-0.6630590000000001,-0.652724,-0.328176,-0.25699,-0.283852,-0.30806300000000003,-0.314136,-0.29338200000000003 +637,637,20210621,0.0,0.253137,-0.619183,-0.5978439999999999,-0.592591,-0.5649609999999999,-0.54889,-0.572863,-0.275106,-0.213588,-0.24000500000000002,-0.212313,-0.17341099999999998,-0.29338200000000003 +638,638,20210621,0.0,0.253137,-0.39705999999999997,-0.38861999999999997,-0.37541199999999997,-0.363257,-0.353647,-0.336956,-0.25971,-0.200828,-0.25806599999999996,-0.264656,-0.26871100000000003,-0.25861799999999996 +639,639,20210621,0.0,0.253137,0.12089000000000001,-0.66315,-0.612736,-0.354272,0.602367,2.262304,-0.222338,-0.060770000000000005,0.8675299999999999,4.6070720000000005,6.231201,0.139758 +640,640,20210621,0.0,0.253137,0.069813,0.12579200000000001,0.175316,0.196249,0.219761,0.21139499999999997,-0.160815,-0.12678399999999998,-0.18320799999999998,-0.11656400000000001,-0.117776,-0.124626 +641,641,20210621,0.0,0.253137,1.319212,1.394539,1.503958,1.53383,1.721797,1.830958,0.07464900000000001,0.041051,0.015580000000000002,0.043018,0.045857,0.021629 +642,642,20210621,0.0,-1.486041,0.664357,0.017941,0.04307,-0.672497,-0.6630590000000001,-0.652724,-0.191003,-0.213588,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +643,643,20210621,0.0,0.253137,-0.067473,0.018363,0.101024,0.23049299999999998,0.350657,0.44841000000000003,-0.040063999999999995,-0.03998,-0.012818000000000001,-0.020814,0.013131,-0.012121999999999999 +644,644,20210621,0.0,0.253137,3.058516,2.6674029999999997,1.472494,0.087733,0.209119,0.21094200000000002,0.865569,0.307235,-0.012818000000000001,0.33026700000000003,-0.052323,0.044129 +645,645,20210621,0.0,0.253137,-0.29511,-0.417943,-0.407093,-0.37706,-0.340061,-0.295883,-0.14874,-0.25699,-0.254658,-0.24423000000000003,-0.183229,-0.29338200000000003 +646,646,20210621,0.0,-1.486041,2.216711,1.3783530000000002,1.485068,-0.672497,-0.745301,-0.652724,-0.029195999999999996,-0.03998,-0.29680100000000004,-0.30806300000000003,0.013131,-0.29338200000000003 +647,647,20210621,1.0,-1.486041,-0.215311,-0.194725,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.279936,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +648,648,20210621,0.0,0.253137,0.358414,0.39515100000000003,0.2795,0.192378,0.272412,0.327745,-0.154778,-0.144752,-0.18320799999999998,-0.14848,-0.117776,-0.152752 +649,649,20210621,1.0,1.992316,1.8323669999999999,1.8630759999999997,2.093433,2.3667,2.614288,2.63634,-0.341942,0.394038,0.157572,0.138768,-0.314136,0.550397 +650,650,20210621,0.0,2.861905,-0.409431,-0.398806,-0.38655900000000004,-0.367562,-0.354865,-0.347988,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +651,651,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.662067,-0.667834,-0.6663479999999999,-0.656083,-0.341942,-0.209247,-0.279762,-0.30806300000000003,-0.314136,-0.29338200000000003 +652,652,20210621,0.0,-0.616452,-0.500788,-0.5856060000000001,-0.565222,-0.555914,-0.539695,-0.409294,-0.281566,0.08223899999999999,0.129174,0.170684,0.634741,-0.265256 +653,653,20210621,0.0,0.253137,-0.42217,-0.407461,-0.41740299999999997,-0.382345,-0.348647,-0.324496,-0.263453,-0.200524,-0.245684,-0.25061300000000003,-0.255228,-0.203379 +654,654,20210621,1.0,-1.486041,-0.698358,-0.6937939999999999,-0.677929,-0.019632,-0.6630590000000001,-0.652724,-0.341942,-0.248309,2.088659,-0.30806300000000003,-0.314136,-0.29338200000000003 +655,655,20210621,0.0,0.253137,-0.584594,-0.5626899999999999,-0.538502,-0.553987,-0.5306649999999999,-0.537583,-0.191003,-0.207294,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.209004 +656,656,20210621,1.0,-1.486041,-0.667367,-0.6410060000000001,-0.596845,-0.588557,-0.5994689999999999,-0.593517,-0.124771,-0.010814,0.011434,-0.060072,-0.082235,-0.095432 +657,657,20210621,0.0,-0.616452,-0.507958,-0.47160100000000005,-0.442984,-0.551873,-0.630162,-0.652724,-0.221191,-0.200567,-0.29680100000000004,-0.180397,-0.248683,-0.29338200000000003 +658,658,20210621,1.0,0.253137,-0.058401,-0.007209,0.033654,0.110724,0.058747,-0.074887,-0.191003,-0.17018599999999998,-0.126411,-0.180397,-0.183229,-0.180878 +659,659,20210621,0.0,-0.616452,0.027673000000000003,-0.155791,-0.393221,-0.446233,-0.6630590000000001,-0.628208,-0.070252,-0.169708,-0.120448,-0.30806300000000003,-0.218574,-0.29338200000000003 +660,660,20210621,0.0,-0.616452,-0.689843,-0.686796,-0.660928,-0.645854,-0.615769,-0.635143,-0.341942,-0.205819,-0.199452,-0.22571799999999997,-0.245606,-0.23713 +661,661,20210621,0.0,-1.486041,-0.5034770000000001,-0.577091,-0.49867399999999995,-0.48371000000000003,-0.44279799999999997,-0.519112,0.14746199999999998,0.282539,0.392994,0.546724,0.20667600000000003,-0.186222 +662,662,20210621,1.0,-0.616452,-0.113633,-0.059771000000000005,-0.677929,-0.6602640000000001,-0.639093,-0.652724,-0.15393199999999999,-0.25699,-0.252102,-0.215058,-0.314136,-0.29338200000000003 +663,663,20210621,0.0,-0.616452,-0.6816,-0.128969,-0.677929,-0.672497,-0.6630590000000001,-0.6441600000000001,2.073079,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.28075500000000003,-0.29338200000000003 +664,664,20210621,0.0,-0.616452,-0.6258779999999999,-0.607243,-0.587515,-0.579231,-0.567493,-0.646175,-0.263453,-0.213588,-0.289986,-0.295296,-0.288609,-0.22756700000000002 +665,665,20210621,0.0,1.992316,-0.36816,-0.333866,-0.262965,-0.220046,-0.174656,-0.141315,-0.221191,-0.078608,-0.234325,-0.231463,-0.22250100000000003,-0.29338200000000003 +666,666,20210621,0.0,0.253137,1.070742,1.126922,0.717565,0.851959,0.944659,1.0285309999999999,-0.007461,-0.06589099999999999,-0.080179,-0.08069,-0.050948,-0.086319 +667,667,20210621,0.0,1.992316,0.14107,0.190128,0.240552,0.321195,0.44492299999999996,0.346048,-0.160151,-0.12266099999999999,-0.18320799999999998,-0.014431,-0.314136,-0.166365 +668,668,20210621,0.0,0.253137,-0.355068,-0.332165,-0.30474,-0.27031700000000003,-0.232817,-0.200724,-0.25137800000000005,-0.19679100000000002,-0.24608200000000002,-0.24423000000000003,-0.21589099999999997,-0.180878 +669,669,20210621,0.0,1.992316,0.6217,0.7519600000000001,0.735186,0.9345469999999999,0.9368129999999999,1.051502,0.15313800000000002,-0.25699,0.157572,-0.30806300000000003,0.248763,-0.29338200000000003 +670,670,20210621,1.0,0.253137,-0.617336,-0.585451,-0.5672119999999999,-0.558743,-0.5403859999999999,-0.525141,-0.221191,-0.235289,-0.29680100000000004,-0.276146,-0.281409,-0.29338200000000003 +671,671,20210621,0.0,1.992316,0.6565479999999999,-0.236792,-0.218797,-0.096188,-0.043578,-0.033042,1.650451,1.1752719999999999,0.033187,-0.22348400000000002,-0.314136,-0.119282 +672,672,20210621,1.0,0.253137,-0.5210359999999999,-0.49170699999999995,-0.463215,-0.42935200000000007,-0.393518,-0.365367,-0.248903,-0.202824,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.23713 +673,673,20210621,1.0,0.253137,0.610714,0.465951,0.504034,0.604896,0.633734,0.6782050000000001,-0.12459,-0.092062,-0.126411,-0.11656400000000001,-0.116271,-0.124626 +674,674,20210621,1.0,5.470672,-0.663048,-0.657263,-0.643321,-0.635191,-0.623582,-0.622499,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +675,675,20210621,0.0,0.253137,0.632497,0.709443,0.792231,0.9174479999999999,1.049057,1.124832,-0.06904400000000001,-0.03781,-0.092901,-0.071881,-0.068686,-0.095938 +676,676,20210621,1.0,1.992316,0.183863,0.196493,-0.205112,-0.18065599999999998,-0.182107,-0.17741700000000002,-0.341942,-0.131124,-0.29680100000000004,-0.14848,-0.314136,-0.220255 +677,677,20210621,1.0,1.992316,1.281865,1.51162,1.620414,1.843677,2.062855,2.200661,0.5636909999999999,0.029463,0.072377,0.106851,0.144038,0.100381 +678,678,20210621,0.0,0.253137,0.28201,1.024972,1.4553049999999998,1.6525279999999998,1.846541,1.9722099999999998,2.805374,1.045066,0.043979000000000004,0.074935,0.144038,0.269137 +679,679,20210621,0.0,-0.616452,-0.650215,-0.675767,-0.61536,-0.5571109999999999,-0.596294,-0.610611,-0.27631300000000003,-0.067974,0.1248,-0.30806300000000003,-0.149979,-0.060443 +680,680,20210621,0.0,-1.486041,-0.30135700000000004,-0.451945,-0.576643,-0.5633130000000001,-0.547525,-0.534779,-0.26448,0.047865,0.10213799999999999,0.1403,0.145608,0.10173099999999999 +681,681,20210621,0.0,0.253137,-0.33371999999999996,-0.398919,-0.381367,-0.343609,-0.298874,-0.28065300000000004,-0.249446,-0.17018599999999998,-0.25232899999999997,-0.11656400000000001,-0.183229,-0.180878 +682,682,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.6631630000000001,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.212546,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +683,683,20210621,0.0,-1.486041,-0.6378020000000001,-0.614662,-0.588784,-0.672497,-0.6630590000000001,-0.652724,-0.266472,-0.213588,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +684,684,20210621,0.0,0.253137,0.750254,0.839873,0.9425020000000001,0.17874600000000002,0.294058,0.307259,0.14106300000000002,0.0034219999999999997,-0.012818000000000001,0.011101999999999999,-0.052323,-0.012121999999999999 +685,685,20210621,0.0,0.253137,2.662506,2.697498,2.756852,2.927279,3.114862,3.3073879999999996,0.261814,0.177029,0.271165,0.9047629999999999,0.536758,0.156633 +686,686,20210621,0.0,-0.616452,-0.674619,-0.691433,1.8836220000000001,2.038402,-0.5832510000000001,-0.583458,-0.341942,7.454263,-0.097559,0.003187,-0.040017000000000004,0.269531 +687,687,20210621,1.0,0.253137,-0.685049,-0.690983,-0.667373,-0.662518,-0.642465,-0.641927,-0.341942,-0.225219,-0.279762,-0.24423000000000003,-0.281409,-0.23713 +688,688,20210621,0.0,0.253137,1.513522,1.6442139999999998,1.657718,1.9265450000000002,1.990514,2.2331529999999997,0.110875,0.0034219999999999997,0.271165,0.138768,0.733118,0.05538 +689,689,20210621,0.0,0.253137,0.975433,1.073966,1.1922700000000002,1.359702,1.532262,1.6357709999999999,-0.081723,-0.000354,-0.045419,-0.015708,-0.001924,-0.025228999999999998 +690,690,20210621,0.0,0.253137,0.002019,0.037837,0.008361,0.009623,0.031986,0.061377999999999995,-0.230066,-0.183206,-0.21035700000000002,-0.209249,-0.216741,-0.209004 +691,691,20210621,0.0,-0.616452,0.119396,0.323832,0.062739,0.17218599999999998,-0.6630590000000001,-0.616975,0.865569,1.045066,2.789529,-0.30806300000000003,-0.174786,-0.29338200000000003 +692,692,20210621,0.0,-1.486041,-0.6797529999999999,-0.680024,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +693,693,20210621,1.0,0.253137,1.4690729999999999,1.51429,1.227585,1.179402,1.347118,1.446595,0.030152999999999996,-0.060378999999999995,-0.041216,0.011101999999999999,0.013131,-0.012121999999999999 +694,694,20210621,0.0,1.992316,0.060307000000000006,0.14542,0.15224400000000002,0.22707399999999997,0.33818899999999996,0.343513,0.008236,-0.25699,-0.169009,-0.020814,-0.314136,-0.152752 +695,695,20210621,0.0,-1.486041,-0.10450699999999999,-0.683986,-0.671743,-0.45088100000000003,-0.5739569999999999,-0.602903,-0.311754,-0.238283,0.516981,0.039125,-0.119085,-0.010546999999999999 +696,696,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +697,697,20210621,0.0,0.253137,-0.315848,-0.29,-0.5107,-0.569733,-0.542179,-0.5256109999999999,-0.265446,-0.18958599999999998,0.129798,-0.24423000000000003,-0.291686,-0.23713 +698,698,20210621,0.0,-1.486041,-0.576241,-0.5856060000000001,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +699,699,20210621,0.0,0.253137,-0.315033,-0.110676,0.0647,-0.116753,-0.598005,-0.41816099999999995,2.154345,2.004681,1.7337930000000001,-0.055603,0.598218,-0.043792000000000005 +700,700,20210621,0.0,-0.616452,-0.10339300000000001,-0.082884,-0.15656,-0.201424,-0.16705699999999998,-0.643304,-0.24201999999999999,-0.17899600000000002,-0.254204,-0.30806300000000003,-0.277417,-0.265256 +701,701,20210621,0.0,-0.616452,-0.695642,-0.575279,-0.677929,-0.672497,-0.637991,-0.652724,0.155251,-0.25699,-0.29680100000000004,-0.210781,-0.314136,-0.271725 +702,702,20210621,0.0,-0.616452,-0.617146,-0.689508,-0.676415,-0.672497,-0.541603,-0.508517,-0.335602,-0.252432,-0.29680100000000004,0.16328,0.247977,-0.22003000000000003 +703,703,20210621,1.0,-1.486041,-0.585517,-0.553599,-0.558834,-0.672497,-0.6630590000000001,-0.652724,-0.221191,-0.212025,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +704,704,20210621,1.0,0.253137,0.017542,0.031542,0.042594,-0.36104899999999995,-0.33284,-0.021103,-0.341942,-0.25699,-0.18320799999999998,-0.24423000000000003,-0.248683,-0.203379 +705,705,20210621,0.0,1.992316,-0.388965,-0.318396,-0.305691,-0.282177,-0.258937,-0.21014499999999997,-0.064214,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.170139,-0.152752 +706,706,20210621,1.0,0.253137,-0.485849,-0.46066999999999997,-0.41698500000000005,-0.38609099999999996,-0.356806,-0.33267399999999997,-0.25137800000000005,-0.17018599999999998,-0.211606,-0.231463,-0.255228,-0.23713 +707,707,20210621,0.0,0.253137,0.093416,0.13814200000000001,0.133512,0.161663,0.18415,0.197206,-0.191003,-0.14848499999999998,-0.18320799999999998,-0.180397,-0.10468499999999999,-0.180878 +708,708,20210621,0.0,1.992316,-0.52875,-0.525105,-0.486604,-0.474182,-0.44019899999999995,-0.406339,-0.341942,-0.171488,-0.29680100000000004,-0.24423000000000003,-0.21595599999999998,-0.29338200000000003 +709,709,20210621,0.0,0.253137,-0.553372,-0.588711,-0.668008,-0.6618029999999999,-0.651742,-0.630559,-0.281566,-0.227129,-0.29680100000000004,-0.30806300000000003,-0.27159099999999997,-0.29338200000000003 +710,710,20210621,0.0,0.253137,-0.473926,-0.445144,-0.41179399999999994,-0.38610700000000003,-0.35382800000000003,-0.484807,-0.25494,-0.19622699999999998,-0.2759,-0.284061,-0.301045,-0.29338200000000003 +711,711,20210621,0.0,0.253137,-0.455524,-0.434579,-0.41758999999999996,-0.383853,-0.348039,-0.348995,-0.244677,-0.17018599999999998,-0.2525,-0.24423000000000003,-0.248683,-0.180878 +712,712,20210621,0.0,0.253137,-0.044969999999999996,-0.339401,-0.30635500000000004,-0.261969,-0.20316099999999998,0.12396099999999999,-0.235983,-0.191887,-0.24000500000000002,-0.18620599999999998,-0.248683,-0.180878 +713,713,20210621,0.0,-0.616452,-0.439159,-0.49078,-0.62283,-0.635128,-0.6578109999999999,-0.652724,-0.341942,-0.090847,-0.18320799999999998,-0.2877,-0.314136,-0.29338200000000003 +714,714,20210621,0.0,-0.616452,-0.695642,-0.667238,-0.677929,-0.672497,-0.6630590000000001,-0.572963,-0.239907,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.0032329999999999998,-0.29338200000000003 +715,715,20210621,0.0,-1.486041,-0.6928850000000001,-0.680207,-0.668354,-0.653067,-0.663223,-0.616219,-0.295452,-0.22804000000000002,-0.225465,-0.30806300000000003,-0.17118599999999998,-0.29338200000000003 +716,716,20210621,0.0,0.253137,-0.220838,-0.237508,-0.22726100000000002,-0.17485799999999999,-0.11083599999999999,-0.154933,-0.244556,-0.17018599999999998,-0.211606,-0.180397,-0.206465,-0.23353000000000002 +717,717,20210621,0.0,0.253137,0.403895,0.43778,0.507134,0.611254,0.737442,0.808979,-0.10044,-0.08338200000000001,-0.098013,-0.05273099999999999,-0.052323,-0.152752 +718,718,20210621,1.0,0.253137,0.247094,0.27769,-0.11867899999999999,-0.614081,-0.642317,-0.652724,-0.198127,-0.169101,-0.24000500000000002,-0.306467,-0.314136,-0.20051 +719,719,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +720,720,20210621,0.0,0.253137,-0.082153,-0.10248399999999999,-0.060292,-0.302556,-0.47023400000000004,-0.195385,-0.160815,-0.108859,-0.18320799999999998,0.011101999999999999,0.814018,-0.180878 +721,721,20210621,0.0,0.253137,-0.371175,-0.291124,-0.310234,-0.271793,-0.190858,-0.140241,-0.021951,-0.25699,-0.24000500000000002,-0.094095,-0.16359300000000002,-0.29338200000000003 +722,722,20210621,1.0,0.253137,-0.587541,-0.555412,-0.555099,-0.53838,-0.510203,-0.568211,-0.221191,-0.213588,-0.268403,-0.212313,-0.314136,-0.152752 +723,723,20210621,0.0,-0.616452,-0.695642,-0.644083,-0.629867,-0.620688,-0.608236,-0.596757,-0.140408,-0.112331,-0.107498,-0.095307,-0.09598,-0.105894 +724,724,20210621,0.0,-0.616452,-0.570809,-0.49540200000000006,-0.6199319999999999,-0.667585,-0.524563,-0.647418,0.49981400000000004,-0.082427,-0.278854,0.229411,-0.293453,-0.264356 +725,725,20210621,0.0,1.992316,-0.34343,-0.308673,-0.262878,-0.206118,-0.179722,-0.125447,-0.221191,-0.15551600000000002,-0.18320799999999998,-0.30806300000000003,-0.150503,-0.29338200000000003 +726,726,20210621,1.0,0.253137,-0.5986899999999999,-0.5727359999999999,-0.536397,-0.524701,-0.502621,-0.481583,-0.257416,-0.183206,-0.29680100000000004,-0.282529,-0.274864,-0.282132 +727,727,20210621,0.0,-0.616452,-0.520928,-0.6282909999999999,-0.395874,-0.534245,-0.575405,-0.635966,-0.07121799999999999,0.594685,-0.284192,0.033763,-0.24881399999999998,0.21311 +728,728,20210621,0.0,-1.486041,-0.695832,-0.6549020000000001,-0.683509,-0.678513,-0.669424,-0.650827,-0.186052,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.281409,-0.151908 +729,729,20210621,0.0,-0.616452,-0.022738,1.19116,1.170886,0.5618380000000001,-0.517079,0.184847,5.091855000000001,-0.12678399999999998,-0.012818000000000001,0.25845500000000005,2.950678,-0.264187 +730,730,20210621,1.0,1.992316,-0.688227,-0.687401,-0.671238,-0.6542640000000001,-0.651018,-0.635546,-0.341942,-0.235289,-0.24000500000000002,-0.30806300000000003,-0.276042,-0.29338200000000003 +731,731,20210621,0.0,0.253137,-0.560719,-0.536022,-0.493425,-0.517317,-0.484034,-0.523999,-0.267438,-0.17018599999999998,-0.279933,-0.24423000000000003,-0.294042,-0.273075 +732,732,20210621,0.0,0.253137,1.3802290000000002,1.502333,1.604451,1.844672,2.058282,2.181754,0.020312,-0.03998,-0.012818000000000001,0.011101999999999999,0.007698,0.269137 +733,733,20210621,0.0,-1.486041,-0.678286,-0.682005,-0.668974,-0.6727770000000001,-0.663355,-0.653026,-0.341942,-0.230037,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +734,734,20210621,0.0,-0.616452,-0.69135,-0.6865439999999999,-0.677929,-0.667585,-0.652663,-0.652724,-0.322863,-0.25699,-0.278854,-0.26771999999999996,-0.314136,-0.275606 +735,735,20210621,0.0,0.253137,-0.069143,-0.11421600000000001,-0.09981699999999999,-0.040477,-0.029318,-0.13385999999999998,-0.202716,-0.16536800000000001,-0.1259,-0.197951,-0.21595599999999998,-0.29338200000000003 +736,736,20210621,0.0,0.253137,-0.324281,-0.7056100000000001,-0.424555,-0.393941,-0.362118,-0.339407,-0.279091,0.561656,-0.26045100000000004,-0.265741,-0.270544,-0.25456799999999996 +737,737,20210621,0.0,0.253137,0.684049,0.7405510000000001,0.784848,0.8948309999999999,1.013248,0.9711040000000001,-0.10044,-0.081993,-0.103125,-0.05273099999999999,-0.074249,-0.121814 +738,738,20210621,0.0,0.253137,1.243174,1.087876,0.301,0.23525,1.068976,1.1266120000000002,0.052913999999999996,-0.165846,-0.174688,2.8835830000000002,-0.0065049999999999995,-0.180878 +739,739,20210621,0.0,0.253137,0.5653,0.640512,0.676021,0.660017,0.758792,0.757966,-0.07955,-0.080127,-0.11823299999999999,-0.101372,-0.10684500000000001,-0.11326300000000002 +740,740,20210621,1.0,0.253137,-0.460291,-0.42040200000000005,-0.34026999999999996,-0.31858200000000003,-0.280748,-0.254458,-0.160815,-0.049095,-0.29680100000000004,-0.255975,-0.25961300000000004,-0.180878 +741,741,20210621,0.0,0.253137,0.7963600000000001,0.427059,0.45317399999999997,0.573248,0.683441,0.761761,-0.077497,-0.12678399999999998,-0.126411,-0.11656400000000001,-0.052323,-0.040248 +742,742,20210621,0.0,-1.486041,-0.681192,-0.6628689999999999,-0.6231899999999999,-0.672497,-0.6630590000000001,-0.652724,-0.220768,-0.092236,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +743,743,20210621,0.0,0.253137,0.075245,0.123235,0.153643,0.182819,0.256128,0.283314,-0.214247,-0.170012,-0.186559,-0.17573699999999998,-0.189186,-0.173453 +744,744,20210621,0.0,0.253137,-0.111026,-0.083207,-0.041791,-0.033435,-0.006405,0.021463999999999997,-0.160815,-0.08338200000000001,-0.29680100000000004,-0.212313,-0.117776,-0.012121999999999999 +745,745,20210621,0.0,-1.486041,-0.295232,-0.289256,-0.43467799999999995,-0.47488100000000005,-0.491666,-0.44228999999999996,0.261814,-0.12678399999999998,0.425255,0.357076,0.5061260000000001,0.390135 +746,746,20210621,0.0,0.253137,-0.40624,-0.368429,-0.328013,-0.275244,-0.170445,-0.074518,-0.221191,-0.17018599999999998,-0.18320799999999998,0.011101999999999999,0.013131,-0.012121999999999999 +747,747,20210621,0.0,0.253137,-0.548687,-0.524107,-0.481009,-0.44012399999999996,-0.390558,-0.370187,-0.268223,-0.17018599999999998,-0.211606,-0.180397,-0.183229,-0.068374 +748,748,20210621,1.0,0.253137,3.118093,3.177121,3.2436130000000003,2.3338389999999998,2.422039,2.555655,0.322189,0.263833,0.11213499999999998,0.106851,0.089908,0.016004 +749,749,20210621,1.0,-0.616452,-0.690345,-0.685504,-0.672305,-0.597495,-0.577494,-0.6396270000000001,-0.318395,-0.240063,-0.022757,0.023996,-0.26308200000000004,-0.29338200000000003 +750,750,20210621,1.0,2.861905,-0.184374,-0.16968699999999998,-0.155377,-0.10708499999999999,-0.083597,-0.075676,-0.341942,-0.25699,-0.24000500000000002,-0.30806300000000003,-0.314136,-0.124626 +751,751,20210621,0.0,0.253137,-0.695642,-0.690983,-0.6526069999999999,-0.630232,-0.596459,-0.56581,-0.341942,-0.180776,-0.24000500000000002,-0.20995100000000003,-0.235592,-0.180878 +752,752,20210621,0.0,-0.616452,0.454768,0.53609,0.589039,-0.378879,-0.675938,0.5826100000000001,-0.10044,-0.115586,-0.24000500000000002,-0.30806300000000003,4.7585,-0.29338200000000003 +753,753,20210621,1.0,0.253137,-0.043286,-0.03361,-0.072131,-0.374868,-0.616263,-0.316201,-0.215153,-0.203735,-0.275048,-0.180397,0.9949309999999999,-0.256875 +754,754,20210621,0.0,0.253137,-0.10697899999999999,-0.07310499999999999,-0.11508800000000001,-0.220279,-0.28926799999999997,-0.458108,-0.100077,-0.153563,-0.232848,-0.25814499999999996,-0.27512600000000004,-0.204954 +755,755,20210621,0.0,-0.616452,-0.683786,-0.668601,-0.656039,-0.668067,-0.651742,-0.617462,-0.281264,-0.213588,-0.280614,-0.264146,-0.17668399999999998,-0.23634299999999997 +756,756,20210621,0.0,0.253137,0.800434,0.889667,0.978018,1.136873,0.08769600000000001,0.205048,-0.003839,-0.009599,-0.012818000000000001,-0.189653,0.10476500000000001,-0.29338200000000003 +757,757,20210621,0.0,0.253137,-0.639785,-0.60626,-0.446849,-0.289856,-0.343005,-0.3161,-0.221191,0.438525,1.101305,-0.24423000000000003,-0.248683,-0.23713 +758,758,20210621,1.0,-0.616452,-0.564779,-0.5483439999999999,-0.651728,-0.685368,-0.561851,-0.440091,-0.268163,-0.17726,-0.29680100000000004,0.193856,0.5154850000000001,-0.126933 +759,759,20210621,0.0,-0.616452,-0.354729,-0.391289,-0.446863,-0.523224,-0.628007,0.43046,-0.250835,-0.21068,-0.122947,-0.166992,3.9091769999999997,-0.162653 +760,760,20210621,0.0,0.253137,-0.270312,-0.252879,-0.223123,-0.190372,-0.16087200000000001,-0.140106,-0.24751399999999998,-0.178866,-0.234325,-0.212313,-0.21595599999999998,-0.124626 +761,761,20210621,1.0,1.992316,-0.107019,-0.08176,-0.340256,-0.331002,-0.314698,-0.338534,-0.263453,-0.19622699999999998,-0.24454800000000002,-0.199547,-0.314136,-0.24275500000000003 +762,762,20210621,0.0,-1.486041,-0.692966,-0.690983,-0.677929,-0.668875,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.283568,-0.30806300000000003,-0.314136,-0.29338200000000003 +763,763,20210621,0.0,0.253137,-0.587445,0.259523,-0.591409,-0.672497,0.790126,0.7907270000000001,3.742462,0.0034219999999999997,-0.29680100000000004,5.331448,0.013131,1.112916 +764,764,20210621,0.0,-1.486041,-0.4315,-0.647104,-0.6473439999999999,-0.624108,-0.6630590000000001,-0.652724,-0.341942,-0.10469200000000001,-0.119993,-0.30806300000000003,-0.314136,-0.29338200000000003 +765,765,20210621,0.0,0.253137,2.575618,2.594523,2.7549919999999997,3.098252,3.255693,3.271672,0.261814,0.220431,0.271165,0.33026700000000003,0.340398,0.156633 +766,766,20210621,0.0,-0.616452,-0.6669189999999999,-0.661253,-0.597754,-0.602003,-0.605686,-0.633985,-0.274502,-0.059077,-0.291633,-0.303658,-0.24109,-0.17440899999999998 +767,767,20210621,0.0,0.253137,0.413415,-0.043684,-0.181607,-0.100012,-0.036703,0.026233,-0.193418,-0.17018599999999998,-0.126411,-0.180397,-0.117776,-0.012121999999999999 +768,768,20210621,0.0,0.253137,-0.540253,-0.638463,-0.569404,-0.51368,-0.470004,-0.516476,-0.11625799999999999,0.06965299999999999,-0.012818000000000001,0.011101999999999999,-0.303533,1.268171 +769,769,20210621,0.0,-1.486041,-0.693496,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.6424479999999999,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.274079,-0.188585 +770,770,20210621,0.0,-1.486041,-0.66499,-0.631115,-0.659687,-0.6340560000000001,-0.6630590000000001,-0.652724,-0.08438,-0.184639,-0.156343,-0.30806300000000003,-0.314136,-0.29338200000000003 +771,771,20210621,0.0,-0.616452,-0.549882,-0.47733400000000004,-0.461629,-0.5210319999999999,-0.48025100000000004,-0.516325,0.576129,0.395427,0.25804499999999997,0.401376,0.217542,0.198035 +772,772,20210621,0.0,-0.616452,-0.69135,-0.6865439999999999,-0.673372,-0.667585,-0.6578609999999999,-0.644899,-0.322863,-0.243275,-0.278854,-0.287891,-0.28363499999999997,-0.275606 +773,773,20210621,0.0,0.253137,-0.545903,-0.557013,-0.526375,-0.509716,-0.49627200000000005,-0.48311099999999996,-0.271061,-0.207121,-0.26834600000000003,-0.28533800000000004,-0.280951,-0.267619 +774,774,20210621,0.0,0.253137,0.850764,0.9404030000000001,0.936792,1.0812549999999999,1.227999,1.327844,-0.009997,-0.018279,-0.069615,-0.033581,0.013916,-0.06820599999999999 +775,775,20210621,0.0,-1.486041,-0.595648,-0.618203,-0.217903,-0.500825,-0.6630590000000001,-0.652724,-0.33958699999999997,1.132434,0.332449,-0.30806300000000003,-0.314136,-0.29338200000000003 +776,776,20210621,0.0,0.253137,-0.29299200000000003,-0.38669499999999996,-0.263556,-0.008237999999999999,0.100214,-0.014756,-0.341942,0.090225,0.555149,0.266434,0.340398,-0.29338200000000003 +777,777,20210621,0.0,-0.616452,-0.522951,-0.46387399999999995,-0.649752,-0.590158,-0.638666,-0.59575,0.638798,-0.171792,-0.106021,0.001463,-0.09094,-0.124964 +778,778,20210621,0.0,-0.616452,-0.676113,-0.673266,-0.671425,-0.685088,-0.669967,-0.630559,-0.265808,-0.23741500000000001,-0.29680100000000004,-0.258273,-0.17472000000000001,-0.29338200000000003 +779,779,20210621,1.0,-0.616452,-0.045703,0.000617,-0.063796,-0.662564,-0.586754,-0.6139020000000001,-0.191003,-0.12678399999999998,0.100775,-0.05273099999999999,-0.156197,-0.180878 +780,780,20210621,0.0,1.992316,-0.695642,-0.690983,-0.675189,-0.672497,-0.06994500000000001,-0.101099,-0.341942,-0.248743,-0.29680100000000004,1.993689,-0.314136,-0.157252 +781,781,20210621,0.0,0.253137,-0.142478,-0.06485700000000001,-0.06069600000000001,0.011768,0.015899,-0.070521,-0.040063999999999995,-0.25699,-0.126411,-0.30806300000000003,-0.117776,-0.124626 +782,782,20210621,0.0,-0.616452,-0.684519,-0.64879,-0.653746,-0.654201,-0.641462,-0.634505,-0.210081,-0.25677300000000003,-0.22978099999999999,-0.22405799999999998,-0.242923,-0.29338200000000003 +783,783,20210621,1.0,1.992316,0.3851,0.45402200000000004,0.515454,0.627156,0.740402,0.809769,-0.11311800000000001,-0.118104,-0.12073199999999999,-0.103797,-0.096045,-0.108876 +784,784,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.642023,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.148919,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +785,785,20210621,1.0,0.253137,0.49624300000000005,0.34208299999999997,0.365732,0.522402,0.5740430000000001,0.634278,-0.18315399999999998,-0.143537,0.043979000000000004,-0.30806300000000003,-0.117776,-0.135877 +786,786,20210621,0.0,-1.486041,-0.26892699999999997,-0.379768,-0.677929,-0.672497,-0.6630590000000001,-0.652724,0.995799,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +787,787,20210621,0.0,-0.616452,-0.683025,-0.686375,-0.677929,-0.648574,-0.633205,-0.652724,-0.32213800000000004,-0.25699,-0.209391,-0.192206,-0.314136,-0.29338200000000003 +788,788,20210621,0.0,0.253137,-0.65968,-0.6883,-0.649853,-0.49103199999999997,-0.397252,-0.106674,-0.329867,-0.17235599999999998,0.367265,0.33026700000000003,0.9949309999999999,0.044129 +789,789,20210621,0.0,0.253137,-0.534115,-0.518347,-0.49901999999999996,-0.449279,-0.42197399999999996,-0.583391,-0.264419,-0.211548,-0.18320799999999998,-0.285147,-0.302682,-0.23713 +790,790,20210621,0.0,-1.486041,0.052158,0.121591,-0.541242,-0.672497,-0.6630590000000001,-0.652724,-0.040063999999999995,-0.212155,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +791,791,20210621,0.0,0.253137,-0.35094000000000003,-0.31893,-0.306456,-0.268902,-0.22705999999999998,-0.195166,-0.23326599999999997,-0.25699,-0.244094,-0.246783,-0.23683600000000002,-0.238986 +792,792,20210621,0.0,-0.616452,-0.696375,-0.687148,-0.677655,-0.676446,-0.6717270000000001,-0.63432,-0.305716,-0.25616500000000003,-0.29680100000000004,-0.30806300000000003,-0.19003699999999998,-0.29338200000000003 +793,793,20210621,0.0,-1.486041,-0.6231899999999999,-0.6155470000000001,-0.6819810000000001,-0.6768649999999999,-0.6676810000000001,-0.657443,-0.015913999999999998,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +794,794,20210621,0.0,-1.486041,-0.699553,-0.69503,-0.682082,-0.676974,-0.6677960000000001,-0.617059,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.156263,-0.29338200000000003 +795,795,20210621,0.0,0.253137,-0.06075,-0.012112000000000001,0.018297,-0.38805,-0.34522600000000003,-0.311365,-0.20187,-0.201348,-0.109429,-0.22361199999999998,-0.227149,-0.230717 +796,796,20210621,0.0,0.253137,0.6225149999999999,0.353689,0.403627,0.519837,0.622681,0.696441,-0.17289000000000002,-0.13980399999999998,0.009901,-0.084647,-0.085049,-0.113376 +797,797,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +798,798,20210621,0.0,-1.486041,-0.508216,-0.556817,-0.6002770000000001,-0.551546,-0.6630590000000001,-0.652724,-0.259106,-0.201652,0.151892,-0.30806300000000003,-0.314136,-0.29338200000000003 +799,799,20210621,0.0,0.253137,-0.487112,-0.43879399999999996,-0.416091,-0.387024,-0.368106,-0.348005,-0.15091300000000002,-0.222268,-0.251364,-0.30806300000000003,-0.270806,-0.124626 +800,800,20210621,0.0,0.253137,-0.191151,-0.188627,-0.184304,-0.169931,-0.16406300000000001,-0.182354,-0.221191,-0.17018599999999998,-0.15799000000000002,-0.22239899999999999,-0.246196,-0.180878 +801,801,20210621,0.0,-0.616452,-0.690413,-0.512614,-0.659327,-0.672497,-0.6630590000000001,-0.601375,0.44487200000000005,-0.20100099999999999,-0.29680100000000004,-0.30806300000000003,-0.11398,-0.081425 +802,802,20210621,1.0,0.253137,-0.415746,-0.40990600000000005,-0.39917600000000003,-0.371977,-0.377465,-0.378784,-0.341942,-0.25699,-0.268403,-0.262422,-0.292798,-0.29338200000000003 +803,803,20210621,0.0,0.253137,-0.668481,-0.680024,-0.677929,-0.556349,-0.495712,-0.46626899999999993,-0.29484899999999997,-0.25699,0.127583,-0.11656400000000001,-0.24187600000000004,-0.23713 +804,804,20210621,0.0,-1.486041,-0.605114,-0.597324,-0.677929,-0.672497,-0.6630590000000001,-0.652724,0.060522,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +805,805,20210621,0.0,-1.486041,-0.274142,-0.6032529999999999,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.157796,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +806,806,20210621,0.0,-0.616452,-0.35288200000000003,-0.339711,-0.37799299999999997,-0.672497,-0.6630590000000001,0.451416,-0.23851799999999998,-0.213588,-0.29680100000000004,-0.30806300000000003,3.989751,-0.124626 +807,807,20210621,0.0,-0.616452,-0.682088,-0.594626,-0.650834,-0.654699,-0.542525,-0.590544,0.072295,-0.25651199999999996,-0.231712,0.159769,-0.071697,-0.269419 +808,808,20210621,1.0,1.992316,-0.468113,-0.42581099999999994,-0.391519,-0.373345,-0.32534,-0.317679,-0.19704000000000002,-0.187547,-0.29680100000000004,-0.20593000000000003,-0.300456,-0.29338200000000003 +809,809,20210621,0.0,1.992316,-0.273816,-0.23956,-0.200022,-0.14824600000000002,-0.074896,-0.062141999999999996,-0.23628400000000002,-0.182338,-0.222966,-0.142097,-0.314136,-0.214629 +810,810,20210621,0.0,0.253137,-0.6590560000000001,-0.15098599999999998,-0.117424,-0.228331,-0.21454299999999998,-0.182203,1.824815,-0.199482,-0.24619499999999997,-0.24423000000000003,-0.24226799999999998,-0.269419 +811,811,20210621,0.0,0.253137,0.256302,0.38311,0.385285,-0.48085,-0.460266,-0.652724,0.1471,-0.25699,-0.28277199999999997,-0.30806300000000003,-0.314136,-0.29338200000000003 +812,812,20210621,0.0,-0.616452,0.652352,0.747,0.90302,-0.66743,-0.629899,0.383443,-0.040063999999999995,0.177029,-0.27828600000000003,-0.179375,3.724795,0.707058 +813,813,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.677929,-0.672497,-0.645196,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.23874,-0.314136,-0.29338200000000003 +814,814,20210621,0.0,-0.616452,-0.35720100000000005,-0.39124699999999996,-0.44415200000000005,-0.496783,-0.475612,-0.549657,-0.221191,-0.12678399999999998,-0.29680100000000004,0.011101999999999999,0.091806,-0.29338200000000003 +815,815,20210621,1.0,1.992316,0.201422,0.256081,0.30846999999999997,0.40608299999999997,0.5002880000000001,0.559891,-0.160815,-0.13980399999999998,-0.14345,-0.142097,-0.130867,-0.29338200000000003 +816,816,20210621,0.0,0.253137,2.207041,2.5260279999999997,2.549407,1.7919459999999998,2.005598,1.163184,0.8836809999999999,-0.25699,0.02126,0.094085,-0.052323,-0.068374 +817,817,20210621,1.0,0.253137,0.050855000000000004,0.03098,0.039235,0.11033499999999999,0.145957,0.140601,-0.341942,-0.165846,-0.186048,-0.18678,-0.16889500000000002,-0.175253 +818,818,20210621,0.0,1.992316,-0.639948,-0.68386,-0.634063,-0.672497,-0.524859,-0.5485479999999999,-0.31133099999999997,-0.12496099999999999,-0.29680100000000004,0.228262,-0.314136,-0.026804 +819,819,20210621,0.0,-0.616452,-0.6602640000000001,-0.654382,-0.611741,-0.632004,-0.62021,-0.589,-0.18466300000000002,-0.057775,-0.148846,-0.141778,-0.065741,0.307107 +820,820,20210621,0.0,0.253137,-0.48677299999999996,-0.633152,-0.397417,-0.39406599999999997,-0.359092,-0.33623400000000003,-0.09156399999999999,0.586526,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.23713 +821,821,20210621,0.0,-0.616452,-0.685049,-0.690983,-0.672305,-0.660373,-0.656644,-0.646175,-0.341942,-0.240063,-0.2525,-0.30806300000000003,-0.288609,-0.271444 +822,822,20210621,1.0,0.253137,-0.032082,-0.015413999999999999,0.023084,-0.257974,-0.234808,-0.20186600000000002,-0.221191,-0.160073,-0.23529,-0.237846,-0.22250100000000003,-0.124626 +823,823,20210621,0.0,0.253137,0.055852,0.12752,-0.15506,-0.127868,-0.093434,0.40777399999999997,-0.034932,-0.08338200000000001,-0.29680100000000004,-0.180397,1.6494650000000002,-0.012121999999999999 +824,824,20210621,0.0,0.253137,-0.42073,-0.404356,-0.395542,-0.361873,-0.330866,-0.321843,-0.256812,-0.204907,-0.266472,-0.26338,-0.248683,-0.29338200000000003 +825,825,20210621,1.0,0.253137,-0.5454680000000001,-0.529812,-0.508119,-0.47570500000000004,-0.454822,-0.444288,-0.221191,-0.191887,-0.164465,-0.161247,-0.248683,-0.176491 +826,826,20210621,0.0,-1.486041,-0.695642,-0.592041,-0.634871,-0.672497,-0.6630590000000001,-0.652724,0.083223,-0.127392,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +827,827,20210621,0.0,1.992316,-0.327785,-0.320447,-0.28870500000000004,-0.24202600000000002,-0.18215599999999998,-0.17236300000000002,-0.341942,-0.19622699999999998,-0.234325,-0.174013,-0.314136,-0.23713 +828,828,20210621,0.0,1.992316,-0.5767439999999999,-0.576361,-0.5692020000000001,-0.545593,-0.548528,-0.553267,-0.271483,-0.212633,-0.23795999999999998,-0.30806300000000003,-0.13741199999999998,-0.29338200000000003 +829,829,20210621,0.0,-0.616452,-0.654425,2.113495,-0.667546,-0.672497,-0.6630590000000001,-0.627537,11.711789,-0.22574,-0.29680100000000004,-0.30806300000000003,-0.21595599999999998,10.1499 +830,830,20210621,0.0,0.253137,-0.41121,-0.625003,0.003055,-0.416279,-0.5093810000000001,-0.489962,-0.199455,1.883807,-0.126354,-0.18792899999999998,-0.281409,-0.26508699999999996 +831,831,20210621,0.0,0.253137,-0.6683859999999999,-0.64213,-0.634135,-0.647113,-0.603301,-0.652724,-0.221191,-0.213588,-0.204052,-0.180397,-0.314136,-0.124626 +832,832,20210621,0.0,2.861905,-0.365498,-0.353958,-0.341179,-0.319344,-0.30454899999999996,-0.29737800000000003,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +833,833,20210621,1.0,0.253137,1.3750959999999999,0.181319,0.108696,-0.449233,0.939675,0.8705709999999999,-0.160755,-0.083165,-0.182015,5.911881,0.013196000000000001,-0.012066 +834,834,20210621,0.0,0.253137,-0.6881729999999999,-0.690983,-0.490281,-0.45075600000000005,-0.43838999999999995,-0.652724,-0.341942,0.307799,-0.225692,-0.07449800000000001,-0.314136,-0.29338200000000003 +835,835,20210621,0.0,-1.486041,-0.46143100000000004,-0.45229600000000003,-0.44759799999999994,-0.380682,-0.6630590000000001,-0.652724,-0.221191,-0.17018599999999998,-0.126411,-0.30806300000000003,-0.314136,-0.29338200000000003 +836,836,20210621,1.0,-0.616452,-0.67394,-0.65604,-0.677929,-0.597729,-0.617069,-0.5982350000000001,-0.19178800000000001,-0.25699,-0.023609,-0.12958599999999998,-0.10174,0.11753800000000002 +837,837,20210621,0.0,1.992316,-0.38471500000000003,-0.356065,-0.328201,-0.290695,-0.24977600000000003,-0.224938,-0.24534099999999998,-0.209247,-0.24000500000000002,-0.237846,-0.254835,-0.29338200000000003 +838,838,20210621,0.0,0.253137,-0.490996,-0.46445,-0.43495200000000006,-0.399413,-0.364799,-0.336569,-0.24534099999999998,-0.200567,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.23713 +839,839,20210621,0.0,0.253137,0.512322,0.429996,0.483961,0.772854,0.9571430000000001,1.080183,1.469324,0.201985,0.555149,0.33026700000000003,0.340398,0.831656 +840,840,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +841,841,20210621,0.0,0.253137,0.381542,0.42544399999999993,0.472613,-0.220637,-0.22633699999999998,-0.197517,-0.221191,-0.161462,-0.18320799999999998,-0.24423000000000003,-0.248683,-0.180878 +842,842,20210621,0.0,0.253137,0.223056,0.272267,0.233111,0.228877,0.2243,0.018357,-0.15846,-0.168146,-0.197407,-0.199355,-0.201491,-0.249281 +843,843,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.540304,-0.538473,-0.341942,-0.25699,-0.29680100000000004,0.168322,0.131209,-0.012966 +844,844,20210621,1.0,-0.616452,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.650205,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.2945,-0.287644 +845,845,20210621,0.0,0.253137,3.5849660000000005,3.974732,4.730573000000001,4.843268,5.415156,5.516541999999999,1.167446,1.9131040000000001,0.839132,0.942169,0.610196,0.38287899999999997 +846,846,20210621,0.0,0.253137,-0.6373810000000001,-0.624413,-0.637509,-0.578811,-0.486699,-0.5108,-0.05588200000000001,-0.13533399999999998,0.045512000000000004,0.376354,0.078584,-0.22931100000000001 +847,847,20210621,0.0,-1.486041,2.089243,-0.692192,-0.6791689999999999,-0.641191,-0.666101,-0.622247,-0.341942,-0.25699,-0.177528,-0.30806300000000003,-0.183229,-0.012121999999999999 +848,848,20210621,1.0,0.253137,-0.048569,0.014794,0.050424000000000004,-0.172325,-0.177337,-0.152515,-0.118552,-0.096403,-0.29680100000000004,-0.239634,-0.21595599999999998,-0.22970500000000002 +849,849,20210621,1.0,0.253137,1.3566129999999998,1.469778,1.489682,1.627905,1.6949040000000002,1.750693,0.050499,-0.25699,-0.267721,-0.30806300000000003,-0.026927,-0.05594299999999999 +850,850,20210621,0.0,0.253137,-0.685782,-0.680783,-0.45586099999999996,-0.439331,-0.416332,-0.400848,-0.341942,0.41139899999999996,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.28775700000000004 +851,851,20210621,0.0,5.470672,-0.423555,-0.39022199999999996,-0.321251,-0.298654,0.049437,0.087103,-0.221191,-0.08338200000000001,-0.29680100000000004,0.9685959999999999,-0.183229,-0.29338200000000003 +852,852,20210621,0.0,0.253137,-0.30051500000000003,-0.257966,-0.25666300000000003,-0.214279,-0.278429,-0.276119,-0.191003,-0.25699,-0.24511599999999997,-0.24423000000000003,-0.248683,-0.23713 +853,853,20210621,0.0,-1.486041,-0.28279299999999996,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.311754,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +854,854,20210621,0.0,0.253137,-0.088142,-0.070745,-0.032793,0.0029850000000000002,0.060342999999999994,0.09642200000000001,-0.215153,-0.169014,-0.19456700000000002,-0.20593000000000003,-0.199593,-0.19775399999999999 +855,855,20210621,0.0,0.253137,-0.627916,-0.59627,-0.542871,-0.5393439999999999,-0.497489,-0.652724,-0.221191,-0.12678399999999998,-0.211606,-0.212313,-0.314136,-0.29338200000000003 +856,856,20210621,0.0,-1.486041,-0.32955100000000004,-0.321895,-0.43227,-0.24507199999999998,-0.39827199999999996,-0.530145,-0.261461,-0.159075,1.264937,-0.257826,-0.301045,-0.29338200000000003 +857,857,20210621,1.0,1.992316,-0.33628600000000003,-0.277552,-0.243238,-0.216098,-0.105573,-0.073628,-0.136665,-0.191887,-0.29680100000000004,0.011101999999999999,-0.22904699999999997,-0.29338200000000003 +858,858,20210621,1.0,1.992316,-0.010027,0.033762,0.073943,0.146554,0.228429,0.240193,-0.209115,-0.17018599999999998,-0.18320799999999998,-0.14848,-0.314136,-0.040248 +859,859,20210621,0.0,0.253137,1.083969,1.1875209999999998,1.225364,1.309602,1.4535719999999999,1.524643,0.080687,-0.033427,-0.043261,0.011101999999999999,-0.006374,0.156633 +860,860,20210621,0.0,0.253137,-0.42107,-0.42130100000000004,-0.387914,-0.366086,-0.338827,-0.5465840000000001,-0.252465,-0.19622699999999998,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +861,861,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +862,862,20210621,0.0,0.253137,-0.6808930000000001,-0.650898,-0.117914,0.028354,0.11332300000000001,0.123037,-0.12748800000000002,1.4285649999999999,0.839132,0.6494310000000001,0.667665,0.269137 +863,863,20210621,1.0,6.340261,-0.662369,-0.65656,-0.6426,-0.634413,-0.6227600000000001,-0.611584,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +864,864,20210621,0.0,0.253137,-0.47950699999999996,-0.563828,-0.5351560000000001,-0.517442,-0.5029170000000001,-0.506586,-0.201267,-0.16150499999999998,-0.24000500000000002,-0.286806,-0.29378000000000004,-0.275269 +865,865,20210621,0.0,0.253137,-0.104683,-0.064942,-0.020753,0.089521,0.117567,0.181254,-0.23694899999999997,-0.180776,-0.145609,-0.19788699999999998,-0.117776,-0.152752 +866,866,20210621,0.0,0.253137,-0.312208,-0.28529299999999996,-0.253448,-0.241326,-0.21454299999999998,-0.19247999999999998,-0.252344,-0.194664,-0.23318899999999998,-0.244549,-0.249403,-0.248381 +867,867,20210621,0.0,-1.486041,0.924968,1.039318,-0.677929,-0.672497,-0.6630590000000001,-0.652724,0.020312,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +868,868,20210621,0.0,-1.486041,-0.300325,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,2.405023 +869,869,20210621,0.0,0.253137,0.732925,0.578283,0.396504,0.475862,0.5899810000000001,0.663748,-0.160815,0.0034219999999999997,-0.069615,-0.05273099999999999,-0.052323,-0.124626 +870,870,20210621,0.0,0.253137,3.519807,3.735553,3.8511699999999998,4.264891,4.5316790000000005,4.477117,0.383289,0.264354,0.328871,0.399717,0.473333,0.383385 +871,871,20210621,0.0,0.253137,-0.497488,-0.47157299999999996,-0.43815299999999996,-0.408895,-0.378271,-0.356115,-0.265567,-0.20156500000000002,-0.262326,-0.267912,-0.272377,-0.257325 +872,872,20210621,0.0,0.253137,-0.21135900000000002,-0.169968,-0.123279,-0.067478,0.007889,0.071134,-0.221191,-0.17018599999999998,-0.21745599999999998,-0.14848,-0.117776,-0.203379 +873,873,20210621,0.0,-1.486041,-0.510199,-0.573649,-0.6441859999999999,-0.636123,-0.474971,-0.649551,0.162254,-0.15542899999999998,-0.16389700000000001,0.421867,-0.301765,0.009872 +874,874,20210621,0.0,-0.616452,-0.6351680000000001,-0.6444770000000001,-0.5737300000000001,-0.593843,-0.616477,-0.620988,-0.142099,0.056719000000000006,-0.00941,-0.127288,-0.190429,-0.148477 +875,875,20210621,0.0,-0.616452,-0.655633,-0.690983,-0.672305,-0.666435,-0.656644,-0.646175,-0.341942,-0.240063,-0.27465100000000003,-0.283168,-0.288609,-0.249506 +876,876,20210621,0.0,1.992316,-0.279995,-0.275388,-0.241133,-0.196589,-0.162106,-0.152028,-0.23326599999999997,-0.191366,-0.225294,-0.14848,-0.314136,-0.23713 +877,877,20210621,0.0,0.253137,-0.079967,0.015215000000000001,0.11218499999999999,0.248416,0.391219,0.5031680000000001,0.020312,0.0034219999999999997,0.043979000000000004,0.074935,0.07865,0.044129 +878,878,20210621,0.0,-0.616452,-0.6151909999999999,-0.618287,-0.663797,-0.624962,-0.611114,-0.492699,-0.029559,-0.210202,-0.123117,-0.106478,0.309635,-0.29338200000000003 +879,879,20210621,0.0,0.253137,-0.375317,-0.34562600000000004,-0.38715,-0.505675,-0.48926499999999995,-0.472096,-0.23326599999999997,-0.179951,0.312741,-0.283551,-0.264588,-0.2652 +880,880,20210621,0.0,1.992316,-0.48794099999999996,-0.461401,-0.427612,-0.39618000000000003,-0.345719,-0.336301,-0.263453,-0.200567,-0.257044,-0.193163,-0.314136,-0.23713 +881,881,20210621,0.0,0.253137,-0.628622,-0.6937939999999999,-0.512632,-0.489835,-0.46942799999999996,-0.563426,-0.341942,0.24920599999999998,0.234986,-0.101755,-0.117776,-0.23713 +882,882,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +883,883,20210621,0.0,0.253137,2.346677,2.502817,1.982557,1.320141,1.489759,1.5890389999999999,0.186344,0.067222,-0.038944,-0.007409999999999999,-0.0032329999999999998,-0.017748 +884,884,20210621,0.0,0.253137,-0.044902,-0.010173999999999999,0.015961000000000003,-0.23025900000000002,-0.185298,-0.1549,-0.221915,-0.170663,-0.23898200000000003,-0.240783,-0.24318499999999998,-0.23443000000000003 +885,885,20210621,1.0,0.253137,0.006976,-0.309924,-0.27268400000000004,-0.2246,-0.18176199999999998,-0.15102100000000002,-0.16504100000000002,-0.194187,-0.231031,-0.241612,-0.24331599999999998,-0.23746799999999998 +886,886,20210621,0.0,0.253137,-0.021978,0.036881,0.086921,0.184777,0.276113,0.340356,-0.160815,-0.13980399999999998,-0.126411,-0.11656400000000001,-0.117776,-0.028998000000000003 +887,887,20210621,0.0,-1.486041,-0.674673,-0.667828,-0.659413,-0.6555850000000001,-0.6483869999999999,-0.657829,-0.263453,-0.213588,-0.24000500000000002,-0.24423000000000003,-0.294238,1.9310439999999998 +888,888,20210621,0.0,-0.616452,-0.661853,-0.501641,-0.632174,-0.46728000000000003,-0.5545979999999999,-0.6099220000000001,0.471679,-0.119275,0.453596,0.112852,-0.147295,-0.23713 +889,889,20210621,0.0,1.992316,-0.364262,-0.37104299999999996,-0.397301,-0.42097299999999993,-0.42177700000000007,-0.410554,-0.254156,-0.196921,-0.273685,-0.26510300000000003,-0.314136,-0.287644 +890,890,20210621,0.0,0.253137,1.333906,1.273172,1.2431590000000001,0.9771850000000001,0.177406,-0.005319,0.14384,-0.03347,0.004051,0.016464,0.017385,-0.00976 +891,891,20210621,0.0,-0.616452,-0.685158,-0.686248,-0.669017,-0.670166,-0.660591,-0.6463939999999999,-0.321414,-0.230167,-0.28828200000000004,-0.29848800000000003,-0.29927800000000004,-0.29338200000000003 +892,892,20210621,0.0,0.253137,-0.5107970000000001,-0.47930100000000003,-0.44891099999999995,-0.476653,-0.357135,-0.446455,-0.159668,-0.039373000000000005,-0.296631,0.141321,-0.182837,-0.180597 +893,893,20210621,0.0,-1.486041,-0.309845,-0.32996,-0.511335,-0.635968,-0.6630590000000001,-0.652724,-0.26592899999999997,-0.212069,-0.205927,-0.30806300000000003,-0.314136,-0.29338200000000003 +894,894,20210621,0.0,0.253137,1.172691,2.112947,1.08265,0.9662729999999999,0.9851709999999999,0.960508,0.023209999999999998,0.019524,-0.12396900000000001,-0.11458499999999999,-0.113456,-0.12288199999999999 +895,895,20210621,1.0,-1.486041,-0.6924100000000001,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +896,896,20210621,0.0,-1.486041,-0.694284,-0.689578,-0.676487,-0.6709430000000001,-0.6614140000000001,-0.651045,-0.335904,-0.25264899999999996,-0.291122,-0.301679,-0.307591,-0.28775700000000004 +897,897,20210621,1.0,1.992316,0.5620539999999999,0.640358,0.653771,0.8996649999999999,0.9696110000000001,1.05293,-0.070252,-0.25699,0.345001,-0.30806300000000003,-0.045777,-0.29338200000000003 +898,898,20210621,1.0,1.992316,1.095146,1.190317,1.193222,1.4820209999999998,1.5785799999999999,1.7822790000000002,-0.003839,-0.25699,0.327962,-0.30806300000000003,0.405851,0.024779 +899,899,20210621,1.0,0.253137,-0.541978,-0.517602,-0.485436,-0.450585,-0.43436,-0.41455,-0.268766,-0.203996,-0.23159899999999997,-0.30806300000000003,-0.28075500000000003,-0.26385 +900,900,20210621,0.0,-0.616452,-0.64299,-0.529461,-0.592346,-0.667912,-0.6323489999999999,-0.652724,0.352135,-0.21311,-0.279933,-0.12147899999999999,-0.314136,-0.29338200000000003 +901,901,20210621,0.0,-1.486041,-0.695642,-0.6558579999999999,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.191003,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +902,902,20210621,0.0,0.253137,-0.640831,-0.690983,-0.677929,-0.626315,-0.636626,-0.652724,-0.341942,-0.25699,-0.128058,-0.30806300000000003,-0.314136,-0.29338200000000003 +903,903,20210621,0.0,0.253137,1.589777,1.499368,1.04634,0.125196,0.19104200000000002,-0.071596,0.261814,-0.08772200000000001,-0.24000500000000002,-0.24423000000000003,-0.183229,-0.180878 +904,904,20210621,0.0,-1.486041,1.408938,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +905,905,20210621,0.0,1.992316,0.08339400000000001,0.13288699999999998,0.18529400000000001,0.304625,0.389245,0.410075,-0.209115,-0.16150499999999998,-0.069615,-0.194631,-0.314136,-0.180878 +906,906,20210621,0.0,1.992316,-0.31848200000000004,-0.262996,-0.255063,-0.33908499999999997,-0.17439300000000002,-0.16432,-0.152604,-0.25699,-0.29680100000000004,1.58835,-0.314136,-0.204729 +907,907,20210621,1.0,1.992316,-0.63878,-0.618596,-0.6248779999999999,-0.663233,-0.655723,-0.607403,-0.203078,-0.25699,-0.257044,-0.30806300000000003,-0.16359300000000002,-0.29338200000000003 +908,908,20210621,0.0,0.253137,-0.391016,-0.5167729999999999,-0.617379,-0.624947,-0.651972,-0.652724,-0.25137800000000005,-0.213588,-0.25806599999999996,-0.30806300000000003,-0.314136,-0.251868 +909,909,20210621,0.0,0.253137,-0.600442,-0.552222,-0.517651,-0.47174099999999997,-0.42595500000000003,-0.652724,-0.160815,-0.191887,-0.18320799999999998,-0.180397,-0.314136,-0.29338200000000003 +910,910,20210621,0.0,-0.616452,0.38859,-0.305217,0.304317,-0.06463300000000001,0.232656,0.12226500000000001,1.3162719999999999,1.919787,1.924232,3.168023,2.7067330000000003,1.956695 +911,911,20210621,0.0,0.253137,0.47247700000000004,0.614266,0.661111,0.703696,0.832793,0.8386,0.159175,-0.152825,-0.24000500000000002,-0.05273099999999999,-0.07850399999999999,-0.068374 +912,912,20210621,0.0,0.253137,4.551957,4.75929,3.5496769999999995,3.595051,3.5056760000000002,3.6068510000000003,1.168412,0.611829,0.271165,4.7588029999999995,3.140362,0.269137 +913,913,20210621,0.0,0.253137,0.22885500000000003,0.292148,0.357498,0.47177399999999997,0.577579,0.643077,-0.160815,-0.12678399999999998,-0.126411,-0.11656400000000001,-0.117776,-0.012121999999999999 +914,914,20210621,0.0,0.253137,-0.462233,-0.353143,-0.343674,-0.33052,-0.301193,-0.652724,0.135025,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +915,915,20210621,0.0,0.253137,-0.425633,-0.401392,-0.362722,-0.32360300000000003,-0.285814,-0.259731,-0.260314,-0.187547,-0.24290100000000003,-0.24423000000000003,-0.248683,-0.23713 +916,916,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.585843,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.053435,-0.29338200000000003 +917,917,20210621,0.0,0.253137,0.050868000000000003,-0.016876,0.023329,0.079091,0.125462,-0.08471000000000001,-0.21593800000000002,-0.170663,-0.206438,-0.214484,-0.183229,-0.209004 +918,918,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +919,919,20210621,0.0,0.253137,5.711859,6.030425,5.026788,5.3322330000000004,5.195965,5.262281,0.6267229999999999,0.397814,0.384759,0.6494310000000001,0.471304,0.381641 +920,920,20210621,0.0,0.253137,-0.395389,-0.33957,-0.25643299999999997,-0.163464,-0.03445,0.081813,0.020312,-0.03998,-0.069615,0.074935,0.20949099999999998,-0.068374 +921,921,20210621,0.0,-0.616452,-0.695642,-0.690983,-0.677929,-0.672497,-0.630491,-0.610745,-0.341942,-0.25699,-0.29680100000000004,-0.181673,-0.150503,-0.29338200000000003 +922,922,20210621,0.0,0.253137,-0.325639,-0.293358,-0.21793099999999999,-0.189221,-0.13939000000000001,-0.10606900000000001,-0.23326599999999997,-0.06602100000000001,-0.29680100000000004,-0.218696,-0.22250100000000003,-0.214629 +923,923,20210621,0.0,0.253137,-0.580465,-0.507402,-0.42358900000000005,-0.327349,-0.222504,-0.12627,-0.041272,-0.034598000000000004,0.0017219999999999998,0.037656999999999996,0.049261,0.029616000000000003 +924,924,20210621,0.0,-0.616452,-0.6770229999999999,-0.6797989999999999,-0.67219,-0.6601239999999999,-0.656512,-0.6407010000000001,-0.293883,-0.25699,-0.251591,-0.30806300000000003,-0.26727199999999995,0.387885 +925,925,20210621,0.0,0.253137,-0.32365700000000003,-0.291785,-0.265878,-0.222875,-0.265681,-0.652724,-0.235258,-0.183206,-0.23943699999999998,-0.235229,-0.314136,-0.29338200000000003 +926,926,20210621,1.0,-1.486041,-0.540932,-0.484612,-0.475472,-0.46358,-0.441992,-0.43308800000000003,-0.130627,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +927,927,20210621,0.0,0.253137,-0.6154890000000001,-0.595905,-0.5604779999999999,-0.545764,-0.526142,-0.510162,-0.2742,-0.191887,-0.280273,-0.288785,-0.294238,-0.275438 +928,928,20210621,0.0,0.253137,-0.011969,0.018307,0.031779,-0.03701,-0.329847,-0.311802,-0.22746999999999998,-0.185116,-0.197407,-0.262294,-0.26485,-0.23713 +929,929,20210621,0.0,-1.486041,-0.5498270000000001,-0.393158,-0.505812,-0.044192,-0.5115689999999999,-0.35391500000000004,0.937838,0.26105500000000004,1.99892,0.279839,0.850607,0.0956 +930,930,20210621,0.0,-1.486041,-0.678775,-0.634698,-0.664359,-0.6358590000000001,-0.614618,-0.6335310000000001,-0.098387,-0.215975,-0.16242,-0.119947,-0.239323,-0.251531 +931,931,20210621,0.0,0.253137,0.233418,0.157461,0.023791,0.12023699999999998,0.222442,0.29983699999999996,-0.191003,-0.08338200000000001,-0.069615,-0.063263,-0.065086,-0.124626 +932,932,20210621,1.0,-0.616452,-0.560447,-0.642299,0.53942,-0.658725,-0.469938,-0.580234,-0.13274,3.407864,-0.246479,0.428122,-0.031574,2.657931 +933,933,20210621,1.0,-0.616452,-0.6686300000000001,-0.691096,-0.665441,-0.672497,-0.6483869999999999,-0.652724,-0.341942,-0.219056,-0.29680100000000004,-0.25112399999999996,-0.314136,-0.259968 +934,934,20210621,1.0,1.992316,-0.589021,-0.563617,-0.510729,-0.49976800000000005,-0.450496,-0.441719,-0.25137800000000005,-0.12678399999999998,-0.29680100000000004,-0.180397,-0.314136,-0.23713 +935,935,20210621,0.0,0.253137,-0.466049,-0.443065,-0.411476,-0.512716,-0.48794899999999997,-0.47177700000000006,-0.262608,-0.207208,-0.277036,-0.27538,-0.285664,-0.282694 +936,936,20210621,0.0,-1.486041,-0.40960799999999997,-0.599726,-0.646104,-0.672497,-0.6630590000000001,-0.652724,-0.221191,-0.213588,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +937,937,20210621,0.0,0.253137,-0.049411000000000004,0.040815,0.098111,0.179617,0.257806,0.31108800000000003,0.261814,-0.144145,-0.15481,-0.16763,-0.150503,-0.124626 +938,938,20210621,0.0,-0.616452,-0.5343859999999999,-0.6069760000000001,-0.577883,-0.021838999999999997,-0.49173199999999995,-0.6239939999999999,-0.341942,0.044133,2.081673,-0.30806300000000003,-0.202145,1.234533 +939,939,20210621,1.0,0.253137,-0.484491,-0.48010200000000003,-0.42194499999999996,-0.405569,-0.35494699999999996,-0.259982,-0.341942,-0.12678399999999998,-0.29680100000000004,-0.180397,0.013131,-0.180878 +940,940,20210621,0.0,-0.616452,-0.6257020000000001,-0.54781,-0.530989,-0.5141,-0.488804,-0.46477399999999996,0.273285,0.185275,0.281957,0.368183,0.418484,0.279825 +941,941,20210621,0.0,1.992316,-0.11788399999999999,-0.204434,-0.287219,-0.384335,-0.332445,-0.32310300000000003,-0.227228,-0.195012,-0.262723,-0.11656400000000001,-0.314136,-0.23713 +942,942,20210621,0.0,-0.616452,-0.678517,-0.673266,-0.659745,-0.652896,-0.642317,-0.63155,-0.265808,-0.20226,-0.225181,-0.227569,-0.23159899999999997,-0.222448 +943,943,20210621,0.0,-0.616452,-0.630659,-0.64317,-0.677929,-0.5810649999999999,-0.5663090000000001,-0.635714,-0.12923900000000002,-0.25699,0.037277,-0.30806300000000003,-0.24783200000000002,-0.29338200000000003 +944,944,20210621,1.0,2.861905,-0.679345,-0.6741229999999999,-0.660625,-0.653844,-0.653189,-0.647687,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +945,945,20210621,0.0,-1.486041,-0.644321,-0.6355689999999999,-0.6473869999999999,-0.637382,-0.6050449999999999,-0.634253,-0.103156,-0.164804,-0.1681,-0.075838,-0.22885,-0.29338200000000003 +946,946,20210621,0.0,-0.616452,-0.480336,-0.576136,-0.663451,-0.656891,-0.652433,-0.593819,-0.281566,-0.213414,-0.239777,-0.266826,-0.084526,-0.29338200000000003 +947,947,20210621,0.0,0.253137,2.279847,2.3587580000000004,2.030734,2.22094,2.4897400000000003,2.5681990000000003,0.148972,0.095564,0.083736,0.33026700000000003,0.189855,0.044129 +948,948,20210621,0.0,0.253137,-0.056417999999999996,-0.009836,0.036149,-0.377309,-0.341673,-0.320399,-0.21098699999999998,-0.161071,-0.25818,-0.253485,-0.266617,-0.254737 +949,949,20210621,0.0,0.253137,1.8881700000000001,1.8550389999999999,1.0570540000000002,1.3371,1.2028,2.10745,2.073804,0.177897,1.978984,1.28808,6.231201,2.592623 +950,950,20210621,0.0,-0.616452,-0.668481,-0.676933,-0.6472859999999999,-0.639465,-0.64661,-0.617042,-0.341942,-0.164761,-0.176108,-0.24423000000000003,-0.175048,1.014475 +951,951,20210621,1.0,-1.486041,-0.520493,-0.501528,-0.581964,-0.569624,-0.6630590000000001,-0.652724,-0.22052600000000003,-0.161028,-0.177471,-0.298615,-0.314136,-0.29338200000000003 +952,952,20210621,0.0,0.253137,0.405389,0.408625,0.42033999999999994,0.521516,0.611874,0.674981,-0.118552,-0.109423,-0.13209100000000001,-0.122947,-0.128183,-0.119001 +953,953,20210621,0.0,0.253137,-0.547763,-0.323623,0.825772,0.943267,1.013775,0.861773,1.468539,4.2689129999999995,-0.17837999999999998,-0.235931,2.6673310000000003,-0.29338200000000003 +954,954,20210621,0.0,0.253137,-0.653067,-0.6513329999999999,-0.649983,-0.58206,-0.6198319999999999,-0.608596,-0.170898,-0.169535,0.033642,-0.14031,-0.314136,-0.29338200000000003 +955,955,20210621,0.0,0.253137,-0.662913,-0.6607609999999999,-0.646767,-0.645776,1.106643,1.159775,-0.21207399999999998,-0.163198,-0.199168,6.559785000000001,0.013131,-0.0965 +956,956,20210621,0.0,1.992316,0.8949959999999999,-0.5333100000000001,-0.45423199999999997,-0.391345,-0.375228,-0.317914,0.582709,0.394038,-0.126411,-0.30806300000000003,-0.117776,-0.29338200000000003 +957,957,20210621,0.0,0.253137,-0.399857,-0.396291,-0.408967,-0.463207,1.141694,1.1200290000000002,-0.261944,-0.21037600000000004,-0.24000500000000002,6.0113959999999995,-0.069013,-0.068374 +958,958,20210621,1.0,-0.616452,-0.6113609999999999,-0.5965229999999999,-0.56913,-0.66687,-0.660081,-0.64453,-0.274321,-0.212546,-0.27624099999999996,-0.30806300000000003,-0.282195,-0.276506 +959,959,20210621,0.0,0.253137,-0.635358,-0.217205,-0.47196800000000005,-0.41716499999999995,-0.48487299999999994,-0.614758,1.704245,0.449029,-0.06808099999999999,-0.293126,-0.211702,1.188631 +960,960,20210621,1.0,-0.616452,-0.677471,-0.691321,-0.557897,-0.58122,-0.284416,-0.612978,-0.341942,0.10532899999999999,-0.29680100000000004,1.161371,-0.159208,-0.11804500000000001 +961,961,20210621,1.0,-1.486041,-0.584268,-0.5802390000000001,-0.677958,-0.672528,-0.663091,-0.652758,-0.33958699999999997,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +962,962,20210621,0.0,-0.616452,-0.690264,-0.685419,-0.672218,-0.6601859999999999,-0.6565449999999999,-0.6397609999999999,-0.318033,-0.239802,-0.251818,-0.30806300000000003,-0.263606,-0.29338200000000003 +963,963,20210621,0.0,0.253137,-0.236877,-0.186871,-0.30238899999999996,-0.24507199999999998,-0.18470599999999998,-0.12131600000000001,-0.160815,-0.17018599999999998,-0.18320799999999998,-0.180397,-0.117776,-0.068374 +964,964,20210621,0.0,0.253137,-0.317749,-0.288132,-0.25078,-0.201952,-0.25948000000000004,-0.267975,-0.24534099999999998,-0.191887,-0.24000500000000002,-0.24423000000000003,-0.248683,-0.23713 +965,965,20210621,0.0,0.253137,-0.49278900000000003,-0.519977,-0.622455,-0.49968999999999997,-0.556489,-0.548834,-0.159185,-0.089545,0.335857,-0.11598900000000001,-0.116729,-0.124176 +966,966,20210621,0.0,0.253137,3.308276,3.424646,3.5292440000000003,3.804668,3.8542019999999995,3.82511,0.865991,0.612176,0.840268,0.331352,0.669235,0.26925 +967,967,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.659039,-0.659813,-0.6630590000000001,-0.652724,-0.341942,-0.200133,-0.25045500000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +968,968,20210621,0.0,-0.616452,-0.682116,-0.6333489999999999,-0.618648,-0.656067,-0.646775,-0.630492,-0.09428099999999999,-0.20876999999999998,-0.236767,-0.24486799999999997,-0.227476,-0.234936 +969,969,20210621,0.0,0.253137,-0.11461099999999999,-0.114792,-0.039599,0.060405999999999994,0.13464,-0.404643,-0.160815,-0.03998,0.271165,-0.11586199999999999,-0.182509,-0.180259 +970,970,20210621,0.0,-0.616452,0.31188699999999997,-0.26005900000000004,-0.585237,-0.600713,-0.618516,0.254432,-0.221191,-0.213588,-0.29680100000000004,-0.135203,3.221917,-0.180878 +971,971,20210621,1.0,0.253137,-0.533042,0.177806,-0.315338,-0.087001,-0.343088,-0.476545,0.924676,-0.03998,1.84307,0.254178,-0.183229,-0.140996 +972,972,20210621,0.0,0.253137,1.116834,1.183235,1.228551,0.910033,0.9995959999999999,1.053265,0.081291,0.031937,-0.075351,-0.055795000000000004,-0.058868,-0.068374 +973,973,20210621,1.0,0.253137,-0.5576770000000001,-0.512698,-0.50225,-0.45520200000000005,-0.439015,-0.404055,-0.178324,-0.25699,-0.18320799999999998,-0.30806300000000003,-0.183229,-0.180878 +974,974,20210621,0.0,-1.486041,-0.694963,-0.5992770000000001,-0.646666,-0.672606,-0.640475,-0.652741,0.176624,-0.14848499999999998,-0.29680100000000004,-0.219973,-0.314136,-0.178066 +975,975,20210621,1.0,0.253137,1.126911,1.0978940000000001,0.8721610000000001,0.403456,0.49987700000000007,0.560764,-0.040063999999999995,-0.105083,-0.14345,-0.142097,-0.134663,-0.141502 +976,976,20210621,0.0,0.253137,-0.021924000000000003,0.168364,-0.22391599999999998,-0.434963,-0.366477,-0.346561,-0.215153,-0.17018599999999998,-0.069615,-0.11656400000000001,-0.21595599999999998,-0.23713 +977,977,20210621,1.0,0.253137,-0.611795,-0.585002,-0.573312,-0.6120760000000001,-0.566227,-0.652724,-0.221191,-0.255774,-0.29680100000000004,-0.180397,-0.314136,-0.29338200000000003 +978,978,20210621,0.0,-0.616452,-0.686597,-0.681682,-0.677986,0.191244,-0.6456890000000001,-0.646175,-0.301973,-0.25699,3.1911389999999997,-0.240655,-0.314136,-0.180991 +979,979,20210621,1.0,0.253137,-0.619713,-0.597984,-0.525452,-0.552292,-0.551308,-0.560588,-0.273959,-0.079867,-0.28317,-0.275891,-0.30307399999999995,-0.289894 +980,980,20210621,0.0,0.253137,1.324427,1.349564,1.417885,1.718747,1.823843,1.7944689999999999,-0.009876000000000001,-0.018279,0.327962,-0.30806300000000003,0.078584,-2.8000000000000003e-05 +981,981,20210621,0.0,0.253137,0.172197,0.22577399999999997,0.229924,0.325594,0.315326,0.369607,-0.160815,-0.161939,-0.171792,-0.168843,-0.156197,-0.183578 +982,982,20210621,0.0,2.861905,-0.228158,-0.213946,-0.19969,-0.168998,-0.147697,-0.139602,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +983,983,20210621,1.0,-1.486041,-0.083077,0.450805,-0.41661000000000004,-0.24923800000000002,-0.31004299999999996,-0.18405,4.590135,0.5340090000000001,1.257439,1.068813,1.521831,0.685233 +984,984,20210621,0.0,0.253137,-0.087219,-0.107261,-0.091771,-0.037617000000000005,0.004944,0.029960000000000004,-0.160815,-0.061421,-0.15481,-0.193163,-0.039231999999999996,-0.152752 +985,985,20210621,0.0,-1.486041,-0.018515,0.014162000000000001,0.043387,-0.35983699999999996,-0.354207,-0.345889,-0.191003,-0.201045,-0.244719,-0.224122,0.015880000000000002,-0.152077 +986,986,20210621,1.0,-0.616452,-0.681817,-0.601384,-0.677958,-0.657963,-0.581063,-0.632373,0.046454,-0.256903,-0.243583,0.010464,-0.23460999999999999,0.24359899999999998 +987,987,20210621,0.0,0.253137,1.134149,1.214146,1.065576,0.921178,-0.0025399999999999997,0.032462,0.024357,0.177029,-0.126411,2.255276,-0.21818099999999999,-0.180878 +988,988,20210621,0.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +989,989,20210621,0.0,1.992316,3.198341,3.393314,3.418196,3.9023489999999996,4.2371870000000005,4.040616,0.309631,-0.25699,0.555149,0.062167999999999994,-0.314136,6.832892999999999 +990,990,20210621,0.0,0.253137,0.157856,0.164472,0.14153,0.188959,0.226044,0.239639,-0.215153,-0.25699,-0.18320799999999998,-0.180397,-0.153448,-0.068374 +991,991,20210621,0.0,0.253137,0.096105,0.148202,-0.6758810000000001,-0.20793699999999998,-0.161217,-0.127546,0.133576,-0.250002,3.9262580000000002,-0.248889,-0.24285700000000002,0.21850999999999998 +992,992,20210621,1.0,-1.486041,-0.679141,-0.678956,-0.673732,-0.660015,-0.661447,-0.645487,-0.341942,-0.24436,-0.25119400000000003,-0.301807,-0.285926,-0.23128 +993,993,20210621,0.0,0.253137,0.083557,0.133056,0.18543900000000002,0.276909,0.363224,0.416154,-0.209115,-0.16150499999999998,-0.171849,-0.161247,-0.16359300000000002,-0.147127 +994,994,20210621,1.0,-1.486041,3.104825,1.689512,0.31431,-0.473529,-0.6630590000000001,-0.652724,0.080929,-0.17917,-0.140213,-0.30806300000000003,-0.314136,-0.29338200000000003 +995,995,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +996,996,20210621,0.0,-1.486041,-0.698358,-0.6937939999999999,-0.680813,-0.672497,0.337005,-0.652724,-0.341942,-0.25699,-0.28544200000000003,3.572979,-0.314136,-0.29338200000000003 +997,997,20210621,0.0,1.992316,-0.156276,-0.117743,-0.074409,0.018483000000000003,0.084242,0.126127,-0.24534099999999998,-0.187547,-0.11681300000000001,-0.199547,-0.20286500000000002,-0.209285 +998,998,20210621,1.0,-1.486041,-0.695642,-0.690983,-0.677929,-0.672497,-0.6630590000000001,-0.652724,-0.341942,-0.25699,-0.29680100000000004,-0.30806300000000003,-0.314136,-0.29338200000000003 +999,999,20210621,1.0,-0.616452,-0.685049,-0.690983,-0.6666810000000001,-0.666435,-0.656644,-0.644328,-0.341942,-0.223136,-0.29680100000000004,-0.283168,-0.281409,0.736028 +1000,1000,20210621,0.0,0.253137,0.8436879999999999,0.8562280000000001,0.932783,0.631026,0.758644,0.8384149999999999,-0.341942,-0.03998,-0.11743699999999999,-0.05694400000000001,-0.065282,-0.180878 diff --git a/deploy/integrated_test/credit_default/default_credit_hetero_host.csv b/deploy/integrated_test/credit_default/default_credit_hetero_host.csv new file mode 100644 index 000000000..37dd4a6d8 --- /dev/null +++ b/deploy/integrated_test/credit_default/default_credit_hetero_host.csv @@ -0,0 +1,1001 @@ +example_id,raw_id,event_time,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9 +1,1,20210621,-1.13672,0.810161,0.185828,-1.057295,-1.24602,1.794564,1.782348,-0.696663,-0.666599,-1.530046 +2,2,20210621,-0.365981,0.810161,0.185828,0.858557,-1.029047,-0.874991,1.782348,0.138865,0.188746,0.234917 +3,3,20210621,-0.597202,0.810161,0.185828,0.858557,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +4,4,20210621,-0.905498,0.810161,0.185828,-1.057295,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +5,5,20210621,-0.905498,-1.234323,0.185828,-1.057295,2.334029,-0.874991,0.111736,-0.696663,0.188746,0.234917 +6,6,20210621,-0.905498,-1.234323,-1.079457,0.858557,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +7,7,20210621,2.56283,-1.234323,-1.079457,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +8,8,20210621,-0.520128,0.810161,0.185828,0.858557,-1.354506,0.014861,-0.72357,-0.696663,0.188746,0.234917 +9,9,20210621,-0.211833,0.810161,1.451114,-1.057295,-0.812074,0.014861,0.111736,1.809921,0.188746,0.234917 +10,10,20210621,-1.13672,-1.234323,1.451114,0.858557,-0.05267,-1.764843,-1.558876,-1.532192,-1.521944,-0.647565 +11,11,20210621,0.250611,0.810161,1.451114,0.858557,-0.161156,0.014861,0.111736,1.809921,0.188746,0.234917 +12,12,20210621,0.713055,0.810161,-1.079457,0.858557,1.683111,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +13,13,20210621,3.564792,0.810161,0.185828,0.858557,0.598248,-0.874991,0.111736,-0.696663,-0.666599,-0.647565 +14,14,20210621,-0.75135,-1.234323,0.185828,0.858557,-0.595102,0.904712,1.782348,1.809921,0.188746,0.234917 +15,15,20210621,0.635981,-1.234323,-1.079457,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +16,16,20210621,-0.905498,0.810161,1.451114,2.77441,-1.354506,0.904712,1.782348,0.138865,0.188746,0.234917 +17,17,20210621,-1.13672,-1.234323,-1.079457,0.858557,-1.24602,0.014861,0.111736,1.809921,1.899436,1.999879 +18,18,20210621,1.175499,-1.234323,-1.079457,-1.057295,1.466139,0.014861,0.111736,0.138865,-0.666599,-0.647565 +19,19,20210621,1.483795,0.810161,-1.079457,-1.057295,1.466139,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +20,20,20210621,0.096463,0.810161,-1.079457,0.858557,-0.703588,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +21,21,20210621,-0.288907,0.810161,1.451114,0.858557,0.381275,0.014861,0.111736,0.138865,0.188746,0.234917 +22,22,20210621,-0.365981,0.810161,0.185828,-1.057295,0.381275,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +23,23,20210621,-0.75135,0.810161,0.185828,0.858557,-1.029047,1.794564,0.111736,0.138865,1.899436,1.999879 +24,24,20210621,2.17746,0.810161,-1.079457,-1.057295,0.489762,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +25,25,20210621,-0.597202,-1.234323,-1.079457,0.858557,-1.354506,0.014861,0.111736,0.138865,-0.666599,0.234917 +26,26,20210621,-0.905498,-1.234323,1.451114,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +27,27,20210621,-0.828424,-1.234323,-1.079457,0.858557,-0.920561,0.904712,-1.558876,-0.696663,-0.666599,-0.647565 +28,28,20210621,-0.905498,0.810161,1.451114,0.858557,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +29,29,20210621,-0.905498,0.810161,1.451114,-1.057295,1.249166,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +30,30,20210621,-0.905498,-1.234323,-1.079457,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +31,31,20210621,0.481833,0.810161,-1.079457,0.858557,-0.920561,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +32,32,20210621,-0.905498,-1.234323,0.185828,0.858557,-0.269643,1.794564,0.111736,0.138865,0.188746,0.234917 +33,33,20210621,-0.520128,-1.234323,-1.079457,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +34,34,20210621,2.56283,0.810161,0.185828,-1.057295,2.00857,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +35,35,20210621,2.56283,-1.234323,-1.079457,-1.057295,2.442516,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +36,36,20210621,-0.057685,-1.234323,-1.079457,0.858557,-0.595102,-0.874991,-0.72357,-1.532192,-1.521944,-1.530046 +37,37,20210621,0.867203,-1.234323,0.185828,-1.057295,0.489762,0.014861,0.111736,0.138865,0.188746,0.234917 +38,38,20210621,-0.828424,0.810161,0.185828,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +39,39,20210621,-0.905498,-1.234323,-1.079457,0.858557,-1.137534,0.904712,-0.72357,-0.696663,-1.521944,-1.530046 +40,40,20210621,0.867203,-1.234323,-1.079457,0.858557,-0.486615,-0.874991,-0.72357,1.809921,-0.666599,0.234917 +41,41,20210621,1.483795,-1.234323,-1.079457,0.858557,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +42,42,20210621,-0.75135,0.810161,-1.079457,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +43,43,20210621,-1.213794,-1.234323,0.185828,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +44,44,20210621,-0.211833,0.810161,0.185828,-1.057295,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +45,45,20210621,-0.982572,0.810161,-1.079457,0.858557,-0.595102,0.014861,0.111736,0.138865,1.899436,0.234917 +46,46,20210621,0.327685,-1.234323,-1.079457,0.858557,-0.703588,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +47,47,20210621,-1.13672,0.810161,-1.079457,0.858557,-1.462993,0.014861,0.111736,1.809921,-0.666599,0.234917 +48,48,20210621,-0.134759,0.810161,3.981685,0.858557,1.14068,0.014861,0.111736,-0.696663,0.188746,0.234917 +49,49,20210621,1.637943,-1.234323,0.185828,0.858557,-0.378129,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +50,50,20210621,-1.13672,-1.234323,-1.079457,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +51,51,20210621,-0.75135,-1.234323,1.451114,0.858557,0.706734,0.904712,1.782348,1.809921,1.899436,1.999879 +52,52,20210621,-0.520128,0.810161,1.451114,2.77441,0.815221,0.014861,0.111736,0.138865,0.188746,0.234917 +53,53,20210621,1.098425,0.810161,0.185828,-1.057295,1.466139,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +54,54,20210621,0.096463,0.810161,-1.079457,0.858557,-1.137534,0.904712,1.782348,0.138865,0.188746,0.234917 +55,55,20210621,-0.134759,0.810161,-1.079457,0.858557,-0.703588,1.794564,0.111736,0.138865,0.188746,0.234917 +56,56,20210621,2.56283,0.810161,-1.079457,-1.057295,1.032193,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +57,57,20210621,0.096463,0.810161,1.451114,-1.057295,-0.161156,0.014861,0.111736,0.138865,-0.666599,-0.647565 +58,58,20210621,0.096463,0.810161,0.185828,-1.057295,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +59,59,20210621,0.250611,0.810161,-1.079457,0.858557,-0.161156,-0.874991,2.617654,1.809921,1.899436,1.999879 +60,60,20210621,1.792091,0.810161,0.185828,-1.057295,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +61,61,20210621,2.56283,0.810161,1.451114,-1.057295,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +62,62,20210621,-0.75135,-1.234323,0.185828,-1.057295,0.381275,0.014861,0.111736,0.138865,0.188746,0.234917 +63,63,20210621,-0.905498,-1.234323,-1.079457,0.858557,-0.703588,1.794564,1.782348,1.809921,1.899436,1.999879 +64,64,20210621,-0.905498,0.810161,0.185828,-1.057295,1.14068,0.014861,0.111736,0.138865,-1.521944,-1.530046 +65,65,20210621,-0.288907,0.810161,0.185828,-1.057295,1.683111,-0.874991,-0.72357,-1.532192,-1.521944,-0.647565 +66,66,20210621,0.250611,-1.234323,-1.079457,-1.057295,2.334029,-1.764843,-1.558876,-1.532192,-0.666599,1.999879 +67,67,20210621,-1.213794,-1.234323,0.185828,-1.057295,2.225543,1.794564,1.782348,1.809921,0.188746,0.234917 +68,68,20210621,0.327685,0.810161,-1.079457,0.858557,-0.595102,1.794564,-0.72357,-0.696663,-0.666599,-0.647565 +69,69,20210621,-0.288907,0.810161,1.451114,0.858557,-0.703588,0.904712,-1.558876,-1.532192,-0.666599,1.999879 +70,70,20210621,-1.13672,-1.234323,3.981685,0.858557,-1.462993,1.794564,0.111736,0.138865,0.188746,0.234917 +71,71,20210621,-0.674276,-1.234323,-1.079457,0.858557,-0.486615,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +72,72,20210621,1.175499,-1.234323,0.185828,0.858557,-0.703588,1.794564,1.782348,1.809921,1.899436,1.999879 +73,73,20210621,0.250611,0.810161,0.185828,-1.057295,-0.378129,-0.874991,-0.72357,-0.696663,-0.666599,1.999879 +74,74,20210621,0.944277,0.810161,-1.079457,0.858557,0.164303,0.904712,-1.558876,-0.696663,-0.666599,-0.647565 +75,75,20210621,1.329647,-1.234323,-1.079457,0.858557,-0.378129,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +76,76,20210621,-1.13672,-1.234323,0.185828,0.858557,-1.24602,0.014861,0.111736,1.809921,0.188746,0.234917 +77,77,20210621,-0.905498,-1.234323,1.451114,0.858557,-1.137534,-0.874991,0.111736,0.138865,0.188746,0.234917 +78,78,20210621,1.021351,0.810161,-1.079457,-1.057295,1.032193,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +79,79,20210621,-1.059646,0.810161,0.185828,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +80,80,20210621,0.558907,0.810161,0.185828,0.858557,0.923707,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +81,81,20210621,2.331608,0.810161,1.451114,2.77441,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +82,82,20210621,1.483795,0.810161,-1.079457,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +83,83,20210621,-0.828424,-1.234323,1.451114,0.858557,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +84,84,20210621,1.792091,0.810161,0.185828,-1.057295,0.923707,0.014861,0.111736,1.809921,0.188746,0.234917 +85,85,20210621,-0.905498,0.810161,1.451114,0.858557,1.466139,0.014861,0.111736,0.138865,0.188746,0.234917 +86,86,20210621,-0.057685,-1.234323,0.185828,0.858557,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +87,87,20210621,1.483795,0.810161,-1.079457,-1.057295,1.032193,-0.874991,-0.72357,1.809921,0.188746,-0.647565 +88,88,20210621,-0.057685,0.810161,0.185828,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +89,89,20210621,-0.288907,0.810161,-1.079457,-1.057295,-0.05267,0.014861,0.111736,0.138865,-0.666599,-0.647565 +90,90,20210621,-1.13672,-1.234323,1.451114,0.858557,0.923707,1.794564,1.782348,0.138865,0.188746,0.234917 +91,91,20210621,0.250611,-1.234323,-1.079457,-1.057295,1.900084,1.794564,1.782348,1.809921,1.899436,1.999879 +92,92,20210621,0.867203,0.810161,-1.079457,0.858557,0.381275,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +93,93,20210621,-0.520128,0.810161,-1.079457,0.858557,-0.920561,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +94,94,20210621,-0.057685,0.810161,0.185828,-1.057295,0.164303,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +95,95,20210621,-0.828424,0.810161,0.185828,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +96,96,20210621,-0.597202,-1.234323,0.185828,0.858557,-0.05267,0.014861,0.111736,0.138865,0.188746,0.234917 +97,97,20210621,1.483795,-1.234323,-1.079457,-1.057295,0.815221,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +98,98,20210621,-0.134759,-1.234323,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +99,99,20210621,-0.905498,0.810161,1.451114,-1.057295,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +100,100,20210621,-1.13672,-1.234323,0.185828,-1.057295,0.272789,0.014861,0.111736,0.138865,0.188746,0.234917 +101,101,20210621,-0.211833,-1.234323,-1.079457,0.858557,-0.378129,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +102,102,20210621,1.637943,0.810161,-1.079457,0.858557,-0.595102,-1.764843,-1.558876,-0.696663,0.188746,0.234917 +103,103,20210621,2.408682,-1.234323,-1.079457,-1.057295,2.984947,0.014861,0.111736,0.138865,1.899436,1.999879 +104,104,20210621,-0.905498,0.810161,1.451114,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +105,105,20210621,-0.828424,0.810161,0.185828,0.858557,-1.029047,1.794564,1.782348,1.809921,1.899436,1.999879 +106,106,20210621,-0.75135,0.810161,0.185828,0.858557,-1.24602,-0.874991,-0.72357,-1.532192,-1.521944,-1.530046 +107,107,20210621,-0.674276,0.810161,0.185828,-1.057295,0.055816,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +108,108,20210621,1.406721,-1.234323,-1.079457,0.858557,1.791598,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +109,109,20210621,-0.288907,-1.234323,0.185828,0.858557,0.272789,0.014861,0.111736,0.138865,-0.666599,-0.647565 +110,110,20210621,1.483795,-1.234323,0.185828,-1.057295,-0.05267,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +111,111,20210621,1.252573,0.810161,-1.079457,-1.057295,-0.486615,0.014861,0.111736,1.809921,0.188746,0.234917 +112,112,20210621,-0.905498,-1.234323,1.451114,-1.057295,1.249166,0.014861,0.111736,1.809921,0.188746,0.234917 +113,113,20210621,0.867203,-1.234323,0.185828,-1.057295,0.598248,1.794564,1.782348,1.809921,1.899436,1.999879 +114,114,20210621,-0.520128,0.810161,-1.079457,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +115,115,20210621,-0.905498,-1.234323,0.185828,0.858557,0.598248,0.014861,0.111736,0.138865,0.188746,0.234917 +116,116,20210621,-1.059646,-1.234323,-1.079457,0.858557,-1.24602,-0.874991,1.782348,0.138865,0.188746,2.88236 +117,117,20210621,0.558907,-1.234323,-1.079457,0.858557,-0.812074,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +118,118,20210621,-0.674276,-1.234323,0.185828,0.858557,-1.029047,1.794564,0.111736,0.138865,0.188746,0.234917 +119,119,20210621,1.792091,-1.234323,0.185828,-1.057295,-0.161156,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +120,120,20210621,0.558907,0.810161,0.185828,0.858557,0.272789,0.014861,0.111736,0.138865,0.188746,-0.647565 +121,121,20210621,-0.905498,-1.234323,1.451114,0.858557,0.164303,1.794564,1.782348,1.809921,2.754781,1.999879 +122,122,20210621,2.17746,-1.234323,-1.079457,-1.057295,0.489762,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +123,123,20210621,-0.443054,0.810161,-1.079457,-1.057295,1.357652,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +124,124,20210621,1.098425,0.810161,0.185828,-1.057295,-0.05267,1.794564,0.111736,0.138865,0.188746,0.234917 +125,125,20210621,-1.13672,-1.234323,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +126,126,20210621,-1.13672,-1.234323,0.185828,0.858557,-1.354506,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +127,127,20210621,0.250611,-1.234323,1.451114,0.858557,1.791598,0.014861,0.111736,0.138865,0.188746,0.234917 +128,128,20210621,0.096463,-1.234323,-1.079457,-1.057295,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +129,129,20210621,-0.905498,-1.234323,0.185828,-1.057295,1.683111,0.014861,0.111736,0.138865,0.188746,0.234917 +130,130,20210621,-0.828424,-1.234323,1.451114,-1.057295,2.117057,2.684416,1.782348,1.809921,0.188746,0.234917 +131,131,20210621,-1.059646,0.810161,-1.079457,0.858557,-1.354506,0.904712,-1.558876,-1.532192,-1.521944,-0.647565 +132,132,20210621,0.558907,-1.234323,-1.079457,0.858557,0.598248,0.904712,-0.72357,-0.696663,0.188746,0.234917 +133,133,20210621,1.946238,-1.234323,0.185828,-1.057295,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +134,134,20210621,1.252573,-1.234323,1.451114,-1.057295,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +135,135,20210621,-1.059646,0.810161,0.185828,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +136,136,20210621,0.558907,-1.234323,0.185828,-1.057295,-0.161156,0.014861,0.111736,0.138865,1.899436,1.999879 +137,137,20210621,-0.134759,-1.234323,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +138,138,20210621,0.327685,0.810161,0.185828,-1.057295,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +139,139,20210621,-0.905498,0.810161,1.451114,-1.057295,1.683111,-0.874991,-0.72357,-0.696663,-0.666599,-1.530046 +140,140,20210621,-0.905498,-1.234323,-1.079457,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +141,141,20210621,0.558907,-1.234323,-1.079457,0.858557,1.249166,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +142,142,20210621,0.096463,-1.234323,0.185828,0.858557,-0.812074,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +143,143,20210621,-0.905498,-1.234323,0.185828,0.858557,-1.354506,0.904712,1.782348,1.809921,1.899436,0.234917 +144,144,20210621,0.019389,-1.234323,0.185828,0.858557,-0.703588,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +145,145,20210621,-1.13672,-1.234323,-1.079457,0.858557,-0.703588,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +146,146,20210621,-0.905498,-1.234323,-1.079457,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +147,147,20210621,0.019389,0.810161,0.185828,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +148,148,20210621,0.250611,-1.234323,-1.079457,0.858557,-0.161156,0.904712,1.782348,0.138865,0.188746,0.234917 +149,149,20210621,-0.674276,0.810161,0.185828,-1.057295,-1.354506,0.904712,1.782348,2.64545,1.899436,0.234917 +150,150,20210621,0.713055,0.810161,-1.079457,-1.057295,2.659488,0.904712,-1.558876,-0.696663,-0.666599,-0.647565 +151,151,20210621,-0.211833,-1.234323,0.185828,-1.057295,-0.378129,0.014861,0.111736,0.138865,0.188746,1.999879 +152,152,20210621,-0.674276,-1.234323,-1.079457,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +153,153,20210621,1.406721,-1.234323,-1.079457,0.858557,0.598248,0.904712,-0.72357,-0.696663,-0.666599,-0.647565 +154,154,20210621,0.867203,0.810161,0.185828,-1.057295,2.225543,0.014861,0.111736,0.138865,0.188746,0.234917 +155,155,20210621,-1.059646,0.810161,1.451114,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +156,156,20210621,-0.211833,-1.234323,-1.079457,-1.057295,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +157,157,20210621,0.250611,0.810161,-1.079457,0.858557,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +158,158,20210621,0.250611,0.810161,1.451114,0.858557,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +159,159,20210621,0.327685,-1.234323,1.451114,-1.057295,1.032193,1.794564,2.617654,3.480978,3.610125,4.647323 +160,160,20210621,-0.905498,-1.234323,1.451114,-1.057295,2.334029,2.684416,1.782348,0.138865,0.188746,0.234917 +161,161,20210621,-1.059646,-1.234323,-1.079457,0.858557,0.598248,1.794564,1.782348,1.809921,1.899436,1.999879 +162,162,20210621,-0.905498,-1.234323,0.185828,0.858557,-0.920561,1.794564,-0.72357,-0.696663,-0.666599,-0.647565 +163,163,20210621,0.944277,-1.234323,1.451114,-1.057295,1.249166,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +164,164,20210621,0.635981,0.810161,-1.079457,-1.057295,-0.161156,0.014861,0.111736,1.809921,0.188746,0.234917 +165,165,20210621,-0.828424,0.810161,0.185828,-1.057295,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +166,166,20210621,-0.443054,0.810161,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +167,167,20210621,1.560869,-1.234323,-1.079457,0.858557,1.574625,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +168,168,20210621,-0.520128,-1.234323,0.185828,-1.057295,-0.920561,-0.874991,1.782348,1.809921,0.188746,0.234917 +169,169,20210621,-0.597202,0.810161,0.185828,-1.057295,-0.05267,0.014861,0.111736,0.138865,0.188746,0.234917 +170,170,20210621,-0.905498,0.810161,0.185828,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +171,171,20210621,0.790129,-1.234323,0.185828,0.858557,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +172,172,20210621,1.021351,0.810161,-1.079457,0.858557,-0.595102,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +173,173,20210621,-0.905498,0.810161,0.185828,0.858557,-1.462993,-0.874991,0.111736,0.138865,0.188746,0.234917 +174,174,20210621,-0.905498,0.810161,-1.079457,0.858557,-1.24602,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +175,175,20210621,1.483795,-1.234323,-1.079457,0.858557,-0.703588,0.904712,-1.558876,-0.696663,-0.666599,-1.530046 +176,176,20210621,-0.288907,-1.234323,1.451114,-1.057295,2.225543,0.904712,1.782348,1.809921,1.899436,1.999879 +177,177,20210621,-0.674276,-1.234323,-1.079457,0.858557,-0.595102,-1.764843,-0.72357,0.138865,0.188746,0.234917 +178,178,20210621,-0.905498,-1.234323,0.185828,0.858557,-0.595102,0.904712,1.782348,0.138865,0.188746,0.234917 +179,179,20210621,-1.13672,0.810161,0.185828,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +180,180,20210621,-0.674276,0.810161,0.185828,-1.057295,-0.703588,0.014861,0.111736,1.809921,0.188746,0.234917 +181,181,20210621,0.558907,-1.234323,-1.079457,0.858557,0.164303,-0.874991,-0.72357,1.809921,0.188746,0.234917 +182,182,20210621,-0.674276,0.810161,1.451114,0.858557,-0.05267,0.014861,-0.72357,0.138865,0.188746,0.234917 +183,183,20210621,2.56283,0.810161,-1.079457,-1.057295,1.249166,0.014861,0.111736,0.138865,0.188746,0.234917 +184,184,20210621,-0.828424,0.810161,0.185828,-1.057295,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +185,185,20210621,-1.13672,-1.234323,0.185828,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +186,186,20210621,-0.520128,0.810161,0.185828,-1.057295,0.272789,0.904712,1.782348,0.138865,0.188746,1.999879 +187,187,20210621,1.483795,0.810161,-1.079457,0.858557,-0.378129,0.904712,-0.72357,-0.696663,-0.666599,-0.647565 +188,188,20210621,0.250611,0.810161,1.451114,0.858557,1.249166,1.794564,1.782348,1.809921,1.899436,1.999879 +189,189,20210621,-0.288907,0.810161,0.185828,-1.057295,-0.161156,0.904712,-0.72357,0.138865,0.188746,0.234917 +190,190,20210621,-1.13672,0.810161,0.185828,0.858557,-0.486615,0.904712,4.288266,3.480978,3.610125,2.88236 +191,191,20210621,1.098425,-1.234323,-1.079457,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +192,192,20210621,-0.828424,0.810161,-1.079457,0.858557,-0.920561,1.794564,0.111736,0.138865,0.188746,1.999879 +193,193,20210621,0.096463,0.810161,-1.079457,0.858557,-0.703588,-0.874991,-0.72357,-0.696663,-1.521944,-0.647565 +194,194,20210621,0.096463,0.810161,-1.079457,0.858557,-1.24602,-0.874991,-0.72357,1.809921,0.188746,0.234917 +195,195,20210621,-0.905498,-1.234323,0.185828,-1.057295,0.055816,0.014861,0.111736,0.138865,0.188746,-0.647565 +196,196,20210621,-0.905498,0.810161,-1.079457,0.858557,-1.24602,0.904712,1.782348,1.809921,1.899436,1.999879 +197,197,20210621,-0.134759,0.810161,0.185828,-1.057295,-0.161156,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +198,198,20210621,-1.13672,0.810161,-1.079457,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,-0.647565 +199,199,20210621,2.56283,0.810161,-1.079457,-1.057295,-0.161156,-1.764843,-1.558876,-1.532192,-0.666599,-0.647565 +200,200,20210621,-1.059646,0.810161,1.451114,0.858557,-1.462993,0.904712,1.782348,1.809921,0.188746,0.234917 +201,201,20210621,0.096463,0.810161,-1.079457,-1.057295,0.272789,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +202,202,20210621,-0.211833,-1.234323,-1.079457,0.858557,-0.486615,0.014861,0.111736,1.809921,0.188746,0.234917 +203,203,20210621,-0.211833,0.810161,-1.079457,0.858557,-1.029047,-0.874991,0.111736,-0.696663,-0.666599,-0.647565 +204,204,20210621,-0.365981,-1.234323,0.185828,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +205,205,20210621,1.483795,0.810161,0.185828,-1.057295,1.357652,0.014861,0.111736,0.138865,0.188746,0.234917 +206,206,20210621,-1.13672,-1.234323,1.451114,-1.057295,0.815221,-0.874991,-0.72357,0.138865,0.188746,0.234917 +207,207,20210621,-0.520128,-1.234323,-1.079457,-1.057295,1.249166,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +208,208,20210621,0.327685,0.810161,0.185828,-1.057295,0.598248,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +209,209,20210621,-0.674276,0.810161,0.185828,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +210,210,20210621,1.252573,0.810161,-1.079457,-1.057295,1.574625,-0.874991,-0.72357,-0.696663,-0.666599,-1.530046 +211,211,20210621,0.404759,-1.234323,-1.079457,0.858557,-1.24602,0.014861,0.111736,0.138865,-0.666599,-0.647565 +212,212,20210621,0.327685,0.810161,-1.079457,-1.057295,0.272789,0.904712,-1.558876,-0.696663,0.188746,-0.647565 +213,213,20210621,-0.982572,0.810161,1.451114,-1.057295,0.815221,0.014861,0.111736,0.138865,0.188746,0.234917 +214,214,20210621,-1.059646,-1.234323,0.185828,0.858557,0.381275,0.014861,0.111736,0.138865,1.899436,0.234917 +215,215,20210621,2.331608,-1.234323,0.185828,0.858557,-0.920561,1.794564,1.782348,1.809921,1.899436,0.234917 +216,216,20210621,-1.059646,-1.234323,1.451114,-1.057295,0.706734,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +217,217,20210621,0.558907,0.810161,0.185828,-1.057295,0.055816,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +218,218,20210621,-0.674276,-1.234323,0.185828,0.858557,0.055816,1.794564,0.111736,0.138865,0.188746,0.234917 +219,219,20210621,-0.443054,0.810161,1.451114,-2.973147,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +220,220,20210621,1.098425,0.810161,-1.079457,0.858557,0.272789,-0.874991,-0.72357,-0.696663,-0.666599,-1.530046 +221,221,20210621,1.483795,0.810161,-1.079457,-1.057295,0.489762,1.794564,1.782348,1.809921,0.188746,0.234917 +222,222,20210621,1.252573,0.810161,1.451114,0.858557,1.032193,0.014861,0.111736,0.138865,0.188746,0.234917 +223,223,20210621,1.021351,0.810161,0.185828,0.858557,-0.05267,0.014861,0.111736,0.138865,0.188746,0.234917 +224,224,20210621,1.175499,0.810161,0.185828,0.858557,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +225,225,20210621,-0.905498,0.810161,1.451114,0.858557,0.164303,0.904712,2.617654,1.809921,0.188746,0.234917 +226,226,20210621,0.019389,0.810161,-1.079457,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +227,227,20210621,1.406721,-1.234323,1.451114,-1.057295,0.923707,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +228,228,20210621,-1.13672,-1.234323,0.185828,-1.057295,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +229,229,20210621,-0.905498,-1.234323,0.185828,0.858557,-1.354506,1.794564,0.111736,0.138865,0.188746,0.234917 +230,230,20210621,-1.13672,0.810161,1.451114,0.858557,-1.24602,0.904712,1.782348,0.138865,0.188746,0.234917 +231,231,20210621,-0.905498,0.810161,-1.079457,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +232,232,20210621,-1.13672,-1.234323,0.185828,0.858557,-1.354506,0.904712,1.782348,0.138865,0.188746,1.999879 +233,233,20210621,-0.905498,-1.234323,0.185828,-1.057295,-1.029047,0.014861,0.111736,-1.532192,-0.666599,-0.647565 +234,234,20210621,0.173537,-1.234323,0.185828,0.858557,-0.161156,1.794564,0.111736,0.138865,0.188746,1.999879 +235,235,20210621,-0.828424,0.810161,0.185828,-1.057295,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +236,236,20210621,-0.674276,-1.234323,-1.079457,0.858557,-0.05267,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +237,237,20210621,-0.134759,0.810161,0.185828,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +238,238,20210621,0.327685,0.810161,-1.079457,0.858557,-0.486615,-1.764843,-1.558876,-1.532192,-1.521944,-0.647565 +239,239,20210621,0.558907,0.810161,1.451114,-1.057295,1.574625,0.014861,0.111736,0.138865,0.188746,0.234917 +240,240,20210621,-0.211833,0.810161,0.185828,2.77441,0.598248,0.014861,0.111736,0.138865,0.188746,0.234917 +241,241,20210621,-0.828424,0.810161,-1.079457,0.858557,-0.812074,0.904712,1.782348,1.809921,-1.521944,-1.530046 +242,242,20210621,-0.905498,-1.234323,-1.079457,0.858557,0.381275,0.014861,0.111736,0.138865,0.188746,0.234917 +243,243,20210621,-0.905498,0.810161,0.185828,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +244,244,20210621,0.096463,0.810161,-1.079457,0.858557,-0.378129,-0.874991,-0.72357,1.809921,1.899436,-0.647565 +245,245,20210621,-1.059646,0.810161,-1.079457,0.858557,0.489762,-0.874991,-0.72357,1.809921,1.899436,1.999879 +246,246,20210621,-1.13672,0.810161,0.185828,0.858557,0.489762,0.014861,0.111736,0.138865,0.188746,0.234917 +247,247,20210621,0.635981,0.810161,0.185828,-1.057295,4.286783,0.014861,-0.72357,-0.696663,-0.666599,-0.647565 +248,248,20210621,-0.520128,0.810161,0.185828,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +249,249,20210621,1.252573,-1.234323,-1.079457,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,1.999879 +250,250,20210621,-0.905498,-1.234323,1.451114,-1.057295,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +251,251,20210621,-0.905498,0.810161,0.185828,0.858557,-1.029047,0.904712,1.782348,1.809921,0.188746,0.234917 +252,252,20210621,-1.059646,-1.234323,0.185828,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +253,253,20210621,-0.211833,0.810161,0.185828,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +254,254,20210621,-0.057685,0.810161,-1.079457,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,-0.647565 +255,255,20210621,1.792091,0.810161,0.185828,0.858557,-0.703588,-0.874991,0.111736,-0.696663,-0.666599,-0.647565 +256,256,20210621,-0.905498,-1.234323,0.185828,-1.057295,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +257,257,20210621,-0.211833,0.810161,0.185828,-1.057295,1.357652,0.014861,-0.72357,-0.696663,-0.666599,-0.647565 +258,258,20210621,-0.057685,0.810161,0.185828,-1.057295,-0.269643,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +259,259,20210621,-0.520128,0.810161,1.451114,-1.057295,0.815221,0.014861,0.111736,-1.532192,-1.521944,-1.530046 +260,260,20210621,0.404759,-1.234323,-1.079457,-1.057295,1.357652,1.794564,0.111736,0.138865,0.188746,0.234917 +261,261,20210621,2.639904,0.810161,-1.079457,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +262,262,20210621,-0.905498,-1.234323,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +263,263,20210621,-0.057685,0.810161,-1.079457,-1.057295,0.272789,-0.874991,-0.72357,-0.696663,-0.666599,1.999879 +264,264,20210621,0.481833,0.810161,-1.079457,0.858557,0.164303,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +265,265,20210621,-0.674276,0.810161,-1.079457,0.858557,0.164303,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +266,266,20210621,-0.134759,0.810161,0.185828,-1.057295,-1.137534,-0.874991,-0.72357,-1.532192,-0.666599,-0.647565 +267,267,20210621,-1.213794,-1.234323,1.451114,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +268,268,20210621,-0.288907,0.810161,1.451114,0.858557,1.466139,0.014861,0.111736,0.138865,0.188746,0.234917 +269,269,20210621,-0.982572,0.810161,-1.079457,0.858557,1.357652,0.014861,0.111736,0.138865,0.188746,0.234917 +270,270,20210621,-0.905498,-1.234323,0.185828,0.858557,-0.920561,2.684416,1.782348,1.809921,0.188746,0.234917 +271,271,20210621,-0.520128,-1.234323,1.451114,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +272,272,20210621,-0.365981,-1.234323,-1.079457,-1.057295,-0.161156,-0.874991,1.782348,-0.696663,0.188746,0.234917 +273,273,20210621,0.713055,0.810161,-1.079457,0.858557,2.442516,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +274,274,20210621,0.250611,0.810161,0.185828,0.858557,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +275,275,20210621,1.483795,0.810161,0.185828,0.858557,-0.812074,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +276,276,20210621,-0.75135,0.810161,0.185828,0.858557,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +277,277,20210621,2.254534,-1.234323,-1.079457,-1.057295,0.489762,1.794564,-0.72357,-0.696663,-0.666599,-0.647565 +278,278,20210621,-0.905498,0.810161,-1.079457,0.858557,-1.029047,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +279,279,20210621,-0.905498,-1.234323,1.451114,-1.057295,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +280,280,20210621,0.635981,0.810161,0.185828,-1.057295,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +281,281,20210621,-1.059646,0.810161,-1.079457,0.858557,-0.920561,0.014861,0.111736,-0.696663,0.188746,0.234917 +282,282,20210621,0.790129,-1.234323,0.185828,-1.057295,0.923707,0.014861,0.111736,0.138865,0.188746,-0.647565 +283,283,20210621,0.096463,0.810161,1.451114,0.858557,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +284,284,20210621,-0.520128,0.810161,-1.079457,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +285,285,20210621,0.481833,0.810161,1.451114,-1.057295,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +286,286,20210621,0.327685,0.810161,-1.079457,-1.057295,1.14068,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +287,287,20210621,0.327685,-1.234323,-1.079457,0.858557,0.272789,1.794564,0.111736,0.138865,0.188746,0.234917 +288,288,20210621,2.100386,0.810161,0.185828,-1.057295,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +289,289,20210621,-0.520128,0.810161,0.185828,0.858557,-1.137534,1.794564,0.111736,0.138865,0.188746,0.234917 +290,290,20210621,0.558907,0.810161,0.185828,-1.057295,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +291,291,20210621,0.867203,-1.234323,-1.079457,0.858557,-0.269643,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +292,292,20210621,-0.905498,0.810161,0.185828,0.858557,-1.462993,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +293,293,20210621,-1.059646,-1.234323,0.185828,-1.057295,0.815221,2.684416,1.782348,1.809921,1.899436,1.999879 +294,294,20210621,-1.213794,-1.234323,0.185828,0.858557,-0.920561,0.014861,0.111736,1.809921,0.188746,0.234917 +295,295,20210621,-0.288907,-1.234323,-1.079457,0.858557,-0.703588,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +296,296,20210621,0.250611,-1.234323,-1.079457,0.858557,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +297,297,20210621,-0.365981,0.810161,0.185828,-1.057295,-0.703588,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +298,298,20210621,0.327685,0.810161,0.185828,-1.057295,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +299,299,20210621,0.867203,0.810161,-1.079457,-1.057295,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +300,300,20210621,1.021351,-1.234323,-1.079457,0.858557,-0.161156,0.904712,-1.558876,-0.696663,0.188746,-0.647565 +301,301,20210621,-0.520128,-1.234323,0.185828,0.858557,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +302,302,20210621,2.100386,0.810161,-1.079457,0.858557,0.055816,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +303,303,20210621,-0.905498,0.810161,1.451114,-1.057295,0.489762,0.014861,0.111736,0.138865,0.188746,0.234917 +304,304,20210621,-1.13672,0.810161,-1.079457,0.858557,-1.137534,0.014861,0.111736,1.809921,0.188746,0.234917 +305,305,20210621,0.250611,0.810161,-1.079457,0.858557,-0.920561,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +306,306,20210621,-0.443054,0.810161,0.185828,0.858557,-1.029047,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +307,307,20210621,2.56283,0.810161,0.185828,-1.057295,0.055816,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +308,308,20210621,1.021351,0.810161,0.185828,-1.057295,-0.920561,0.904712,-0.72357,-0.696663,-1.521944,-1.530046 +309,309,20210621,-1.059646,-1.234323,1.451114,-1.057295,2.117057,1.794564,1.782348,1.809921,2.754781,2.88236 +310,310,20210621,-0.828424,0.810161,-1.079457,0.858557,-0.920561,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +311,311,20210621,1.792091,0.810161,0.185828,-1.057295,0.272789,-0.874991,0.111736,-0.696663,-0.666599,0.234917 +312,312,20210621,0.096463,0.810161,0.185828,-1.057295,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +313,313,20210621,-1.13672,-1.234323,-1.079457,0.858557,0.489762,0.014861,0.111736,0.138865,1.899436,0.234917 +314,314,20210621,0.250611,0.810161,1.451114,-1.057295,1.466139,-0.874991,1.782348,1.809921,1.899436,0.234917 +315,315,20210621,-0.520128,-1.234323,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +316,316,20210621,-0.828424,-1.234323,0.185828,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +317,317,20210621,-0.443054,0.810161,0.185828,0.858557,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +318,318,20210621,0.713055,0.810161,1.451114,-1.057295,1.900084,0.904712,-0.72357,-0.696663,-1.521944,-1.530046 +319,319,20210621,-0.905498,0.810161,1.451114,-1.057295,1.14068,2.684416,1.782348,1.809921,0.188746,0.234917 +320,320,20210621,0.096463,-1.234323,0.185828,0.858557,-0.703588,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +321,321,20210621,-0.443054,-1.234323,0.185828,0.858557,-0.703588,0.904712,1.782348,1.809921,0.188746,0.234917 +322,322,20210621,1.329647,0.810161,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +323,323,20210621,-0.905498,-1.234323,0.185828,0.858557,-1.24602,-0.874991,0.111736,0.138865,0.188746,0.234917 +324,324,20210621,0.481833,0.810161,0.185828,-1.057295,-0.812074,0.014861,0.111736,0.138865,-1.521944,-0.647565 +325,325,20210621,1.483795,0.810161,0.185828,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +326,326,20210621,0.327685,-1.234323,0.185828,0.858557,0.815221,0.904712,-1.558876,-0.696663,0.188746,0.234917 +327,327,20210621,0.404759,0.810161,0.185828,-1.057295,0.598248,-0.874991,1.782348,1.809921,-0.666599,1.999879 +328,328,20210621,-0.828424,0.810161,0.185828,-1.057295,-0.161156,1.794564,1.782348,1.809921,1.899436,1.999879 +329,329,20210621,1.329647,-1.234323,0.185828,-1.057295,2.117057,-1.764843,-0.72357,-0.696663,-1.521944,-1.530046 +330,330,20210621,-0.134759,-1.234323,-1.079457,-1.057295,0.489762,1.794564,1.782348,1.809921,1.899436,1.999879 +331,331,20210621,0.250611,0.810161,0.185828,-1.057295,0.164303,0.904712,-0.72357,1.809921,-0.666599,-0.647565 +332,332,20210621,-0.288907,0.810161,0.185828,0.858557,0.489762,0.014861,0.111736,1.809921,0.188746,0.234917 +333,333,20210621,-0.828424,0.810161,-1.079457,0.858557,-0.812074,0.904712,1.782348,0.138865,0.188746,0.234917 +334,334,20210621,1.792091,0.810161,0.185828,-1.057295,0.815221,0.904712,-1.558876,-1.532192,-1.521944,-0.647565 +335,335,20210621,-1.13672,-1.234323,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +336,336,20210621,0.173537,0.810161,-1.079457,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +337,337,20210621,0.713055,0.810161,-1.079457,0.858557,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +338,338,20210621,-0.211833,0.810161,0.185828,0.858557,-0.486615,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +339,339,20210621,-0.905498,0.810161,0.185828,-1.057295,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +340,340,20210621,-0.365981,0.810161,-1.079457,0.858557,-0.161156,-0.874991,-0.72357,0.138865,-0.666599,-0.647565 +341,341,20210621,0.558907,0.810161,0.185828,0.858557,-0.595102,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +342,342,20210621,-0.905498,-1.234323,0.185828,0.858557,0.055816,0.014861,0.111736,0.138865,0.188746,-0.647565 +343,343,20210621,0.250611,0.810161,-1.079457,0.858557,-0.703588,-0.874991,1.782348,-0.696663,-0.666599,-0.647565 +344,344,20210621,0.096463,-1.234323,-1.079457,-1.057295,0.381275,0.014861,0.111736,-0.696663,0.188746,0.234917 +345,345,20210621,0.096463,0.810161,-1.079457,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +346,346,20210621,-0.057685,0.810161,-1.079457,0.858557,-0.703588,-0.874991,-0.72357,-1.532192,-0.666599,0.234917 +347,347,20210621,-0.520128,0.810161,0.185828,0.858557,-1.029047,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +348,348,20210621,-0.905498,0.810161,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +349,349,20210621,-0.211833,0.810161,0.185828,0.858557,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +350,350,20210621,-1.059646,0.810161,0.185828,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +351,351,20210621,-0.597202,-1.234323,-1.079457,0.858557,-1.029047,0.014861,0.111736,-0.696663,0.188746,0.234917 +352,352,20210621,0.250611,-1.234323,-1.079457,-1.057295,0.055816,0.904712,-1.558876,-0.696663,-0.666599,-1.530046 +353,353,20210621,1.637943,-1.234323,-1.079457,0.858557,-0.595102,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +354,354,20210621,-0.674276,0.810161,0.185828,0.858557,0.815221,0.014861,0.111736,0.138865,0.188746,0.234917 +355,355,20210621,-0.905498,-1.234323,1.451114,-1.057295,2.442516,1.794564,1.782348,1.809921,0.188746,0.234917 +356,356,20210621,0.096463,-1.234323,0.185828,-1.057295,1.032193,-0.874991,0.111736,0.138865,0.188746,0.234917 +357,357,20210621,0.558907,0.810161,0.185828,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +358,358,20210621,1.637943,-1.234323,0.185828,0.858557,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +359,359,20210621,-0.443054,0.810161,2.716399,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +360,360,20210621,0.713055,-1.234323,-1.079457,-1.057295,-0.161156,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +361,361,20210621,2.56283,0.810161,0.185828,0.858557,-1.354506,3.574267,2.617654,1.809921,0.188746,0.234917 +362,362,20210621,1.175499,0.810161,0.185828,0.858557,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +363,363,20210621,-0.905498,-1.234323,0.185828,0.858557,-0.378129,3.574267,2.617654,1.809921,0.188746,0.234917 +364,364,20210621,-0.443054,-1.234323,-1.079457,-1.057295,0.489762,0.904712,-1.558876,-0.696663,0.188746,-0.647565 +365,365,20210621,0.481833,0.810161,-1.079457,0.858557,-0.05267,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +366,366,20210621,1.252573,0.810161,0.185828,-1.057295,2.225543,0.904712,-0.72357,-0.696663,-1.521944,-0.647565 +367,367,20210621,-0.905498,0.810161,0.185828,-1.057295,2.767975,0.014861,0.111736,0.138865,0.188746,0.234917 +368,368,20210621,-1.213794,-1.234323,0.185828,0.858557,-1.24602,-0.874991,1.782348,1.809921,1.899436,0.234917 +369,369,20210621,1.021351,-1.234323,-1.079457,-1.057295,0.489762,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +370,370,20210621,-1.13672,0.810161,0.185828,-1.057295,-0.378129,2.684416,1.782348,0.138865,0.188746,0.234917 +371,371,20210621,0.096463,-1.234323,0.185828,-1.057295,0.055816,1.794564,1.782348,-1.532192,-1.521944,-1.530046 +372,372,20210621,-0.057685,-1.234323,-1.079457,0.858557,-0.595102,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +373,373,20210621,-0.597202,0.810161,-1.079457,0.858557,-0.161156,0.014861,0.111736,0.138865,1.899436,1.999879 +374,374,20210621,-1.059646,-1.234323,1.451114,2.77441,2.00857,0.014861,0.111736,0.138865,0.188746,0.234917 +375,375,20210621,0.096463,-1.234323,-1.079457,-1.057295,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +376,376,20210621,-1.059646,-1.234323,1.451114,-1.057295,2.442516,0.014861,0.111736,0.138865,0.188746,0.234917 +377,377,20210621,-1.059646,-1.234323,0.185828,-1.057295,0.815221,0.904712,1.782348,0.138865,0.188746,0.234917 +378,378,20210621,-0.211833,0.810161,-1.079457,0.858557,-0.812074,-0.874991,0.111736,0.138865,-0.666599,-0.647565 +379,379,20210621,0.327685,-1.234323,-1.079457,0.858557,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +380,380,20210621,-0.905498,-1.234323,0.185828,0.858557,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +381,381,20210621,-0.288907,0.810161,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +382,382,20210621,-0.905498,0.810161,0.185828,-1.057295,0.164303,1.794564,1.782348,1.809921,0.188746,0.234917 +383,383,20210621,-0.211833,-1.234323,1.451114,-1.057295,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +384,384,20210621,0.019389,0.810161,0.185828,0.858557,-0.812074,-0.874991,0.111736,0.138865,1.899436,0.234917 +385,385,20210621,-0.674276,-1.234323,0.185828,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +386,386,20210621,1.869164,0.810161,3.981685,-1.057295,0.706734,0.014861,0.111736,0.138865,0.188746,0.234917 +387,387,20210621,-0.674276,0.810161,-1.079457,0.858557,-0.703588,0.904712,-0.72357,-0.696663,-1.521944,-1.530046 +388,388,20210621,-0.674276,-1.234323,1.451114,-1.057295,4.069811,-0.874991,0.111736,0.138865,1.899436,1.999879 +389,389,20210621,-0.134759,-1.234323,0.185828,-1.057295,0.815221,0.014861,0.111736,0.138865,0.188746,0.234917 +390,390,20210621,0.713055,-1.234323,-1.079457,-1.057295,-0.595102,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +391,391,20210621,1.406721,-1.234323,-1.079457,-1.057295,0.272789,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +392,392,20210621,0.867203,0.810161,0.185828,-1.057295,0.381275,0.904712,-0.72357,0.138865,0.188746,0.234917 +393,393,20210621,1.098425,-1.234323,0.185828,-1.057295,0.923707,0.014861,0.111736,0.138865,0.188746,0.234917 +394,394,20210621,-0.211833,0.810161,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +395,395,20210621,1.483795,-1.234323,-1.079457,-1.057295,1.683111,-0.874991,-0.72357,-0.696663,-1.521944,-1.530046 +396,396,20210621,-0.211833,0.810161,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +397,397,20210621,-0.520128,-1.234323,-1.079457,0.858557,0.272789,0.014861,0.111736,0.138865,0.188746,0.234917 +398,398,20210621,-0.905498,0.810161,0.185828,0.858557,-1.462993,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +399,399,20210621,0.327685,0.810161,0.185828,-1.057295,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +400,400,20210621,-0.365981,0.810161,0.185828,0.858557,-1.137534,1.794564,1.782348,1.809921,1.899436,1.999879 +401,401,20210621,0.558907,-1.234323,-1.079457,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +402,402,20210621,-0.828424,0.810161,1.451114,2.77441,0.706734,0.014861,0.111736,0.138865,0.188746,0.234917 +403,403,20210621,-0.134759,-1.234323,-1.079457,0.858557,0.598248,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +404,404,20210621,-1.059646,-1.234323,0.185828,-1.057295,1.357652,0.014861,0.111736,0.138865,0.188746,0.234917 +405,405,20210621,-0.057685,0.810161,-1.079457,0.858557,-0.703588,1.794564,1.782348,1.809921,1.899436,1.999879 +406,406,20210621,0.250611,-1.234323,-1.079457,-1.057295,1.791598,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +407,407,20210621,-0.365981,0.810161,0.185828,-1.057295,-1.137534,0.014861,0.111736,0.138865,-1.521944,-1.530046 +408,408,20210621,2.56283,-1.234323,-1.079457,-1.057295,0.164303,0.904712,1.782348,0.138865,0.188746,0.234917 +409,409,20210621,1.175499,0.810161,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +410,410,20210621,0.867203,-1.234323,-1.079457,0.858557,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +411,411,20210621,-0.828424,0.810161,-1.079457,0.858557,-1.354506,0.904712,1.782348,1.809921,1.899436,1.999879 +412,412,20210621,0.250611,0.810161,-1.079457,-1.057295,0.272789,-0.874991,-0.72357,-1.532192,-0.666599,-0.647565 +413,413,20210621,0.481833,0.810161,-1.079457,-1.057295,-0.378129,0.904712,-1.558876,-0.696663,-0.666599,-0.647565 +414,414,20210621,0.481833,0.810161,0.185828,0.858557,-0.920561,0.904712,1.782348,0.138865,0.188746,0.234917 +415,415,20210621,2.408682,0.810161,1.451114,-1.057295,0.598248,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +416,416,20210621,-0.905498,0.810161,1.451114,-1.057295,-0.05267,-0.874991,-0.72357,-0.696663,-1.521944,-1.530046 +417,417,20210621,0.250611,0.810161,-1.079457,0.858557,-0.486615,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +418,418,20210621,-0.905498,0.810161,-1.079457,0.858557,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +419,419,20210621,-0.905498,-1.234323,0.185828,-1.057295,1.357652,0.014861,0.111736,0.138865,0.188746,0.234917 +420,420,20210621,0.713055,0.810161,-1.079457,0.858557,0.055816,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +421,421,20210621,-1.059646,-1.234323,-1.079457,0.858557,-1.24602,1.794564,0.111736,0.138865,0.188746,0.234917 +422,422,20210621,2.100386,0.810161,-1.079457,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +423,423,20210621,0.481833,0.810161,0.185828,0.858557,0.272789,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +424,424,20210621,0.250611,-1.234323,0.185828,-1.057295,0.272789,1.794564,1.782348,1.809921,0.188746,0.234917 +425,425,20210621,2.485756,0.810161,0.185828,-1.057295,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +426,426,20210621,-0.674276,0.810161,0.185828,-1.057295,-0.378129,-0.874991,-0.72357,-1.532192,-1.521944,-1.530046 +427,427,20210621,-1.13672,0.810161,1.451114,0.858557,1.466139,1.794564,1.782348,1.809921,1.899436,0.234917 +428,428,20210621,0.019389,0.810161,-1.079457,0.858557,-0.486615,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +429,429,20210621,-0.75135,-1.234323,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +430,430,20210621,0.327685,0.810161,0.185828,0.858557,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +431,431,20210621,-0.597202,0.810161,0.185828,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +432,432,20210621,1.715017,0.810161,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +433,433,20210621,-0.443054,0.810161,-1.079457,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +434,434,20210621,3.179422,0.810161,-1.079457,-1.057295,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +435,435,20210621,1.483795,-1.234323,1.451114,-1.057295,2.117057,0.014861,0.111736,-0.696663,-0.666599,-0.647565 +436,436,20210621,0.790129,0.810161,0.185828,-1.057295,-0.378129,0.904712,1.782348,1.809921,1.899436,1.999879 +437,437,20210621,-0.828424,0.810161,-1.079457,0.858557,-0.920561,-0.874991,-0.72357,-1.532192,-0.666599,1.999879 +438,438,20210621,-0.443054,-1.234323,1.451114,-1.057295,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +439,439,20210621,-0.905498,0.810161,-1.079457,-1.057295,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +440,440,20210621,-0.674276,0.810161,-1.079457,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +441,441,20210621,-0.905498,-1.234323,0.185828,0.858557,-1.354506,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +442,442,20210621,-0.520128,-1.234323,-1.079457,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,1.999879 +443,443,20210621,-1.059646,0.810161,-1.079457,0.858557,-1.029047,0.904712,-1.558876,-0.696663,-0.666599,-0.647565 +444,444,20210621,0.250611,0.810161,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +445,445,20210621,0.558907,-1.234323,-1.079457,0.858557,0.923707,0.014861,0.111736,0.138865,0.188746,0.234917 +446,446,20210621,0.404759,-1.234323,0.185828,0.858557,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +447,447,20210621,-0.057685,0.810161,-1.079457,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +448,448,20210621,0.096463,0.810161,-1.079457,-1.057295,1.900084,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +449,449,20210621,0.250611,-1.234323,2.716399,-1.057295,0.706734,0.014861,0.111736,0.138865,0.188746,0.234917 +450,450,20210621,-0.211833,0.810161,1.451114,-1.057295,-0.595102,0.014861,0.111736,0.138865,1.899436,0.234917 +451,451,20210621,1.637943,-1.234323,-1.079457,-1.057295,1.683111,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +452,452,20210621,3.33357,-1.234323,-1.079457,-1.057295,1.900084,1.794564,1.782348,0.138865,0.188746,0.234917 +453,453,20210621,0.713055,-1.234323,0.185828,0.858557,0.164303,0.014861,0.111736,0.138865,-0.666599,0.234917 +454,454,20210621,0.250611,0.810161,-1.079457,0.858557,-1.029047,0.014861,0.111736,-1.532192,-1.521944,-1.530046 +455,455,20210621,-0.674276,-1.234323,0.185828,0.858557,0.706734,0.014861,0.111736,0.138865,0.188746,0.234917 +456,456,20210621,-0.982572,-1.234323,0.185828,0.858557,0.381275,0.014861,0.111736,0.138865,0.188746,0.234917 +457,457,20210621,-0.288907,-1.234323,1.451114,0.858557,0.381275,0.904712,1.782348,1.809921,1.899436,1.999879 +458,458,20210621,-0.905498,-1.234323,-1.079457,0.858557,-0.378129,-0.874991,0.111736,0.138865,0.188746,0.234917 +459,459,20210621,0.481833,0.810161,0.185828,-1.057295,0.598248,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +460,460,20210621,-0.75135,-1.234323,0.185828,-1.057295,1.357652,0.014861,0.111736,0.138865,0.188746,0.234917 +461,461,20210621,0.096463,0.810161,0.185828,-1.057295,0.272789,0.014861,0.111736,0.138865,0.188746,0.234917 +462,462,20210621,-0.674276,0.810161,0.185828,-1.057295,0.055816,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +463,463,20210621,0.944277,0.810161,0.185828,0.858557,-1.029047,0.014861,0.111736,0.138865,-0.666599,-0.647565 +464,464,20210621,0.481833,0.810161,-1.079457,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +465,465,20210621,0.019389,0.810161,1.451114,2.77441,2.225543,0.904712,-1.558876,-0.696663,-0.666599,-1.530046 +466,466,20210621,0.481833,-1.234323,-1.079457,-1.057295,2.551002,-0.874991,0.111736,0.138865,0.188746,0.234917 +467,467,20210621,0.404759,-1.234323,-1.079457,0.858557,0.272789,0.014861,0.111736,0.138865,0.188746,0.234917 +468,468,20210621,0.481833,-1.234323,0.185828,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +469,469,20210621,2.56283,-1.234323,0.185828,-1.057295,0.272789,0.014861,0.111736,0.138865,-0.666599,0.234917 +470,470,20210621,-0.597202,0.810161,-1.079457,-1.057295,0.598248,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +471,471,20210621,1.715017,0.810161,1.451114,0.858557,-0.05267,0.014861,0.111736,0.138865,0.188746,0.234917 +472,472,20210621,1.792091,0.810161,0.185828,0.858557,0.598248,0.014861,0.111736,0.138865,0.188746,0.234917 +473,473,20210621,0.096463,-1.234323,0.185828,-1.057295,-0.161156,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +474,474,20210621,-0.828424,-1.234323,1.451114,-1.057295,0.272789,0.904712,1.782348,1.809921,0.188746,0.234917 +475,475,20210621,-0.365981,0.810161,0.185828,-1.057295,-0.378129,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +476,476,20210621,-0.828424,0.810161,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +477,477,20210621,-0.905498,-1.234323,-1.079457,0.858557,0.923707,0.014861,0.111736,0.138865,0.188746,0.234917 +478,478,20210621,-0.75135,0.810161,0.185828,-1.057295,0.164303,0.014861,0.111736,0.138865,1.899436,0.234917 +479,479,20210621,2.56283,0.810161,-1.079457,-1.057295,0.272789,-0.874991,1.782348,-0.696663,-0.666599,-0.647565 +480,480,20210621,0.250611,-1.234323,-1.079457,0.858557,-0.486615,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +481,481,20210621,0.635981,0.810161,0.185828,-1.057295,0.489762,0.014861,0.111736,0.138865,0.188746,-0.647565 +482,482,20210621,-0.211833,-1.234323,0.185828,0.858557,-1.029047,0.014861,0.111736,1.809921,1.899436,1.999879 +483,483,20210621,-0.75135,0.810161,0.185828,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,-0.647565 +484,484,20210621,-0.597202,-1.234323,1.451114,-1.057295,1.357652,0.904712,1.782348,1.809921,1.899436,1.999879 +485,485,20210621,-0.520128,0.810161,0.185828,-1.057295,0.815221,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +486,486,20210621,0.173537,-1.234323,0.185828,-1.057295,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +487,487,20210621,0.481833,0.810161,-1.079457,-1.057295,0.706734,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +488,488,20210621,1.175499,-1.234323,0.185828,-1.057295,0.381275,0.014861,0.111736,0.138865,0.188746,0.234917 +489,489,20210621,0.404759,0.810161,0.185828,-1.057295,0.055816,-0.874991,-0.72357,-0.696663,0.188746,-0.647565 +490,490,20210621,0.713055,0.810161,-1.079457,-1.057295,-0.161156,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +491,491,20210621,-0.597202,0.810161,0.185828,0.858557,-0.378129,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +492,492,20210621,-1.059646,0.810161,0.185828,-1.057295,0.815221,1.794564,1.782348,1.809921,1.899436,1.999879 +493,493,20210621,0.713055,-1.234323,0.185828,0.858557,-0.595102,0.014861,0.111736,0.138865,1.899436,0.234917 +494,494,20210621,0.019389,0.810161,0.185828,0.858557,-0.812074,0.014861,0.111736,-0.696663,-0.666599,-1.530046 +495,495,20210621,-0.674276,0.810161,-1.079457,-1.057295,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +496,496,20210621,-0.905498,-1.234323,-1.079457,-1.057295,0.598248,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +497,497,20210621,0.250611,0.810161,1.451114,0.858557,1.249166,0.014861,0.111736,0.138865,0.188746,0.234917 +498,498,20210621,-1.13672,-1.234323,0.185828,0.858557,-1.354506,0.014861,0.111736,1.809921,0.188746,0.234917 +499,499,20210621,0.635981,0.810161,-1.079457,-1.057295,1.466139,-0.874991,-0.72357,-1.532192,-0.666599,-0.647565 +500,500,20210621,-1.13672,-1.234323,-1.079457,-1.057295,0.272789,0.014861,0.111736,0.138865,1.899436,1.999879 +501,501,20210621,-1.059646,0.810161,0.185828,-1.057295,0.272789,0.014861,0.111736,0.138865,0.188746,1.999879 +502,502,20210621,-0.597202,0.810161,0.185828,-1.057295,-0.05267,0.904712,1.782348,1.809921,1.899436,1.999879 +503,503,20210621,0.481833,0.810161,5.24697,0.858557,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +504,504,20210621,-0.288907,0.810161,-1.079457,-1.057295,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +505,505,20210621,-1.059646,-1.234323,5.24697,-1.057295,1.900084,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +506,506,20210621,-0.057685,-1.234323,-1.079457,0.858557,-0.05267,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +507,507,20210621,2.56283,0.810161,0.185828,0.858557,0.815221,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +508,508,20210621,0.096463,0.810161,0.185828,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +509,509,20210621,-0.674276,0.810161,0.185828,-1.057295,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +510,510,20210621,-0.365981,-1.234323,-1.079457,0.858557,-1.029047,-0.874991,-0.72357,-1.532192,-0.666599,-0.647565 +511,511,20210621,-0.288907,-1.234323,0.185828,-1.057295,-0.486615,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +512,512,20210621,-0.365981,0.810161,0.185828,0.858557,-0.05267,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +513,513,20210621,1.483795,-1.234323,-1.079457,0.858557,-0.812074,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +514,514,20210621,-0.905498,-1.234323,0.185828,0.858557,-1.354506,1.794564,1.782348,1.809921,1.899436,1.999879 +515,515,20210621,-1.13672,0.810161,0.185828,0.858557,-1.354506,0.014861,0.111736,1.809921,0.188746,0.234917 +516,516,20210621,-0.520128,-1.234323,1.451114,-1.057295,2.225543,0.014861,0.111736,-0.696663,0.188746,0.234917 +517,517,20210621,-0.75135,-1.234323,1.451114,-1.057295,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +518,518,20210621,-0.905498,-1.234323,0.185828,-1.057295,1.249166,0.014861,0.111736,0.138865,0.188746,0.234917 +519,519,20210621,-1.213794,0.810161,0.185828,0.858557,-1.462993,0.904712,1.782348,0.138865,0.188746,0.234917 +520,520,20210621,0.944277,0.810161,-1.079457,-1.057295,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +521,521,20210621,-1.059646,0.810161,-1.079457,-1.057295,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +522,522,20210621,1.869164,0.810161,0.185828,0.858557,-0.920561,0.904712,-0.72357,0.138865,0.188746,0.234917 +523,523,20210621,1.483795,-1.234323,-1.079457,0.858557,-0.812074,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +524,524,20210621,-0.211833,0.810161,0.185828,-1.057295,0.706734,0.014861,0.111736,0.138865,0.188746,0.234917 +525,525,20210621,0.327685,0.810161,-1.079457,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +526,526,20210621,0.404759,0.810161,0.185828,0.858557,-0.920561,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +527,527,20210621,-1.13672,-1.234323,0.185828,0.858557,-0.920561,0.904712,1.782348,0.138865,0.188746,0.234917 +528,528,20210621,3.487718,0.810161,0.185828,-1.057295,1.032193,1.794564,1.782348,0.138865,0.188746,0.234917 +529,529,20210621,1.483795,-1.234323,-1.079457,0.858557,-1.029047,0.904712,-1.558876,-1.532192,-1.521944,-0.647565 +530,530,20210621,-1.13672,0.810161,0.185828,0.858557,-1.571479,-0.874991,-0.72357,1.809921,1.899436,-0.647565 +531,531,20210621,-0.905498,-1.234323,0.185828,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +532,532,20210621,-0.905498,-1.234323,0.185828,2.77441,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +533,533,20210621,-1.213794,-1.234323,0.185828,0.858557,1.14068,0.014861,0.111736,1.809921,1.899436,1.999879 +534,534,20210621,-0.520128,0.810161,1.451114,-1.057295,1.574625,1.794564,0.111736,0.138865,2.754781,2.88236 +535,535,20210621,-0.905498,-1.234323,-1.079457,0.858557,-1.029047,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +536,536,20210621,-0.828424,-1.234323,0.185828,0.858557,-1.137534,-0.874991,-0.72357,0.138865,-0.666599,-0.647565 +537,537,20210621,2.100386,0.810161,-1.079457,0.858557,-0.05267,0.014861,0.111736,0.138865,0.188746,0.234917 +538,538,20210621,-0.365981,-1.234323,0.185828,-1.057295,0.923707,0.014861,0.111736,0.138865,0.188746,0.234917 +539,539,20210621,-0.905498,0.810161,-1.079457,0.858557,1.791598,0.014861,0.111736,0.138865,-1.521944,-0.647565 +540,540,20210621,-0.443054,0.810161,0.185828,-1.057295,0.489762,0.904712,1.782348,1.809921,1.899436,1.999879 +541,541,20210621,0.250611,0.810161,-1.079457,0.858557,0.272789,-0.874991,-0.72357,-1.532192,-1.521944,-0.647565 +542,542,20210621,-0.134759,0.810161,-1.079457,0.858557,-0.812074,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +543,543,20210621,-1.059646,0.810161,0.185828,-1.057295,0.055816,1.794564,2.617654,1.809921,1.899436,0.234917 +544,544,20210621,-0.520128,0.810161,-1.079457,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,-0.647565 +545,545,20210621,1.483795,0.810161,-1.079457,-1.057295,-0.161156,-0.874991,0.111736,0.138865,-0.666599,0.234917 +546,546,20210621,1.715017,0.810161,-1.079457,0.858557,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +547,547,20210621,0.404759,0.810161,-1.079457,-1.057295,0.598248,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +548,548,20210621,-0.057685,0.810161,0.185828,0.858557,-1.137534,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +549,549,20210621,0.481833,0.810161,-1.079457,0.858557,-0.812074,-0.874991,-0.72357,0.138865,0.188746,0.234917 +550,550,20210621,-0.365981,-1.234323,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +551,551,20210621,-0.520128,-1.234323,1.451114,-1.057295,1.791598,0.014861,0.111736,1.809921,1.899436,1.999879 +552,552,20210621,0.173537,0.810161,-1.079457,0.858557,0.598248,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +553,553,20210621,-0.905498,-1.234323,-1.079457,-1.057295,2.225543,0.014861,0.111736,0.138865,0.188746,0.234917 +554,554,20210621,0.558907,0.810161,-1.079457,-1.057295,0.706734,0.904712,-0.72357,-0.696663,-1.521944,-1.530046 +555,555,20210621,-0.982572,0.810161,0.185828,0.858557,-1.24602,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +556,556,20210621,3.564792,0.810161,0.185828,-1.057295,1.249166,0.014861,0.111736,0.138865,-0.666599,-0.647565 +557,557,20210621,-0.057685,0.810161,-1.079457,-1.057295,-0.269643,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +558,558,20210621,-0.443054,0.810161,0.185828,0.858557,-0.378129,0.014861,0.111736,1.809921,1.899436,1.999879 +559,559,20210621,-1.13672,-1.234323,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,-1.521944,-1.530046 +560,560,20210621,0.327685,0.810161,1.451114,-1.057295,1.900084,0.014861,0.111736,0.138865,0.188746,0.234917 +561,561,20210621,0.790129,-1.234323,-1.079457,0.858557,-0.161156,-0.874991,-0.72357,0.138865,-0.666599,-0.647565 +562,562,20210621,1.483795,0.810161,0.185828,0.858557,1.791598,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +563,563,20210621,-0.828424,0.810161,0.185828,-1.057295,0.706734,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +564,564,20210621,1.483795,-1.234323,0.185828,0.858557,0.272789,-0.874991,0.111736,0.138865,0.188746,0.234917 +565,565,20210621,1.715017,0.810161,-1.079457,0.858557,1.032193,1.794564,1.782348,1.809921,-0.666599,1.999879 +566,566,20210621,0.635981,0.810161,1.451114,0.858557,-0.05267,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +567,567,20210621,-0.597202,0.810161,-1.079457,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +568,568,20210621,1.483795,-1.234323,-1.079457,0.858557,-0.812074,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +569,569,20210621,-0.905498,-1.234323,1.451114,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +570,570,20210621,0.790129,0.810161,-1.079457,-1.057295,0.489762,0.014861,0.111736,0.138865,-1.521944,-1.530046 +571,571,20210621,0.250611,0.810161,-1.079457,0.858557,-0.703588,0.904712,-0.72357,-0.696663,-0.666599,-0.647565 +572,572,20210621,-0.905498,0.810161,0.185828,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +573,573,20210621,1.406721,-1.234323,-1.079457,0.858557,-0.269643,-0.874991,-0.72357,-0.696663,-1.521944,-1.530046 +574,574,20210621,-0.057685,0.810161,0.185828,0.858557,2.659488,-1.764843,-0.72357,-0.696663,0.188746,-0.647565 +575,575,20210621,-0.674276,0.810161,1.451114,-1.057295,1.466139,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +576,576,20210621,0.944277,-1.234323,-1.079457,-1.057295,1.900084,1.794564,0.111736,0.138865,0.188746,0.234917 +577,577,20210621,0.790129,0.810161,-1.079457,0.858557,-0.812074,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +578,578,20210621,-0.674276,-1.234323,-1.079457,0.858557,-0.486615,-0.874991,-0.72357,-0.696663,-0.666599,1.999879 +579,579,20210621,-0.905498,-1.234323,0.185828,0.858557,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +580,580,20210621,-1.059646,-1.234323,0.185828,-1.057295,-0.05267,-1.764843,-0.72357,-0.696663,-0.666599,-0.647565 +581,581,20210621,-1.059646,-1.234323,0.185828,0.858557,-0.812074,0.904712,-0.72357,-0.696663,-1.521944,-1.530046 +582,582,20210621,-0.597202,-1.234323,0.185828,0.858557,-0.269643,-0.874991,0.111736,0.138865,0.188746,0.234917 +583,583,20210621,-0.057685,-1.234323,-1.079457,0.858557,-1.029047,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +584,584,20210621,-0.674276,0.810161,1.451114,0.858557,1.900084,0.014861,0.111736,0.138865,0.188746,0.234917 +585,585,20210621,-0.905498,-1.234323,0.185828,0.858557,0.706734,0.014861,0.111736,0.138865,0.188746,0.234917 +586,586,20210621,-1.13672,0.810161,-1.079457,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +587,587,20210621,0.404759,-1.234323,-1.079457,-1.057295,0.815221,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +588,588,20210621,0.327685,-1.234323,1.451114,0.858557,-1.137534,-0.874991,-0.72357,1.809921,-0.666599,-0.647565 +589,589,20210621,-0.288907,0.810161,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +590,590,20210621,0.713055,0.810161,0.185828,-1.057295,-0.486615,-0.874991,-0.72357,0.138865,0.188746,-0.647565 +591,591,20210621,0.481833,0.810161,-1.079457,-1.057295,-0.595102,0.014861,0.111736,0.138865,-0.666599,0.234917 +592,592,20210621,-0.057685,-1.234323,-1.079457,0.858557,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +593,593,20210621,-0.905498,-1.234323,-1.079457,-1.057295,-0.05267,0.014861,0.111736,0.138865,0.188746,0.234917 +594,594,20210621,-0.674276,-1.234323,0.185828,-1.057295,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +595,595,20210621,-0.443054,-1.234323,1.451114,0.858557,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +596,596,20210621,0.250611,-1.234323,-1.079457,-1.057295,0.815221,0.014861,0.111736,0.138865,0.188746,0.234917 +597,597,20210621,1.483795,-1.234323,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +598,598,20210621,0.327685,0.810161,1.451114,0.858557,-0.486615,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +599,599,20210621,-0.674276,0.810161,0.185828,0.858557,-1.24602,1.794564,0.111736,0.138865,0.188746,0.234917 +600,600,20210621,1.021351,0.810161,0.185828,-1.057295,0.055816,-0.874991,-0.72357,1.809921,0.188746,-0.647565 +601,601,20210621,1.098425,0.810161,0.185828,-1.057295,0.815221,0.014861,0.111736,0.138865,0.188746,0.234917 +602,602,20210621,-1.059646,-1.234323,1.451114,-1.057295,2.551002,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +603,603,20210621,0.019389,-1.234323,-1.079457,-1.057295,1.900084,0.014861,0.111736,0.138865,0.188746,0.234917 +604,604,20210621,-0.211833,0.810161,0.185828,0.858557,-0.812074,1.794564,1.782348,1.809921,0.188746,0.234917 +605,605,20210621,0.096463,0.810161,0.185828,0.858557,-0.486615,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +606,606,20210621,-0.905498,-1.234323,-1.079457,0.858557,-0.161156,0.904712,1.782348,1.809921,1.899436,1.999879 +607,607,20210621,-0.905498,0.810161,0.185828,-1.057295,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +608,608,20210621,-0.443054,0.810161,-1.079457,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,1.999879 +609,609,20210621,2.17746,0.810161,1.451114,-1.057295,0.055816,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +610,610,20210621,0.250611,0.810161,0.185828,-1.057295,-0.161156,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +611,611,20210621,0.404759,-1.234323,-1.079457,0.858557,0.815221,0.014861,0.111736,-0.696663,-0.666599,-0.647565 +612,612,20210621,1.483795,0.810161,-1.079457,0.858557,-0.703588,0.014861,0.111736,-1.532192,-1.521944,-1.530046 +613,613,20210621,-0.905498,-1.234323,0.185828,-1.057295,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +614,614,20210621,-0.982572,-1.234323,0.185828,0.858557,-1.354506,1.794564,1.782348,0.138865,0.188746,0.234917 +615,615,20210621,0.173537,0.810161,0.185828,-1.057295,0.164303,0.904712,1.782348,1.809921,1.899436,1.999879 +616,616,20210621,-0.134759,-1.234323,-1.079457,0.858557,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +617,617,20210621,0.250611,0.810161,-1.079457,-1.057295,0.164303,0.904712,-1.558876,-1.532192,-1.521944,-0.647565 +618,618,20210621,0.790129,0.810161,0.185828,-1.057295,2.225543,0.014861,0.111736,0.138865,0.188746,0.234917 +619,619,20210621,-0.828424,-1.234323,-1.079457,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +620,620,20210621,0.250611,0.810161,0.185828,-1.057295,0.381275,0.014861,0.111736,0.138865,0.188746,0.234917 +621,621,20210621,-0.134759,0.810161,0.185828,-1.057295,0.381275,0.014861,0.111736,0.138865,0.188746,0.234917 +622,622,20210621,0.096463,0.810161,0.185828,0.858557,-0.812074,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +623,623,20210621,-0.597202,0.810161,-1.079457,0.858557,-0.920561,0.014861,0.111736,-1.532192,-1.521944,-1.530046 +624,624,20210621,1.483795,0.810161,0.185828,-1.057295,0.164303,0.904712,-1.558876,-1.532192,-1.521944,-0.647565 +625,625,20210621,-0.597202,0.810161,-1.079457,0.858557,-1.24602,-0.874991,-0.72357,-1.532192,-1.521944,-1.530046 +626,626,20210621,-1.13672,0.810161,0.185828,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,1.999879 +627,627,20210621,-0.75135,-1.234323,-1.079457,-1.057295,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +628,628,20210621,0.481833,-1.234323,-1.079457,-1.057295,0.381275,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +629,629,20210621,-1.059646,-1.234323,1.451114,-1.057295,1.357652,0.014861,0.111736,0.138865,0.188746,0.234917 +630,630,20210621,0.250611,0.810161,1.451114,2.77441,1.032193,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +631,631,20210621,-0.520128,-1.234323,1.451114,0.858557,1.466139,-0.874991,-0.72357,-1.532192,-1.521944,-1.530046 +632,632,20210621,-0.905498,0.810161,0.185828,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +633,633,20210621,-1.13672,0.810161,1.451114,-1.057295,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +634,634,20210621,0.327685,0.810161,0.185828,-1.057295,1.249166,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +635,635,20210621,-0.443054,-1.234323,1.451114,-1.057295,2.225543,0.014861,0.111736,0.138865,0.188746,0.234917 +636,636,20210621,-1.13672,0.810161,1.451114,-1.057295,0.923707,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +637,637,20210621,-0.905498,0.810161,1.451114,-1.057295,1.466139,0.014861,0.111736,0.138865,0.188746,0.234917 +638,638,20210621,-0.905498,-1.234323,0.185828,-1.057295,0.598248,0.014861,0.111736,0.138865,0.188746,0.234917 +639,639,20210621,1.792091,0.810161,-1.079457,0.858557,0.489762,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +640,640,20210621,0.019389,-1.234323,0.185828,0.858557,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +641,641,20210621,0.867203,-1.234323,0.185828,-1.057295,0.706734,0.014861,0.111736,0.138865,0.188746,0.234917 +642,642,20210621,-0.288907,0.810161,1.451114,-1.057295,-0.812074,0.014861,0.111736,0.138865,0.188746,-1.530046 +643,643,20210621,0.327685,0.810161,0.185828,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +644,644,20210621,1.560869,-1.234323,0.185828,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +645,645,20210621,-1.059646,0.810161,0.185828,-1.057295,-0.486615,0.014861,0.111736,1.809921,0.188746,0.234917 +646,646,20210621,-0.134759,-1.234323,1.451114,0.858557,0.381275,0.904712,-0.72357,-0.696663,-1.521944,-1.530046 +647,647,20210621,-0.828424,-1.234323,1.451114,-1.057295,-0.486615,1.794564,0.111736,0.138865,-1.521944,-1.530046 +648,648,20210621,-0.674276,0.810161,0.185828,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +649,649,20210621,0.867203,0.810161,0.185828,-1.057295,0.923707,1.794564,1.782348,1.809921,1.899436,1.999879 +650,650,20210621,-1.13672,0.810161,0.185828,0.858557,1.14068,7.133674,5.958878,5.152034,4.46547,3.764842 +651,651,20210621,0.790129,-1.234323,-1.079457,0.858557,-0.378129,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +652,652,20210621,0.558907,0.810161,0.185828,0.858557,-1.029047,0.014861,0.111736,-0.696663,-0.666599,-0.647565 +653,653,20210621,-1.13672,0.810161,-1.079457,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +654,654,20210621,2.17746,0.810161,-1.079457,-1.057295,0.706734,0.904712,-1.558876,-1.532192,-0.666599,-0.647565 +655,655,20210621,-1.213794,-1.234323,0.185828,0.858557,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +656,656,20210621,0.867203,-1.234323,0.185828,-1.057295,0.381275,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +657,657,20210621,0.944277,0.810161,1.451114,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,-0.647565 +658,658,20210621,0.173537,0.810161,-1.079457,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +659,659,20210621,-0.674276,0.810161,-1.079457,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +660,660,20210621,0.867203,0.810161,0.185828,0.858557,-0.812074,-0.874991,1.782348,-0.696663,-0.666599,0.234917 +661,661,20210621,-0.057685,0.810161,-1.079457,-1.057295,-0.269643,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +662,662,20210621,-0.597202,-1.234323,0.185828,-1.057295,0.489762,0.014861,0.111736,0.138865,-0.666599,-0.647565 +663,663,20210621,-0.211833,0.810161,-1.079457,0.858557,0.164303,-0.874991,-0.72357,-0.696663,-1.521944,-1.530046 +664,664,20210621,-0.905498,-1.234323,-1.079457,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +665,665,20210621,-0.982572,0.810161,0.185828,-1.057295,-0.378129,0.014861,0.111736,0.138865,1.899436,1.999879 +666,666,20210621,-0.288907,0.810161,1.451114,-1.057295,0.815221,0.014861,0.111736,0.138865,0.188746,0.234917 +667,667,20210621,-0.75135,0.810161,1.451114,-1.057295,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +668,668,20210621,-1.059646,0.810161,0.185828,-1.057295,-0.05267,0.014861,0.111736,0.138865,0.188746,0.234917 +669,669,20210621,-0.520128,0.810161,1.451114,-1.057295,-0.05267,0.904712,1.782348,1.809921,1.899436,1.999879 +670,670,20210621,-1.13672,0.810161,-1.079457,-1.057295,-0.595102,1.794564,1.782348,1.809921,0.188746,0.234917 +671,671,20210621,-1.059646,0.810161,0.185828,0.858557,-0.161156,1.794564,-0.72357,1.809921,1.899436,1.999879 +672,672,20210621,-1.13672,-1.234323,0.185828,-1.057295,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +673,673,20210621,-0.520128,0.810161,-1.079457,0.858557,-0.812074,1.794564,0.111736,0.138865,0.188746,0.234917 +674,674,20210621,-1.059646,-1.234323,0.185828,0.858557,-1.137534,1.794564,1.782348,5.987563,6.17616,6.412285 +675,675,20210621,1.175499,0.810161,-1.079457,-1.057295,0.598248,0.014861,0.111736,0.138865,0.188746,0.234917 +676,676,20210621,-0.597202,-1.234323,1.451114,0.858557,0.706734,1.794564,1.782348,1.809921,1.899436,1.999879 +677,677,20210621,0.173537,-1.234323,0.185828,0.858557,0.489762,1.794564,1.782348,1.809921,1.899436,1.999879 +678,678,20210621,0.250611,-1.234323,-1.079457,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +679,679,20210621,1.021351,0.810161,0.185828,0.858557,-0.486615,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +680,680,20210621,-1.059646,0.810161,-1.079457,0.858557,2.225543,-0.874991,0.111736,0.138865,-1.521944,-1.530046 +681,681,20210621,-0.443054,0.810161,0.185828,2.77441,1.032193,0.014861,0.111736,0.138865,0.188746,0.234917 +682,682,20210621,0.481833,0.810161,-1.079457,0.858557,-0.703588,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +683,683,20210621,0.481833,0.810161,-1.079457,-1.057295,-0.05267,0.014861,0.111736,0.138865,0.188746,-1.530046 +684,684,20210621,1.098425,0.810161,0.185828,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +685,685,20210621,1.175499,-1.234323,-1.079457,-1.057295,0.489762,0.014861,0.111736,0.138865,0.188746,0.234917 +686,686,20210621,1.483795,-1.234323,-1.079457,-1.057295,1.249166,-0.874991,-0.72357,-0.696663,0.188746,-0.647565 +687,687,20210621,-1.13672,0.810161,1.451114,-1.057295,0.598248,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +688,688,20210621,0.019389,0.810161,0.185828,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +689,689,20210621,-0.211833,-1.234323,-1.079457,-1.057295,0.489762,0.014861,0.111736,0.138865,0.188746,0.234917 +690,690,20210621,-0.674276,-1.234323,0.185828,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +691,691,20210621,-0.134759,-1.234323,0.185828,0.858557,-0.05267,0.014861,0.111736,0.138865,-0.666599,-0.647565 +692,692,20210621,0.019389,-1.234323,0.185828,0.858557,-0.920561,-0.874991,1.782348,1.809921,-1.521944,-1.530046 +693,693,20210621,0.250611,0.810161,0.185828,-1.057295,-0.703588,1.794564,0.111736,0.138865,0.188746,0.234917 +694,694,20210621,-0.75135,-1.234323,-1.079457,0.858557,-0.595102,0.014861,0.111736,1.809921,0.188746,0.234917 +695,695,20210621,1.175499,-1.234323,0.185828,-1.057295,0.164303,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +696,696,20210621,-0.134759,0.810161,-1.079457,0.858557,-0.703588,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +697,697,20210621,-0.905498,0.810161,-1.079457,-1.057295,-0.161156,0.014861,0.111736,0.138865,-0.666599,0.234917 +698,698,20210621,-0.597202,0.810161,0.185828,0.858557,-0.161156,-0.874991,1.782348,1.809921,-1.521944,-1.530046 +699,699,20210621,0.867203,-1.234323,-1.079457,-1.057295,0.598248,-1.764843,-1.558876,-1.532192,-1.521944,-0.647565 +700,700,20210621,1.021351,0.810161,-1.079457,0.858557,-0.486615,0.014861,0.111736,0.138865,0.188746,1.999879 +701,701,20210621,1.792091,0.810161,0.185828,0.858557,0.489762,-1.764843,-1.558876,-1.532192,-1.521944,-0.647565 +702,702,20210621,0.250611,0.810161,-1.079457,-1.057295,-0.920561,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +703,703,20210621,-1.213794,0.810161,1.451114,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,-1.530046 +704,704,20210621,-0.905498,0.810161,0.185828,2.77441,-0.595102,0.904712,2.617654,1.809921,0.188746,0.234917 +705,705,20210621,-1.059646,0.810161,0.185828,2.77441,-1.462993,0.904712,1.782348,3.480978,2.754781,1.999879 +706,706,20210621,-0.905498,-1.234323,-1.079457,0.858557,-1.029047,-0.874991,0.111736,0.138865,0.188746,0.234917 +707,707,20210621,-0.905498,-1.234323,0.185828,-1.057295,0.272789,0.904712,1.782348,0.138865,0.188746,0.234917 +708,708,20210621,-1.059646,0.810161,1.451114,-1.057295,1.14068,0.904712,1.782348,1.809921,1.899436,1.999879 +709,709,20210621,-1.13672,-1.234323,0.185828,0.858557,-1.24602,0.014861,0.111736,-0.696663,1.899436,0.234917 +710,710,20210621,-1.13672,-1.234323,0.185828,0.858557,1.466139,0.014861,0.111736,0.138865,0.188746,0.234917 +711,711,20210621,-0.905498,-1.234323,-1.079457,2.77441,1.466139,0.014861,0.111736,0.138865,0.188746,0.234917 +712,712,20210621,-1.059646,0.810161,0.185828,-1.057295,0.706734,0.014861,0.111736,0.138865,0.188746,0.234917 +713,713,20210621,1.483795,0.810161,-1.079457,-1.057295,-0.595102,0.904712,1.782348,-0.696663,0.188746,-0.647565 +714,714,20210621,0.019389,-1.234323,0.185828,-1.057295,0.706734,0.904712,-0.72357,-0.696663,-1.521944,-1.530046 +715,715,20210621,1.792091,0.810161,-1.079457,0.858557,-0.486615,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +716,716,20210621,-0.905498,0.810161,0.185828,-1.057295,1.466139,0.014861,0.111736,0.138865,0.188746,0.234917 +717,717,20210621,-0.057685,0.810161,0.185828,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +718,718,20210621,-0.75135,0.810161,0.185828,-1.057295,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +719,719,20210621,-0.134759,0.810161,-1.079457,-1.057295,-0.05267,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +720,720,20210621,-0.674276,0.810161,0.185828,0.858557,1.357652,0.014861,0.111736,0.138865,0.188746,0.234917 +721,721,20210621,-1.059646,0.810161,0.185828,0.858557,-1.462993,0.014861,0.111736,1.809921,0.188746,0.234917 +722,722,20210621,-1.213794,-1.234323,0.185828,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +723,723,20210621,0.096463,0.810161,-1.079457,0.858557,-0.920561,0.904712,-0.72357,-0.696663,-0.666599,-0.647565 +724,724,20210621,1.175499,-1.234323,-1.079457,-1.057295,1.249166,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +725,725,20210621,-0.674276,0.810161,0.185828,0.858557,-0.161156,0.014861,0.111736,0.138865,1.899436,1.999879 +726,726,20210621,-1.213794,-1.234323,0.185828,-1.057295,1.032193,0.014861,0.111736,0.138865,1.899436,0.234917 +727,727,20210621,1.483795,0.810161,0.185828,0.858557,0.381275,-0.874991,-0.72357,-0.696663,0.188746,-0.647565 +728,728,20210621,2.17746,-1.234323,0.185828,0.858557,-0.269643,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +729,729,20210621,1.252573,0.810161,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,-0.647565 +730,730,20210621,-0.828424,-1.234323,-1.079457,0.858557,-0.703588,-0.874991,1.782348,-0.696663,-0.666599,1.999879 +731,731,20210621,-0.905498,0.810161,1.451114,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +732,732,20210621,0.250611,-1.234323,0.185828,-1.057295,0.272789,0.014861,0.111736,0.138865,0.188746,0.234917 +733,733,20210621,-0.365981,-1.234323,-1.079457,0.858557,-0.161156,0.904712,1.782348,-0.696663,-0.666599,-1.530046 +734,734,20210621,-0.057685,0.810161,-1.079457,-1.057295,0.164303,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +735,735,20210621,-0.443054,-1.234323,0.185828,-1.057295,2.334029,0.014861,0.111736,0.138865,0.188746,0.234917 +736,736,20210621,-0.75135,0.810161,1.451114,-1.057295,1.574625,-1.764843,-1.558876,-0.696663,0.188746,0.234917 +737,737,20210621,-0.134759,0.810161,1.451114,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +738,738,20210621,3.410644,0.810161,-1.079457,0.858557,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +739,739,20210621,-0.443054,0.810161,-1.079457,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +740,740,20210621,-0.674276,0.810161,0.185828,0.858557,-1.137534,1.794564,0.111736,0.138865,1.899436,0.234917 +741,741,20210621,0.019389,0.810161,0.185828,-1.057295,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +742,742,20210621,-0.443054,0.810161,-1.079457,0.858557,-0.595102,-0.874991,-0.72357,-0.696663,-0.666599,-1.530046 +743,743,20210621,-0.211833,0.810161,-1.079457,-1.057295,1.683111,0.014861,0.111736,0.138865,0.188746,0.234917 +744,744,20210621,-0.75135,-1.234323,-1.079457,0.858557,1.683111,0.014861,0.111736,0.138865,1.899436,0.234917 +745,745,20210621,0.713055,0.810161,0.185828,-1.057295,1.14068,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +746,746,20210621,0.019389,-1.234323,1.451114,0.858557,0.272789,0.014861,0.111736,0.138865,0.188746,0.234917 +747,747,20210621,-0.905498,0.810161,0.185828,-1.057295,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +748,748,20210621,1.021351,0.810161,1.451114,-1.057295,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +749,749,20210621,-0.134759,0.810161,-1.079457,0.858557,-0.486615,1.794564,-0.72357,-0.696663,-0.666599,-0.647565 +750,750,20210621,-0.905498,0.810161,0.185828,0.858557,-1.137534,7.133674,5.958878,5.152034,4.46547,3.764842 +751,751,20210621,-0.905498,0.810161,0.185828,-1.057295,-1.029047,0.904712,-1.558876,-0.696663,0.188746,0.234917 +752,752,20210621,-0.597202,0.810161,-1.079457,0.858557,-1.137534,1.794564,0.111736,0.138865,0.188746,0.234917 +753,753,20210621,-0.905498,-1.234323,0.185828,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +754,754,20210621,2.56283,0.810161,0.185828,0.858557,0.815221,-0.874991,0.111736,0.138865,0.188746,0.234917 +755,755,20210621,2.331608,0.810161,0.185828,-1.057295,0.055816,-0.874991,0.111736,0.138865,-0.666599,-0.647565 +756,756,20210621,0.481833,-1.234323,0.185828,0.858557,2.442516,0.014861,0.111736,0.138865,0.188746,0.234917 +757,757,20210621,-0.211833,0.810161,0.185828,0.858557,-1.029047,0.014861,0.111736,-0.696663,-0.666599,0.234917 +758,758,20210621,0.481833,0.810161,0.185828,-1.057295,-0.595102,1.794564,0.111736,-0.696663,-0.666599,-0.647565 +759,759,20210621,1.946238,0.810161,0.185828,0.858557,-0.486615,0.014861,0.111736,0.138865,0.188746,-0.647565 +760,760,20210621,-1.059646,0.810161,0.185828,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +761,761,20210621,-0.905498,0.810161,0.185828,0.858557,1.791598,0.904712,1.782348,0.138865,0.188746,0.234917 +762,762,20210621,-0.211833,0.810161,0.185828,0.858557,-1.24602,-0.874991,-0.72357,-1.532192,-0.666599,-0.647565 +763,763,20210621,0.713055,0.810161,0.185828,-1.057295,-0.05267,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +764,764,20210621,-0.597202,0.810161,1.451114,0.858557,-0.703588,-0.874991,1.782348,-0.696663,-0.666599,-0.647565 +765,765,20210621,0.558907,0.810161,0.185828,-1.057295,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +766,766,20210621,2.639904,0.810161,-1.079457,0.858557,-0.05267,-0.874991,0.111736,0.138865,0.188746,0.234917 +767,767,20210621,-0.443054,0.810161,0.185828,-1.057295,-0.05267,0.014861,0.111736,0.138865,0.188746,0.234917 +768,768,20210621,0.327685,0.810161,-1.079457,0.858557,-0.812074,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +769,769,20210621,0.404759,-1.234323,0.185828,-1.057295,0.489762,-0.874991,-0.72357,-1.532192,-1.521944,-1.530046 +770,770,20210621,0.250611,0.810161,-1.079457,-1.057295,-0.05267,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +771,771,20210621,1.483795,0.810161,0.185828,0.858557,1.900084,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +772,772,20210621,0.713055,-1.234323,-1.079457,0.858557,0.923707,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +773,773,20210621,-1.13672,-1.234323,0.185828,-1.057295,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +774,774,20210621,-0.365981,0.810161,0.185828,-1.057295,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +775,775,20210621,-0.905498,0.810161,-1.079457,0.858557,-0.269643,-0.874991,1.782348,-0.696663,-0.666599,-0.647565 +776,776,20210621,-0.828424,0.810161,-1.079457,0.858557,-1.029047,0.904712,1.782348,0.138865,0.188746,0.234917 +777,777,20210621,0.250611,-1.234323,-1.079457,0.858557,-1.029047,-1.764843,-1.558876,-1.532192,-1.521944,-0.647565 +778,778,20210621,-1.13672,-1.234323,0.185828,0.858557,-1.029047,-0.874991,-0.72357,-0.696663,-0.666599,-1.530046 +779,779,20210621,-0.905498,0.810161,-1.079457,-1.057295,-0.378129,1.794564,0.111736,0.138865,-0.666599,0.234917 +780,780,20210621,-0.905498,0.810161,0.185828,0.858557,-0.486615,0.904712,-1.558876,-0.696663,-0.666599,-0.647565 +781,781,20210621,0.481833,-1.234323,-1.079457,0.858557,-0.703588,0.014861,0.111736,1.809921,1.899436,1.999879 +782,782,20210621,-0.905498,-1.234323,0.185828,-1.057295,-0.920561,-0.874991,-0.72357,1.809921,-0.666599,-0.647565 +783,783,20210621,-0.520128,0.810161,-1.079457,0.858557,-0.812074,1.794564,1.782348,1.809921,1.899436,1.999879 +784,784,20210621,0.327685,0.810161,-1.079457,-1.057295,0.706734,0.904712,-1.558876,-0.696663,-0.666599,-1.530046 +785,785,20210621,0.481833,0.810161,0.185828,-1.057295,-0.378129,0.014861,0.111736,0.138865,0.188746,1.999879 +786,786,20210621,2.56283,0.810161,-1.079457,0.858557,-1.029047,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +787,787,20210621,1.560869,0.810161,-1.079457,0.858557,0.272789,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +788,788,20210621,0.481833,0.810161,-1.079457,-1.057295,-0.05267,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +789,789,20210621,-0.674276,-1.234323,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +790,790,20210621,-0.828424,0.810161,0.185828,0.858557,-0.703588,-0.874991,0.111736,0.138865,0.188746,-1.530046 +791,791,20210621,-1.059646,0.810161,0.185828,0.858557,1.683111,0.904712,1.782348,1.809921,0.188746,0.234917 +792,792,20210621,-0.75135,-1.234323,-1.079457,0.858557,-0.920561,0.904712,-0.72357,-0.696663,-0.666599,-1.530046 +793,793,20210621,1.869164,-1.234323,-1.079457,0.858557,-0.378129,-0.874991,-0.72357,-0.696663,-1.521944,-1.530046 +794,794,20210621,0.867203,0.810161,1.451114,-1.057295,0.489762,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +795,795,20210621,-0.905498,0.810161,-1.079457,-1.057295,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +796,796,20210621,-0.520128,0.810161,0.185828,-1.057295,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +797,797,20210621,0.481833,0.810161,-1.079457,0.858557,-0.703588,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +798,798,20210621,-0.905498,0.810161,-1.079457,0.858557,-1.462993,0.014861,0.111736,0.138865,-0.666599,-0.647565 +799,799,20210621,-0.520128,0.810161,-1.079457,0.858557,1.357652,1.794564,1.782348,1.809921,1.899436,1.999879 +800,800,20210621,0.327685,0.810161,0.185828,-1.057295,-0.05267,0.014861,0.111736,0.138865,0.188746,0.234917 +801,801,20210621,1.792091,-1.234323,-1.079457,0.858557,0.164303,-0.874991,-0.72357,-0.696663,-0.666599,-1.530046 +802,802,20210621,-1.13672,-1.234323,0.185828,0.858557,-1.137534,3.574267,2.617654,1.809921,0.188746,0.234917 +803,803,20210621,-0.905498,0.810161,1.451114,-1.057295,0.923707,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +804,804,20210621,0.481833,0.810161,-1.079457,0.858557,-0.812074,-0.874991,-0.72357,-0.696663,-1.521944,-1.530046 +805,805,20210621,0.404759,-1.234323,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,-1.521944,-1.530046 +806,806,20210621,1.021351,0.810161,-1.079457,-1.057295,0.055816,0.014861,0.111736,0.138865,0.188746,-1.530046 +807,807,20210621,-0.674276,0.810161,0.185828,0.858557,-1.354506,0.904712,-0.72357,1.809921,-0.666599,-0.647565 +808,808,20210621,-1.13672,0.810161,1.451114,0.858557,0.055816,0.014861,0.111736,1.809921,1.899436,1.999879 +809,809,20210621,0.173537,0.810161,-1.079457,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +810,810,20210621,-0.057685,0.810161,0.185828,-2.973147,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +811,811,20210621,-0.365981,0.810161,-1.079457,2.77441,0.923707,0.014861,0.111736,1.809921,0.188746,0.234917 +812,812,20210621,4.104309,0.810161,-1.079457,-1.057295,0.381275,0.014861,0.111736,0.138865,0.188746,-1.530046 +813,813,20210621,-0.211833,0.810161,-1.079457,0.858557,-1.24602,0.904712,-1.558876,-1.532192,-1.521944,-0.647565 +814,814,20210621,1.021351,0.810161,1.451114,-1.057295,-0.703588,-0.874991,0.111736,0.138865,0.188746,0.234917 +815,815,20210621,-0.365981,-1.234323,1.451114,-1.057295,-0.269643,0.904712,1.782348,1.809921,1.899436,1.999879 +816,816,20210621,0.867203,0.810161,0.185828,-1.057295,0.381275,0.014861,0.111736,1.809921,0.188746,0.234917 +817,817,20210621,-0.75135,-1.234323,1.451114,-1.057295,1.683111,1.794564,1.782348,0.138865,0.188746,0.234917 +818,818,20210621,-1.13672,0.810161,1.451114,0.858557,-1.24602,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +819,819,20210621,-0.134759,0.810161,0.185828,-1.057295,1.032193,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +820,820,20210621,-0.828424,-1.234323,-1.079457,0.858557,-0.595102,0.014861,-0.72357,0.138865,0.188746,0.234917 +821,821,20210621,0.250611,0.810161,1.451114,-2.973147,1.683111,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +822,822,20210621,-0.905498,0.810161,0.185828,0.858557,-1.24602,0.904712,1.782348,0.138865,0.188746,0.234917 +823,823,20210621,-0.134759,-1.234323,0.185828,-1.057295,1.574625,-0.874991,0.111736,0.138865,1.899436,0.234917 +824,824,20210621,-1.13672,0.810161,-1.079457,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +825,825,20210621,-0.982572,-1.234323,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +826,826,20210621,0.019389,0.810161,0.185828,0.858557,-0.269643,0.904712,-0.72357,-0.696663,-0.666599,-1.530046 +827,827,20210621,-0.905498,0.810161,0.185828,-1.057295,-1.24602,0.904712,1.782348,0.138865,0.188746,0.234917 +828,828,20210621,-1.213794,-1.234323,0.185828,0.858557,0.164303,0.014861,0.111736,0.138865,0.188746,1.999879 +829,829,20210621,0.250611,0.810161,0.185828,-1.057295,2.442516,-0.874991,-0.72357,-0.696663,-0.666599,-1.530046 +830,830,20210621,-0.905498,0.810161,0.185828,-1.057295,1.357652,0.014861,-0.72357,-0.696663,0.188746,0.234917 +831,831,20210621,1.175499,-1.234323,-1.079457,0.858557,-0.812074,-0.874991,0.111736,0.138865,-0.666599,0.234917 +832,832,20210621,-1.13672,0.810161,1.451114,-1.057295,-1.24602,7.133674,5.958878,5.152034,4.46547,3.764842 +833,833,20210621,2.331608,0.810161,0.185828,-1.057295,-0.920561,0.014861,0.111736,0.138865,0.188746,-0.647565 +834,834,20210621,0.481833,0.810161,1.451114,0.858557,-0.595102,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +835,835,20210621,-1.13672,0.810161,-1.079457,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +836,836,20210621,-1.059646,0.810161,1.451114,0.858557,1.900084,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +837,837,20210621,-0.674276,0.810161,0.185828,0.858557,-1.354506,1.794564,1.782348,1.809921,1.899436,1.999879 +838,838,20210621,-0.443054,0.810161,0.185828,-1.057295,2.117057,0.014861,0.111736,0.138865,0.188746,0.234917 +839,839,20210621,1.946238,-1.234323,0.185828,-1.057295,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +840,840,20210621,2.56283,-1.234323,-1.079457,-1.057295,0.815221,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +841,841,20210621,-0.674276,0.810161,0.185828,0.858557,-1.462993,0.904712,1.782348,0.138865,0.188746,0.234917 +842,842,20210621,1.406721,0.810161,0.185828,-1.057295,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +843,843,20210621,-1.059646,0.810161,0.185828,-1.057295,-0.378129,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +844,844,20210621,-0.443054,0.810161,0.185828,0.858557,-0.269643,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +845,845,20210621,2.56283,-1.234323,1.451114,-1.057295,0.381275,0.014861,0.111736,0.138865,0.188746,0.234917 +846,846,20210621,2.485756,0.810161,-1.079457,-1.057295,0.272789,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +847,847,20210621,1.021351,0.810161,0.185828,-1.057295,-0.161156,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +848,848,20210621,-0.905498,-1.234323,0.185828,2.77441,0.706734,1.794564,0.111736,0.138865,1.899436,0.234917 +849,849,20210621,-0.134759,-1.234323,1.451114,-1.057295,0.164303,3.574267,3.45296,3.480978,2.754781,1.999879 +850,850,20210621,-0.674276,0.810161,1.451114,-1.057295,2.334029,-0.874991,1.782348,-0.696663,0.188746,0.234917 +851,851,20210621,-0.982572,0.810161,0.185828,0.858557,-1.354506,0.014861,0.111736,0.138865,1.899436,1.999879 +852,852,20210621,-1.059646,-1.234323,0.185828,0.858557,-0.378129,0.904712,1.782348,1.809921,0.188746,0.234917 +853,853,20210621,-0.905498,-1.234323,-1.079457,-1.057295,0.164303,0.014861,0.111736,-1.532192,-1.521944,-1.530046 +854,854,20210621,-0.211833,0.810161,0.185828,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +855,855,20210621,-0.905498,0.810161,1.451114,0.858557,1.466139,0.014861,0.111736,0.138865,0.188746,0.234917 +856,856,20210621,-1.059646,0.810161,0.185828,0.858557,-1.137534,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +857,857,20210621,-0.982572,0.810161,-1.079457,0.858557,-0.703588,0.014861,0.111736,1.809921,1.899436,1.999879 +858,858,20210621,-0.520128,0.810161,1.451114,-1.057295,0.815221,1.794564,1.782348,1.809921,1.899436,1.999879 +859,859,20210621,-0.288907,-1.234323,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +860,860,20210621,-1.13672,0.810161,0.185828,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +861,861,20210621,-0.905498,-1.234323,-1.079457,0.858557,-1.029047,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +862,862,20210621,0.713055,-1.234323,-1.079457,-1.057295,0.598248,-1.764843,-1.558876,-0.696663,0.188746,0.234917 +863,863,20210621,-1.059646,0.810161,1.451114,0.858557,1.791598,1.794564,1.782348,5.987563,6.17616,6.412285 +864,864,20210621,-1.213794,0.810161,0.185828,-1.057295,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +865,865,20210621,0.250611,-1.234323,-1.079457,0.858557,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +866,866,20210621,-1.059646,0.810161,0.185828,-1.057295,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +867,867,20210621,0.096463,0.810161,0.185828,0.858557,-0.05267,0.014861,0.111736,0.138865,-1.521944,-1.530046 +868,868,20210621,-0.520128,-1.234323,-1.079457,0.858557,-0.05267,0.014861,0.111736,-1.532192,-1.521944,-1.530046 +869,869,20210621,-0.211833,0.810161,0.185828,-1.057295,0.381275,0.014861,0.111736,0.138865,0.188746,0.234917 +870,870,20210621,0.944277,0.810161,0.185828,0.858557,-0.161156,0.014861,0.111736,0.138865,0.188746,0.234917 +871,871,20210621,-1.13672,0.810161,0.185828,2.77441,1.791598,0.014861,0.111736,0.138865,0.188746,0.234917 +872,872,20210621,-0.674276,0.810161,1.451114,-1.057295,0.489762,0.014861,0.111736,0.138865,0.188746,0.234917 +873,873,20210621,2.56283,0.810161,1.451114,-1.057295,0.272789,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +874,874,20210621,0.096463,-1.234323,-1.079457,-1.057295,1.032193,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +875,875,20210621,-1.13672,0.810161,1.451114,-1.057295,0.489762,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +876,876,20210621,-1.059646,0.810161,0.185828,-1.057295,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +877,877,20210621,-0.134759,-1.234323,-1.079457,0.858557,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +878,878,20210621,0.867203,0.810161,0.185828,0.858557,-0.920561,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +879,879,20210621,-0.905498,0.810161,0.185828,-1.057295,0.815221,0.014861,0.111736,0.138865,-0.666599,0.234917 +880,880,20210621,-1.13672,0.810161,0.185828,-1.057295,0.815221,1.794564,0.111736,0.138865,0.188746,0.234917 +881,881,20210621,0.250611,-1.234323,-1.079457,0.858557,-0.595102,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +882,882,20210621,0.327685,0.810161,0.185828,-1.057295,1.466139,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +883,883,20210621,0.481833,0.810161,-1.079457,0.858557,0.272789,0.014861,0.111736,0.138865,0.188746,0.234917 +884,884,20210621,-0.905498,-1.234323,1.451114,0.858557,2.334029,0.014861,0.111736,0.138865,0.188746,0.234917 +885,885,20210621,-0.905498,-1.234323,1.451114,0.858557,2.117057,0.014861,0.111736,0.138865,0.188746,0.234917 +886,886,20210621,-0.75135,0.810161,0.185828,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +887,887,20210621,1.098425,-1.234323,-1.079457,0.858557,-0.595102,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +888,888,20210621,0.096463,0.810161,0.185828,-1.057295,-0.595102,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +889,889,20210621,-0.597202,0.810161,0.185828,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +890,890,20210621,1.715017,-1.234323,0.185828,0.858557,-0.812074,0.014861,0.111736,0.138865,0.188746,0.234917 +891,891,20210621,-0.134759,0.810161,1.451114,-1.057295,-0.161156,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +892,892,20210621,1.792091,-1.234323,0.185828,0.858557,0.164303,0.904712,0.947042,0.974393,1.899436,0.234917 +893,893,20210621,-0.674276,0.810161,0.185828,-1.057295,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +894,894,20210621,1.175499,-1.234323,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +895,895,20210621,0.558907,0.810161,0.185828,-1.057295,0.164303,-0.874991,-0.72357,-1.532192,-1.521944,-1.530046 +896,896,20210621,0.250611,-1.234323,-1.079457,0.858557,-0.486615,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +897,897,20210621,-0.443054,-1.234323,-1.079457,2.77441,2.117057,0.904712,1.782348,1.809921,1.899436,2.88236 +898,898,20210621,0.019389,0.810161,-1.079457,0.858557,-0.812074,1.794564,1.782348,1.809921,1.899436,1.999879 +899,899,20210621,-0.597202,0.810161,1.451114,2.77441,1.683111,0.014861,0.111736,0.138865,0.188746,1.999879 +900,900,20210621,0.250611,-1.234323,-1.079457,-1.057295,0.055816,-0.874991,-0.72357,0.138865,-0.666599,-0.647565 +901,901,20210621,1.483795,-1.234323,-1.079457,0.858557,-0.595102,-1.764843,-0.72357,-0.696663,-1.521944,-1.530046 +902,902,20210621,-0.211833,0.810161,-1.079457,-1.057295,0.055816,-0.874991,-0.72357,-1.532192,-0.666599,0.234917 +903,903,20210621,0.404759,-1.234323,0.185828,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +904,904,20210621,-0.520128,-1.234323,1.451114,-1.057295,1.574625,0.014861,0.111736,-1.532192,-1.521944,-1.530046 +905,905,20210621,-0.674276,0.810161,0.185828,0.858557,0.489762,1.794564,0.111736,0.138865,0.188746,1.999879 +906,906,20210621,-1.059646,0.810161,0.185828,0.858557,-0.920561,-0.874991,-0.72357,1.809921,0.188746,-0.647565 +907,907,20210621,-0.905498,-1.234323,-1.079457,0.858557,-0.595102,1.794564,1.782348,1.809921,-0.666599,1.999879 +908,908,20210621,-0.365981,0.810161,0.185828,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +909,909,20210621,-0.905498,-1.234323,-1.079457,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +910,910,20210621,1.483795,0.810161,-1.079457,0.858557,-0.920561,0.014861,-0.72357,0.138865,-0.666599,-0.647565 +911,911,20210621,-0.597202,0.810161,-1.079457,0.858557,-1.137534,1.794564,1.782348,1.809921,1.899436,0.234917 +912,912,20210621,2.56283,-1.234323,-1.079457,0.858557,-0.378129,-0.874991,0.111736,0.138865,0.188746,0.234917 +913,913,20210621,-0.211833,0.810161,1.451114,-1.057295,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +914,914,20210621,-1.059646,-1.234323,1.451114,-1.057295,1.032193,0.014861,0.111736,1.809921,0.188746,0.234917 +915,915,20210621,-0.75135,-1.234323,1.451114,-1.057295,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +916,916,20210621,0.250611,-1.234323,-1.079457,-1.057295,0.381275,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +917,917,20210621,1.406721,-1.234323,-1.079457,-1.057295,1.357652,0.014861,0.111736,0.138865,0.188746,0.234917 +918,918,20210621,-0.365981,-1.234323,-1.079457,0.858557,-0.378129,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +919,919,20210621,0.558907,-1.234323,-1.079457,0.858557,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +920,920,20210621,-0.597202,0.810161,-1.079457,0.858557,-1.354506,0.014861,0.111736,0.138865,0.188746,0.234917 +921,921,20210621,0.713055,0.810161,-1.079457,0.858557,-0.269643,0.904712,-1.558876,-1.532192,-1.521944,-0.647565 +922,922,20210621,-0.905498,0.810161,-1.079457,0.858557,-1.24602,0.014861,0.111736,0.138865,1.899436,0.234917 +923,923,20210621,-0.443054,-1.234323,-1.079457,-1.057295,0.489762,0.014861,0.111736,0.138865,0.188746,0.234917 +924,924,20210621,-1.13672,0.810161,-1.079457,0.858557,-1.24602,-0.874991,-0.72357,1.809921,-0.666599,0.234917 +925,925,20210621,-1.059646,0.810161,0.185828,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +926,926,20210621,0.096463,-1.234323,-1.079457,0.858557,-0.920561,-1.764843,-0.72357,1.809921,1.899436,-1.530046 +927,927,20210621,-1.13672,-1.234323,0.185828,-1.057295,1.14068,0.014861,0.111736,0.138865,0.188746,0.234917 +928,928,20210621,-0.905498,0.810161,0.185828,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +929,929,20210621,0.096463,0.810161,-1.079457,0.858557,0.055816,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +930,930,20210621,0.250611,-1.234323,-1.079457,-1.057295,-0.161156,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +931,931,20210621,0.713055,0.810161,0.185828,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +932,932,20210621,1.175499,-1.234323,-1.079457,-1.057295,2.659488,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +933,933,20210621,-0.057685,0.810161,0.185828,0.858557,-0.703588,1.794564,1.782348,-0.696663,-0.666599,-0.647565 +934,934,20210621,-1.059646,-1.234323,0.185828,0.858557,-0.378129,1.794564,0.111736,0.138865,1.899436,1.999879 +935,935,20210621,-0.905498,0.810161,0.185828,-1.057295,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +936,936,20210621,-0.905498,-1.234323,0.185828,0.858557,-0.595102,0.014861,0.111736,0.138865,0.188746,-1.530046 +937,937,20210621,-0.597202,0.810161,0.185828,0.858557,-0.703588,0.014861,0.111736,0.138865,0.188746,0.234917 +938,938,20210621,0.558907,-1.234323,-1.079457,0.858557,-0.161156,0.904712,1.782348,-0.696663,-0.666599,0.234917 +939,939,20210621,0.096463,0.810161,0.185828,-1.057295,-0.378129,0.904712,1.782348,1.809921,1.899436,0.234917 +940,940,20210621,0.250611,0.810161,0.185828,-1.057295,-0.378129,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +941,941,20210621,-0.905498,0.810161,-1.079457,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +942,942,20210621,-0.905498,-1.234323,0.185828,-1.057295,0.923707,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +943,943,20210621,1.252573,0.810161,-1.079457,-1.057295,0.164303,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +944,944,20210621,-0.674276,0.810161,0.185828,0.858557,-1.24602,1.794564,1.782348,4.316506,4.46547,3.764842 +945,945,20210621,-0.905498,0.810161,0.185828,0.858557,-1.354506,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +946,946,20210621,1.483795,0.810161,-1.079457,0.858557,-0.703588,0.014861,0.111736,-0.696663,-0.666599,-0.647565 +947,947,20210621,0.558907,0.810161,0.185828,-1.057295,0.164303,0.014861,0.111736,0.138865,0.188746,0.234917 +948,948,20210621,-0.905498,-1.234323,0.185828,-1.057295,2.551002,0.014861,0.111736,0.138865,0.188746,0.234917 +949,949,20210621,2.331608,-1.234323,0.185828,0.858557,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +950,950,20210621,-0.057685,0.810161,1.451114,-1.057295,1.683111,-0.874991,1.782348,-0.696663,-0.666599,-0.647565 +951,951,20210621,-1.059646,-1.234323,-1.079457,-1.057295,-0.920561,-0.874991,0.111736,0.138865,0.188746,0.234917 +952,952,20210621,-0.674276,0.810161,0.185828,-1.057295,-0.378129,0.014861,0.111736,0.138865,0.188746,0.234917 +953,953,20210621,2.56283,0.810161,1.451114,0.858557,0.706734,-1.764843,-0.72357,-0.696663,0.188746,0.234917 +954,954,20210621,0.096463,-1.234323,0.185828,0.858557,0.381275,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +955,955,20210621,-0.443054,0.810161,0.185828,-1.057295,1.14068,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +956,956,20210621,-0.057685,-1.234323,-1.079457,-1.057295,0.598248,0.014861,-0.72357,0.138865,0.188746,1.999879 +957,957,20210621,0.327685,0.810161,0.185828,0.858557,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +958,958,20210621,0.250611,0.810161,-1.079457,-1.057295,-0.161156,-0.874991,0.111736,0.138865,-0.666599,0.234917 +959,959,20210621,1.406721,-1.234323,-1.079457,0.858557,-0.05267,-0.874991,-0.72357,-0.696663,0.188746,0.234917 +960,960,20210621,0.635981,-1.234323,-1.079457,0.858557,0.598248,-0.874991,-0.72357,-0.696663,0.188746,-0.647565 +961,961,20210621,1.637943,-1.234323,-1.079457,0.858557,0.815221,0.904712,1.782348,1.809921,-1.521944,-1.530046 +962,962,20210621,-1.059646,-1.234323,0.185828,0.858557,1.249166,-0.874991,-0.72357,-0.696663,-0.666599,0.234917 +963,963,20210621,0.250611,-1.234323,0.185828,0.858557,-0.486615,0.014861,0.111736,0.138865,0.188746,0.234917 +964,964,20210621,-1.059646,-1.234323,0.185828,0.858557,-0.595102,-0.874991,0.111736,0.138865,0.188746,0.234917 +965,965,20210621,-0.905498,-1.234323,0.185828,0.858557,-1.24602,0.014861,0.111736,-0.696663,-0.666599,0.234917 +966,966,20210621,2.56283,-1.234323,-1.079457,-1.057295,0.055816,0.014861,0.111736,0.138865,0.188746,0.234917 +967,967,20210621,-1.059646,-1.234323,-1.079457,0.858557,-0.812074,0.904712,-1.558876,-0.696663,-0.666599,-0.647565 +968,968,20210621,0.404759,0.810161,-1.079457,-1.057295,0.055816,-0.874991,-0.72357,0.138865,-0.666599,-0.647565 +969,969,20210621,-1.13672,0.810161,0.185828,-1.057295,-0.920561,0.014861,0.111736,0.138865,-0.666599,0.234917 +970,970,20210621,0.096463,0.810161,0.185828,-1.057295,-0.378129,0.014861,0.111736,0.138865,0.188746,-0.647565 +971,971,20210621,1.021351,-1.234323,-1.079457,-1.057295,0.706734,-0.874991,0.111736,0.138865,-0.666599,0.234917 +972,972,20210621,-0.288907,0.810161,0.185828,-1.057295,-0.269643,0.014861,0.111736,0.138865,0.188746,0.234917 +973,973,20210621,0.096463,0.810161,1.451114,-1.057295,0.381275,1.794564,1.782348,1.809921,1.899436,1.999879 +974,974,20210621,-0.134759,0.810161,-1.079457,2.77441,-0.595102,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +975,975,20210621,-0.211833,-1.234323,0.185828,-1.057295,-0.595102,0.014861,0.111736,0.138865,0.188746,0.234917 +976,976,20210621,-0.905498,0.810161,0.185828,0.858557,-1.462993,0.014861,0.111736,0.138865,0.188746,0.234917 +977,977,20210621,-1.13672,-1.234323,0.185828,0.858557,-1.137534,0.904712,1.782348,1.809921,0.188746,0.234917 +978,978,20210621,0.096463,-1.234323,-1.079457,0.858557,-0.812074,-0.874991,-0.72357,-0.696663,-0.666599,-0.647565 +979,979,20210621,0.096463,-1.234323,0.185828,0.858557,-1.029047,0.014861,0.111736,0.138865,0.188746,0.234917 +980,980,20210621,-0.134759,0.810161,1.451114,-1.057295,2.00857,-0.874991,0.111736,0.138865,0.188746,1.999879 +981,981,20210621,-0.75135,0.810161,-1.079457,0.858557,-1.24602,0.014861,0.111736,0.138865,0.188746,0.234917 +982,982,20210621,-1.059646,-1.234323,0.185828,0.858557,-0.703588,7.133674,5.958878,5.152034,4.46547,3.764842 +983,983,20210621,2.56283,-1.234323,-1.079457,0.858557,0.055816,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +984,984,20210621,-0.828424,-1.234323,1.451114,-1.057295,1.466139,0.014861,0.111736,0.138865,0.188746,0.234917 +985,985,20210621,-0.905498,0.810161,-1.079457,0.858557,-1.354506,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +986,986,20210621,-0.288907,-1.234323,1.451114,0.858557,0.815221,0.904712,-0.72357,-0.696663,-1.521944,-0.647565 +987,987,20210621,0.713055,0.810161,0.185828,-1.057295,-0.269643,-1.764843,-1.558876,-1.532192,-0.666599,-0.647565 +988,988,20210621,1.637943,-1.234323,1.451114,-1.057295,1.900084,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +989,989,20210621,1.483795,0.810161,0.185828,0.858557,-1.137534,1.794564,1.782348,1.809921,1.899436,1.999879 +990,990,20210621,-0.905498,-1.234323,1.451114,-1.057295,2.00857,0.904712,1.782348,1.809921,0.188746,0.234917 +991,991,20210621,-0.905498,0.810161,1.451114,-1.057295,0.381275,0.014861,0.111736,1.809921,-0.666599,0.234917 +992,992,20210621,0.713055,0.810161,-1.079457,-1.057295,0.923707,-0.874991,1.782348,1.809921,-0.666599,-0.647565 +993,993,20210621,-0.674276,0.810161,0.185828,0.858557,-0.920561,0.014861,0.111736,0.138865,0.188746,0.234917 +994,994,20210621,1.483795,0.810161,-1.079457,0.858557,-1.137534,0.014861,0.111736,0.138865,0.188746,0.234917 +995,995,20210621,0.944277,0.810161,-1.079457,0.858557,-0.703588,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +996,996,20210621,0.250611,-1.234323,-1.079457,0.858557,0.381275,-1.764843,-1.558876,-1.532192,-1.521944,-1.530046 +997,997,20210621,-0.211833,-1.234323,-1.079457,-1.057295,1.032193,0.014861,0.111736,0.138865,0.188746,1.999879 +998,998,20210621,1.483795,-1.234323,-1.079457,-1.057295,0.272789,0.904712,-1.558876,-1.532192,-1.521944,-1.530046 +999,999,20210621,-0.905498,0.810161,0.185828,0.858557,-1.354506,-0.874991,-0.72357,-0.696663,0.188746,-0.647565 +1000,1000,20210621,-0.365981,-1.234323,0.185828,0.858557,-1.137534,1.794564,1.782348,0.138865,0.188746,0.234917 \ No newline at end of file diff --git a/deploy/integrated_test/rsa_private.key b/deploy/integrated_test/rsa_private.key new file mode 100644 index 000000000..b6069ce87 --- /dev/null +++ b/deploy/integrated_test/rsa_private.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDGWKQc2A50Tpq6gvC4Q14YFtdxPybk1B5ByrBsD0nJ6eUwLnqq +Od2srmM0pS6yPskKdtOim/wvsP1XViXCywIwFARqn2bwp7JqXzjLfrNyazR9uEQo +NvNpv5yHaaFam+0hAxZST6t7NIP6Geb9HO+GMuSfw7rmlnLlO1EbmEW25wIDAQAB +AoGBAIq2aSeG7izm4Az6D/E9o+uC5e7cNI4pznNCljksQ/WCrvcQOlccGuxuFRE3 +SD397Ml1qrJ5FlggFjzjEYt2QDM1myvHdUcPCSeKCdvnZmNP7qv6toJkxvpA1pMU +PLZ91O2SshtJyPT0yBbXMGpj0NmlgjajW9hCajoILaEbabOpAkEA8NsEh1y/EZE/ +gB3kZbov/j4sZiLKR2dTqxvBFmsOLQe3PEPzMDXehshxOETFjD70D602WjXXm3+F ++65aJigBxQJBANLRXRkFxc6WKHUeO2R0VPZMZW6aOxpdET/qGdFtv06ZNUC0Y4OB +ZK4P1UXMApRz+KKOK6Ina3mBDR4Adj99fLsCQGM+G7Oa56/ZZYzoxD+WZEgiXjEH +jMm3LaaHnRwbqI+tajcO2Jm42KQ4204QKEYNeosrGAY7wUd1WEPIJ6UpPvECQQCj +IrQiGt94/6WLC7v1/jeI6JFNRzgZLI+en+8eqwhxMAmPaoffSY+5SjNFcZtFeYCb +edy1/D8kpQKbhsv6UYblAkACYZrjnNOem0uyw7HrZF09n69BUsNRrxdWwE02NmjP +wlbixMa2wcd5LY01zznyhc5xjLMD9hVfaWaoPhBIM4Qw +-----END RSA PRIVATE KEY----- diff --git a/deploy/kubernetes_operator/go.mod b/deploy/kubernetes_operator/go.mod index 9fe704a74..df75cb149 100644 --- a/deploy/kubernetes_operator/go.mod +++ b/deploy/kubernetes_operator/go.mod @@ -3,7 +3,7 @@ module github.com/bytedance/fedlearner/deploy/kubernetes_operator go 1.14 require ( - github.com/gin-gonic/gin v1.6.3 + github.com/gin-gonic/gin v1.7.2 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect github.com/golang/protobuf v1.3.3 diff --git a/deploy/kubernetes_operator/go.sum b/deploy/kubernetes_operator/go.sum index d4157e829..6a1b96fcd 100644 --- a/deploy/kubernetes_operator/go.sum +++ b/deploy/kubernetes_operator/go.sum @@ -41,8 +41,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA= +github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= @@ -66,8 +66,8 @@ github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8c github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= @@ -192,6 +192,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= diff --git a/deploy/scripts/data_join/run_data_join_follower_master.sh b/deploy/scripts/data_join/run_data_join_follower_master.sh index 8b4028d72..1021a7730 100755 --- a/deploy/scripts/data_join/run_data_join_follower_master.sh +++ b/deploy/scripts/data_join/run_data_join_follower_master.sh @@ -16,6 +16,8 @@ set -ex +source /app/deploy/scripts/pre_start_hook.sh || true + echo "Reset the ROLE=$ROLE as follower" export ROLE=follower data_join_master_cmd=/app/deploy/scripts/data_join/run_data_join_master.sh diff --git a/deploy/scripts/data_join/run_data_join_leader_master.sh b/deploy/scripts/data_join/run_data_join_leader_master.sh index 955c23f50..50f2f11e4 100755 --- a/deploy/scripts/data_join/run_data_join_leader_master.sh +++ b/deploy/scripts/data_join/run_data_join_leader_master.sh @@ -16,6 +16,8 @@ set -ex +source /app/deploy/scripts/pre_start_hook.sh || true + echo "Reset the ROLE=$ROLE as leader" export ROLE=leader data_join_master_cmd=/app/deploy/scripts/data_join/run_data_join_master.sh diff --git a/deploy/scripts/data_join/run_data_join_master.sh b/deploy/scripts/data_join/run_data_join_master.sh index 152f0a607..d4f07d68f 100755 --- a/deploy/scripts/data_join/run_data_join_master.sh +++ b/deploy/scripts/data_join/run_data_join_master.sh @@ -18,8 +18,10 @@ set -ex export CUDA_VISIBLE_DEVICES= source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true source /app/deploy/scripts/env_to_args.sh + kvstore_type=$(normalize_env_to_args '--kvstore_type' $KVSTORE_TYPE) python -m fedlearner.data_join.cmd.prepare_launch_data_join_cli \ @@ -33,8 +35,13 @@ python -m fedlearner.data_join.cmd.prepare_launch_data_join_cli \ --raw_data_sub_dir=$RAW_DATA_SUB_DIR \ $kvstore_type +LISTEN_PORT=50051 +if [[ -n "${PORT0}" ]]; then + LISTEN_PORT=${PORT0} +fi + python -m fedlearner.data_join.cmd.data_join_master_service \ $PEER_ADDR \ - --listen_port=50051 \ + --listen_port=${LISTEN_PORT} \ --data_source_name=$APPLICATION_ID $BATCH_MODE \ $kvstore_type diff --git a/deploy/scripts/data_join/run_data_join_worker.sh b/deploy/scripts/data_join/run_data_join_worker.sh index 6993e4072..370fde8e3 100755 --- a/deploy/scripts/data_join/run_data_join_worker.sh +++ b/deploy/scripts/data_join/run_data_join_worker.sh @@ -18,8 +18,10 @@ set -ex export CUDA_VISIBLE_DEVICES= source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true source /app/deploy/scripts/env_to_args.sh + MASTER_POD_NAMES=`python -c 'import json, os; print(json.loads(os.environ["CLUSTER_SPEC"])["clusterSpec"]["Master"][0])'` raw_data_iter=$(normalize_env_to_args "--raw_data_iter" $RAW_DATA_ITER) @@ -53,11 +55,16 @@ if [ -n "$JOIN_KEY_MAPPER" ]; then join_key_mapper=$(normalize_env_to_args '--join_key_mapper' "${mapper[0]}") fi +LISTEN_PORT=50051 +if [[ -n "${PORT0}" ]]; then + LISTEN_PORT=${PORT0} +fi + python -m fedlearner.data_join.cmd.data_join_worker_service \ $PEER_ADDR \ $MASTER_POD_NAMES \ $INDEX \ - --listen_port=50051 \ + --listen_port=${LISTEN_PORT} \ $raw_data_iter $compressed_type $read_ahead_size $read_batch_size \ $example_joiner $min_matching_window $max_matching_window \ $data_block_dump_interval $data_block_dump_threshold \ diff --git a/deploy/scripts/data_join/run_psi_data_join_follower_worker.sh b/deploy/scripts/data_join/run_psi_data_join_follower_worker.sh index b5b2bb8de..811111ecd 100755 --- a/deploy/scripts/data_join/run_psi_data_join_follower_worker.sh +++ b/deploy/scripts/data_join/run_psi_data_join_follower_worker.sh @@ -16,6 +16,8 @@ set -ex +source /app/deploy/scripts/pre_start_hook.sh || true + WORKER_REPLICAS=`python -c 'import json, os; print(len(json.loads(os.environ["CLUSTER_SPEC"])["clusterSpec"]["Worker"]))'` echo "${WORKER_REPLICAS:?Need to set WORKER_REPLICAS non-empty}" diff --git a/deploy/scripts/data_join/run_psi_data_join_follower_worker_v2.sh b/deploy/scripts/data_join/run_psi_data_join_follower_worker_v2.sh index 47ca4e004..d05c3ea0d 100755 --- a/deploy/scripts/data_join/run_psi_data_join_follower_worker_v2.sh +++ b/deploy/scripts/data_join/run_psi_data_join_follower_worker_v2.sh @@ -16,6 +16,8 @@ set -ex +source /app/deploy/scripts/pre_start_hook.sh || true + psi_preprocessor_cmd=/app/deploy/scripts/rsa_psi/run_psi_preprocessor.sh data_join_worker_cmd=/app/deploy/scripts/data_join/run_data_join_worker.sh @@ -23,15 +25,6 @@ echo "launch ras psi preprocessor at front ground" ${psi_preprocessor_cmd} echo "ras psi preprocessor run finished" -TCP_MSL=60 -if [ -f "/proc/sys/net/ipv4/tcp_fin_timeout" ] -then - TCP_MSL=`cat /proc/sys/net/ipv4/tcp_fin_timeout` -fi -SLEEP_TM=$((TCP_MSL * 3)) -echo "sleep 3msl($SLEEP_TM) to make sure tcp state at CLOSED" -sleep $SLEEP_TM - echo "launch data join worker" export RAW_DATA_ITER=$PSI_OUTPUT_BUILDER export COMPRESSED_TYPE=$PSI_OUTPUT_BUILDER_COMPRESSED_TYPE diff --git a/deploy/scripts/data_join/run_psi_data_join_leader_worker.sh b/deploy/scripts/data_join/run_psi_data_join_leader_worker.sh index a5b025555..009d25242 100755 --- a/deploy/scripts/data_join/run_psi_data_join_leader_worker.sh +++ b/deploy/scripts/data_join/run_psi_data_join_leader_worker.sh @@ -16,6 +16,8 @@ set -ex +source /app/deploy/scripts/pre_start_hook.sh || true + WORKER_REPLICAS=`python -c 'import json, os; print(len(json.loads(os.environ["CLUSTER_SPEC"])["clusterSpec"]["Worker"]))'` echo "${WORKER_REPLICAS:?Need to set WORKER_REPLICAS non-empty}" echo "${INDEX:?Need to set INDEX non-empty}" diff --git a/deploy/scripts/data_join/run_psi_data_join_leader_worker_v2.sh b/deploy/scripts/data_join/run_psi_data_join_leader_worker_v2.sh index b5f4dadaf..d8f96d18f 100755 --- a/deploy/scripts/data_join/run_psi_data_join_leader_worker_v2.sh +++ b/deploy/scripts/data_join/run_psi_data_join_leader_worker_v2.sh @@ -16,6 +16,8 @@ set -ex +source /app/deploy/scripts/pre_start_hook.sh || true + psi_signer_cmd=/app/deploy/scripts/rsa_psi/run_rsa_psi_signer.sh psi_preprocessor_cmd=/app/deploy/scripts/rsa_psi/run_psi_preprocessor.sh data_join_worker_cmd=/app/deploy/scripts/data_join/run_data_join_worker.sh @@ -53,15 +55,6 @@ echo "launch psi signer for follower of psi preprocessor at front ground" ${psi_signer_cmd} echo "psi signer for follower of psi preprocessor finish" -TCP_MSL=60 -if [ -f "/proc/sys/net/ipv4/tcp_fin_timeout" ] -then - TCP_MSL=`cat /proc/sys/net/ipv4/tcp_fin_timeout` -fi -SLEEP_TM=$((TCP_MSL * 3)) -echo "sleep 3msl($SLEEP_TM) to make sure tcp state at CLOSED" -sleep $SLEEP_TM - echo "launch data join worker" export RAW_DATA_ITER=$PSI_OUTPUT_BUILDER export COMPRESSED_TYPE=$PSI_OUTPUT_BUILDER_COMPRESSED_TYPE diff --git a/deploy/scripts/data_portal/run_data_portal_master.sh b/deploy/scripts/data_portal/run_data_portal_master.sh index f3bc6a72a..933eee544 100755 --- a/deploy/scripts/data_portal/run_data_portal_master.sh +++ b/deploy/scripts/data_portal/run_data_portal_master.sh @@ -18,14 +18,22 @@ set -ex export CUDA_VISIBLE_DEVICES= source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true source /app/deploy/scripts/env_to_args.sh -input_file_wildcard=$(normalize_env_to_args "--input_file_wildcard" $FILE_WILDCARD) +input_file_wildcard=$(normalize_env_to_args "--input_file_wildcard" "$FILE_WILDCARD") kvstore_type=$(normalize_env_to_args '--kvstore_type' $KVSTORE_TYPE) files_per_job_limit=$(normalize_env_to_args '--files_per_job_limit' $FILES_PER_JOB_LIMIT) +start_date=$(normalize_env_to_args '--start_date' $START_DATE) +end_date=$(normalize_env_to_args '--end_date' $END_DATE) + +LISTEN_PORT=50051 +if [[ -n "${PORT0}" ]]; then + LISTEN_PORT=${PORT0} +fi python -m fedlearner.data_join.cmd.data_portal_master_service \ - --listen_port=50051 \ + --listen_port=${LISTEN_PORT} \ --data_portal_name=$DATA_PORTAL_NAME \ --data_portal_type=$DATA_PORTAL_TYPE \ --output_partition_num=$OUTPUT_PARTITION_NUM \ @@ -33,4 +41,5 @@ python -m fedlearner.data_join.cmd.data_portal_master_service \ --output_base_dir=$OUTPUT_BASE_DIR \ --raw_data_publish_dir=$RAW_DATA_PUBLISH_DIR \ $input_file_wildcard $LONG_RUNNING $CHECK_SUCCESS_TAG \ - $kvstore_type $SINGLE_SUBFOLDER $files_per_job_limit + $kvstore_type $SINGLE_SUBFOLDER $files_per_job_limit \ + $start_date $end_date diff --git a/deploy/scripts/data_portal/run_data_portal_worker.sh b/deploy/scripts/data_portal/run_data_portal_worker.sh index d3c7344f6..58e195748 100755 --- a/deploy/scripts/data_portal/run_data_portal_worker.sh +++ b/deploy/scripts/data_portal/run_data_portal_worker.sh @@ -18,6 +18,7 @@ set -ex export CUDA_VISIBLE_DEVICES= source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true source /app/deploy/scripts/env_to_args.sh MASTER_POD_NAMES=`python -c 'import json, os; print(json.loads(os.environ["CLUSTER_SPEC"])["clusterSpec"]["Master"][0])'` diff --git a/deploy/scripts/env_to_args.sh b/deploy/scripts/env_to_args.sh index b4ab241e5..8913bc9f2 100755 --- a/deploy/scripts/env_to_args.sh +++ b/deploy/scripts/env_to_args.sh @@ -10,21 +10,30 @@ normalize_env_to_args() { return 0 } - pull_code() { cwd=$PWD cd $2 - if [[ $1 == "hdfs://"* ]]; then - ${HADOOP_HOME}/bin/hadoop fs -copyToLocal $1 code.tar.gz + if [[ $1 == "hdfs://"* || $1 == "viewfs://"* ]]; then + ${HADOOP_HOME}/bin/hadoop fs -copyToLocal $1 pulled_file elif [[ $1 == "http://"* || $1 == "https://"* ]]; then - wget $1 -O code.tar.gz + wget $1 -O pulled_file elif [[ $1 == "oss://"* ]]; then - python -c "import tensorflow.compat.v1 as tf; import tensorflow_io; open('code.tar.gz', 'wb').write(tf.io.gfile.GFile('$1', 'rb').read())" + python -c "import tensorflow as tf; import tensorflow_io; open('pulled_file', 'wb').write(tf.io.gfile.GFile('$1', 'rb').read())" elif [[ $1 == "base64://"* ]]; then - python -c "import base64; f = open('code.tar.gz', 'wb'); f.write(base64.b64decode('$1'[9:])); f.close()" + python -c "import base64; f = open('pulled_file', 'wb'); f.write(base64.b64decode('$1'[9:])); f.close()" + elif [[ $1 == "file://"* ]]; then + path=$1 + pure_path=${path#file://} + cp -r $pure_path pulled_file else - cp $1 code.tar.gz + cp -r $1 pulled_file fi - tar -zxvf code.tar.gz + + if [[ -d pulled_file ]]; then + mv pulled_file/* . + rm -r pulled_file + else + tar -zxvf pulled_file cd $cwd + fi } diff --git a/deploy/scripts/hdfs_common.sh b/deploy/scripts/hdfs_common.sh index c58366b5b..e80471766 100755 --- a/deploy/scripts/hdfs_common.sh +++ b/deploy/scripts/hdfs_common.sh @@ -2,5 +2,29 @@ set -ex -export LD_LIBRARY_PATH=${HADOOP_HOME}/lib/native:${JAVA_HOME}/jre/lib/amd64/server:${LD_LIBRARY_PATH} -export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$($HADOOP_HOME/bin/hadoop classpath --glob) +# When recongize HADOOP_HOME, export some also useful environment variables for GFile +if [ ! -z $HADOOP_HOME ] +then + echo "set hadoop env" + # This is super import for compitable with hadoop and hadoop_current + if [ -f "$HADOOP_HOME/conf/hadoop-env.sh" ] + then + export HADOOP_CONF_DIR=$HADOOP_HOME/conf + source "$HADOOP_HOME/conf/hadoop-env.sh" &> /dev/null + else + export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop + source "$HADOOP_HOME/etc/hadoop/hadoop-env.sh" &> /dev/null + fi + + if [[ "$USING_MT_HADOOP" == "True" ]]; then + echo "mt kerberos auth" + python3 /app/deploy/scripts/mt_auth_util.py ${HADOOP_USER_NAME} + export KRB5CCNAME=/tmp/krb5cc_0 + echo $KRB5CCNAME + fi + export LD_LIBRARY_PATH=${HADOOP_HOME}/lib/native:${HADOOP_HOME}/lib/native/nfs:${JAVA_HOME}/jre/lib/amd64/server:${LD_LIBRARY_PATH} + export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$($HADOOP_HOME/bin/hadoop classpath --glob) +else + echo "skipping hadoop env initialized..." +fi + diff --git a/deploy/scripts/pre_start_hook.sh b/deploy/scripts/pre_start_hook.sh new file mode 100644 index 000000000..5e684e44f --- /dev/null +++ b/deploy/scripts/pre_start_hook.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +python -c 'from fedlearner.common.hooks import pre_start_hook; pre_start_hook()' diff --git a/deploy/scripts/rsa_psi/run_raw_data_partitioner.sh b/deploy/scripts/rsa_psi/run_raw_data_partitioner.sh index 07461dec4..ab16113b4 100755 --- a/deploy/scripts/rsa_psi/run_raw_data_partitioner.sh +++ b/deploy/scripts/rsa_psi/run_raw_data_partitioner.sh @@ -21,7 +21,7 @@ source /app/deploy/scripts/hdfs_common.sh || true source /app/deploy/scripts/env_to_args.sh partitioner_name=$(normalize_env_to_args "--partitioner_name" $NAME) -input_file_wildcard=$(normalize_env_to_args "--input_file_wildcard" $FILE_WILDCARD) +input_file_wildcard=$(normalize_env_to_args "--input_file_wildcard" "$FILE_WILDCARD") raw_data_iter=$(normalize_env_to_args "--raw_data_iter" $FILE_FORMAT) compressed_type=$(normalize_env_to_args "--compressed_type" $COMPRESSED_TYPE) read_ahead_size=$(normalize_env_to_args "--read_ahead_size" $READ_AHEAD_SIZE) diff --git a/deploy/scripts/rsa_psi/run_rsa_psi_signer.sh b/deploy/scripts/rsa_psi/run_rsa_psi_signer.sh index 78cd484d2..e6eb0da40 100755 --- a/deploy/scripts/rsa_psi/run_rsa_psi_signer.sh +++ b/deploy/scripts/rsa_psi/run_rsa_psi_signer.sh @@ -27,8 +27,13 @@ signer_offload_processor_number=$(normalize_env_to_args "--signer_offload_proces # Turn off display to avoid RSA_KEY_PEM showing in log set +x +LISTEN_PORT=50051 +if [[ -n "${PORT0}" ]]; then + LISTEN_PORT=${PORT0} +fi + python -m fedlearner.data_join.cmd.rsa_psi_signer_service \ - --listen_port=50051 \ + --listen_port=${LISTEN_PORT} \ --rsa_private_key_path="$RSA_PRIVATE_KEY_PATH" \ --rsa_privet_key_pem="$RSA_KEY_PEM" \ $slow_sign_threshold $worker_num $signer_offload_processor_number diff --git a/deploy/scripts/sgx/enclave_env.sh b/deploy/scripts/sgx/enclave_env.sh new file mode 100755 index 000000000..8be67f851 --- /dev/null +++ b/deploy/scripts/sgx/enclave_env.sh @@ -0,0 +1,199 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +EXEC_DIR=/app/exec_dir +SGX_CONFIG_PATH="$GRPC_PATH/examples/dynamic_config.json" +TEMPLATE_PATH="/gramine/CI-Examples/generate-token/python.manifest.template" + +# 更新sgx的认证策略 +update_sgx_dynamic_config() { + local mr_enclave="$1" + local mr_signer="$2" + local isv_prod_id="$3" + local isv_svn="$4" + local json_data=$(cat "$SGX_CONFIG_PATH") + + # 创建json体 + local new_mrs=$(jq -n --arg mr_enclave "$mr_enclave" \ + --arg mr_signer "$mr_signer" \ + --arg isv_prod_id "$isv_prod_id" \ + --arg isv_svn "$isv_svn" \ + '{ + mr_enclave: $mr_enclave, + mr_signer: $mr_signer, + isv_prod_id: $isv_prod_id, + isv_svn: $isv_svn + }') + + # 检查sgx_mrs数组中是否存在相同的条目 + local exists=$(echo "$json_data" | jq --argjson check_mrs "$new_mrs" \ + '.sgx_mrs[] | select(.mr_enclave == $check_mrs.mr_enclave and .mr_signer == $check_mrs.mr_signer and .isv_prod_id == $check_mrs.isv_prod_id and .isv_svn == $check_mrs.isv_svn) | . != null') + + # 不重复添加 + if [[ -z "$exists" ]]; then + json_data=$(echo "$json_data" | jq --argjson new_mrs "$new_mrs" '.sgx_mrs += [$new_mrs]') + echo "$json_data" > "$SGX_CONFIG_PATH" + fi +} + +# 从sig中获取度量值hex +function get_env() { + gramine-sgx-get-token -s python.sig -o /dev/null | grep $1 | awk -F ":" '{print $2}' | xargs +} + +# 设置自定义环境 +function make_custom_env() { + cd $EXEC_DIR + + export DEBUG=0 + export CUDA_VISIBLE_DEVICES="" + export DNNL_VERBOSE=0 + export GRPC_VERBOSITY=ERROR + export GRPC_POLL_STRATEGY=epoll1 + export TF_CPP_MIN_LOG_LEVEL=1 + export TF_GRPC_SGX_RA_TLS_ENABLE=on + export FL_GRPC_SGX_RA_TLS_ENABLE=on + export TF_DISABLE_MKL=0 + export TF_ENABLE_MKL_NATIVE_FORMAT=1 + export parallel_num_threads=$1 + export INTRA_OP_PARALLELISM_THREADS=$parallel_num_threads + export INTER_OP_PARALLELISM_THREADS=$parallel_num_threads + export GRPC_SERVER_CHANNEL_THREADS=4 + export KMP_SETTINGS=1 + export KMP_BLOCKTIME=0 + export HADOOP_HOME=${HADOOP_HOME:-/opt/tiger/yarn_deploy/hadoop_current} + export PATH=$PATH:${HADOOP_HOME}/bin + export JAVA_HOME=/opt/tiger/jdk/openjdk-1.8.0_265 + export LD_LIBRARY_PATH=${HADOOP_HOME}/lib/native:${JAVA_HOME}/jre/lib/amd64/server:${LD_LIBRARY_PATH} + export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$($HADOOP_HOME/bin/hadoop classpath --glob) + export RA_TLS_ALLOW_OUTDATED_TCB_INSECURE=1 + + if [ -z "$PEER_MR_SIGNER" ]; then + export PEER_MR_SIGNER=`get_env mr_signer` + fi + + if [ -z "$PEER_MR_ENCLAVE" ]; then + export PEER_MR_ENCLAVE=`get_env mr_enclave` + fi + + update_sgx_dynamic_config $PEER_MR_ENCLAVE $PEER_MR_SIGNER 0 0 + cp $SGX_CONFIG_PATH $EXEC_DIR + cd - +} + +# 生成enclave和token +function generate_token() { + cd /gramine/CI-Examples/generate-token/ + ./generate.sh + update_sgx_dynamic_config `get_env mr_enclave` `get_env mr_signer` 0 0 + mkdir -p $EXEC_DIR + cp /app/sgx/gramine/CI-Examples/tensorflow_io.py $EXEC_DIR + cp python.sig $EXEC_DIR + cp python.manifest.sgx $EXEC_DIR + cp python.token $EXEC_DIR + cp python.manifest $EXEC_DIR + cd - +} + +# 根据enclave_size调整enclave +function build_enclave(){ + local enclave_size="$1" + local need_clean="$2" + sed -i "/sgx.enclave_size/ s/\"[^\"]*\"/\"$enclave_size\"/" "$TEMPLATE_PATH" + if [ $? -eq 0 ]; then + echo "Enclave size changed to $enclave_size in $TEMPLATE_PATH" + else + echo "Failed to change enclave size in $TEMPLATE_PATH" + fi + generate_token + if [ -n "$need_clean" ]; then + rm -rf $EXEC_DIR + fi +} + +function build_enclave_all(){ + local enclave_size="8G" + if [ -n "$1" ] && [ $1 == "ps" ]; then + # build worker/master + if [ -n "$GRAMINE_ENCLAVE_SIZE" ]; then + enclave_size=$GRAMINE_ENCLAVE_SIZE + fi + build_enclave $enclave_size 1 + + # build ps + if [ -n "$COSTOM_PS_SIZE" ]; then + enclave_size=$COSTOM_PS_SIZE + else + enclave_size="16G" + fi + build_enclave $enclave_size + else + # build ps + if [ -n "$COSTOM_PS_SIZE" ]; then + enclave_size=$COSTOM_PS_SIZE + else + enclave_size="16G" + fi + build_enclave $enclave_size 1 + + # build worker/master + if [ -n "$GRAMINE_ENCLAVE_SIZE" ]; then + enclave_size=$GRAMINE_ENCLAVE_SIZE + else + enclave_size="8G" + fi + build_enclave $enclave_size + fi +} + +if [ -n "$PCCS_IP" ]; then + sed -i "s|PCCS_URL=https://[^ ]*|PCCS_URL=https://pccs_url:8081/sgx/certification/v3/|" /etc/sgx_default_qcnl.conf + echo >> /etc/hosts + echo "$PCCS_IP pccs_url" | tee -a /etc/hosts +elif [ -n "$PCCS_URL" ]; then + sed -i "s|PCCS_URL=[^ ]*|PCCS_URL=$PCCS_URL|" /etc/sgx_default_qcnl.conf +fi +sed -i 's/USE_SECURE_CERT=TRUE/USE_SECURE_CERT=FALSE/' /etc/sgx_default_qcnl.conf + +if [ -n "$GRAMINE_LOG_LEVEL" ]; then + sed -i "/loader.log_level/ s/\"[^\"]*\"/\"$GRAMINE_LOG_LEVEL\"/" "$TEMPLATE_PATH" + if [ $? -eq 0 ]; then + echo "Log level changed to $GRAMINE_LOG_LEVEL in $TEMPLATE_PATH" + else + echo "Failed to change log level in $TEMPLATE_PATH" + fi +fi + +if [ -n "$GRAMINE_THREAD_NUM" ]; then + sed -i "s/sgx.thread_num = [0-9]\+/sgx.thread_num = $GRAMINE_THREAD_NUM/" "$TEMPLATE_PATH" + if [ $? -eq 0 ]; then + echo "Thread number changed to $GRAMINE_THREAD_NUM in $TEMPLATE_PATH" + else + echo "Failed to change thread number in $TEMPLATE_PATH" + fi +fi + +if [ -n "$GRAMINE_STACK_SIZE" ]; then + sed -i "/sys.stack.size/ s/\"[^\"]*\"/\"$GRAMINE_STACK_SIZE\"/" "$TEMPLATE_PATH" + if [ $? -eq 0 ]; then + echo "Stack size changed to $GRAMINE_STACK_SIZE in $TEMPLATE_PATH" + else + echo "Failed to change stack size in $TEMPLATE_PATH" + fi +fi + +mkdir -p /data +build_enclave_all $1 \ No newline at end of file diff --git a/deploy/scripts/sgx/get_token.sh b/deploy/scripts/sgx/get_token.sh new file mode 100755 index 000000000..cf978735a --- /dev/null +++ b/deploy/scripts/sgx/get_token.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +function get_token(){ + local need_clean=0 + cd /gramine/CI-Examples/generate-token/ + make clean > /dev/null + export SGX=1 + export SGX_SIGNER_KEY=/root/.config/gramine/enclave-key.pem + + # mkdir and make + if [ ! -d "/gramine/leader" ] || [ ! -d "/gramine/follower" ]; then + mkdir -p /gramine/leader + mkdir -p /gramine/follower + need_clean=1 + fi + make all > /dev/null + if [ $? -eq 0 ]; then + gramine-sgx-get-token -s python.sig -o /dev/null + fi + + # clean + make clean > /dev/null + if [ $need_clean==1 ]; then + rm -rf /gramine/leader + rm -rf /gramine/follower + fi + cd - +} + +get_token \ No newline at end of file diff --git a/deploy/scripts/sgx/run_data_join_master.sh b/deploy/scripts/sgx/run_data_join_master.sh new file mode 100755 index 000000000..4d631713f --- /dev/null +++ b/deploy/scripts/sgx/run_data_join_master.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +export CUDA_VISIBLE_DEVICES= +source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/env_to_args.sh + +kvstore_type=$(normalize_env_to_args '--kvstore_type' $KVSTORE_TYPE) + +source /app/deploy/scripts/sgx/enclave_env.sh +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ +unset HTTPS_PROXY https_proxy http_proxy ftp_proxy + +make_custom_env 4 + +python -m fedlearner.data_join.cmd.prepare_launch_data_join_cli \ + --data_source_name=$APPLICATION_ID \ + --partition_num=$PARTITION_NUM \ + --start_time=$START_TIME \ + --end_time=$END_TIME \ + --negative_sampling_rate=$NEGATIVE_SAMPLING_RATE \ + --role=$ROLE \ + --output_base_dir=$OUTPUT_BASE_DIR \ + --raw_data_sub_dir=$RAW_DATA_SUB_DIR \ + $kvstore_type + +python -m fedlearner.data_join.cmd.data_join_master_service \ + $PEER_ADDR \ + --listen_port=50051 \ + --data_source_name=$APPLICATION_ID $BATCH_MODE \ + $kvstore_type diff --git a/deploy/scripts/sgx/run_data_join_worker.sh b/deploy/scripts/sgx/run_data_join_worker.sh new file mode 100755 index 000000000..e492e5fe2 --- /dev/null +++ b/deploy/scripts/sgx/run_data_join_worker.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +export CUDA_VISIBLE_DEVICES= +source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/env_to_args.sh + +MASTER_POD_NAMES=`python -c 'import json, os; print(json.loads(os.environ["CLUSTER_SPEC"])["clusterSpec"]["Master"][0])'` + +raw_data_iter=$(normalize_env_to_args "--raw_data_iter" $RAW_DATA_ITER) +compressed_type=$(normalize_env_to_args "--compressed_type" $COMPRESSED_TYPE) +read_ahead_size=$(normalize_env_to_args "--read_ahead_size" $READ_AHEAD_SIZE) +read_batch_size=$(normalize_env_to_args "--read_batch_size" $READ_BATCH_SIZE) +example_joiner=$(normalize_env_to_args "--example_joiner" $EXAMPLE_JOINER) +min_matching_window=$(normalize_env_to_args "--min_matching_window" $MIN_MATCHING_WINDOW) +max_matching_window=$(normalize_env_to_args "--max_matching_window" $MAX_MATCHING_WINDOW) +data_block_dump_interval=$(normalize_env_to_args "--data_block_dump_interval" $DATA_BLOCK_DUMP_INTERVAL) +data_block_dump_threshold=$(normalize_env_to_args "--data_block_dump_threshold" $DATA_BLOCK_DUMP_THRESHOLD) +example_id_dump_interval=$(normalize_env_to_args "--example_id_dump_interval" $EXAMPLE_ID_DUMP_INTERVAL) +example_id_dump_threshold=$(normalize_env_to_args "--example_id_dump_threshold" $EXAMPLE_ID_DUMP_THRESHOLD) +data_block_builder=$(normalize_env_to_args "--data_block_builder" $DATA_BLOCK_BUILDER) +data_block_compressed_type=$(normalize_env_to_args "--data_block_compressed_type" $DATA_BLOCK_COMPRESSED_TYPE) +kvstore_type=$(normalize_env_to_args '--kvstore_type' $KVSTORE_TYPE) +max_conversion_delay=$(normalize_env_to_args '--max_conversion_delay' $MAX_CONVERSION_DELAY) +enable_negative_example_generator=$(normalize_env_to_args '--enable_negative_example_generator' $ENABLE_NEGATIVE_EXAMPLE_GENERATOR) +negative_sampling_rate=$(normalize_env_to_args '--negative_sampling_rate' $NEGATIVE_SAMPLING_RATE) +optional_fields=$(normalize_env_to_args '--optional_fields' $OPTIONAL_FIELDS) + +join_expr=$(normalize_env_to_args '--join_expr' ${JOIN_EXPR}) +negative_sampling_filter_expr=$(normalize_env_to_args '--negative_sampling_filter_expr' ${NEGATIVE_SAMPLING_FILTER_EXPR}) +raw_data_cache_type=$(normalize_env_to_args '--raw_data_cache_type' ${RAW_DATA_CACHE_TYPE}) +join_key_mapper=$(normalize_env_to_args '--join_key_mapper' ${JOIN_KEY_MAPPER}) + +if [ -n "$JOIN_KEY_MAPPER" ]; then + IFS='=' read -r -a mapper <<< "$JOIN_KEY_MAPPER" + echo "${mapper[0]}" + pull_code "${mapper[1]}" /app/fedlearner/data_join/key_mapper/impl + join_key_mapper=$(normalize_env_to_args '--join_key_mapper' "${mapper[0]}") +fi + +source /app/deploy/scripts/sgx/enclave_env.sh +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ +unset HTTPS_PROXY https_proxy http_proxy ftp_proxy + +make_custom_env 4 + +python -m fedlearner.data_join.cmd.data_join_worker_service \ + $PEER_ADDR \ + $MASTER_POD_NAMES \ + $INDEX \ + --listen_port=50051 \ + $raw_data_iter $compressed_type $read_ahead_size $read_batch_size \ + $example_joiner $min_matching_window $max_matching_window \ + $data_block_dump_interval $data_block_dump_threshold \ + $example_id_dump_interval $example_id_dump_threshold \ + $data_block_builder $data_block_compressed_type \ + $kvstore_type $max_conversion_delay \ + $enable_negative_example_generator $negative_sampling_rate \ + $join_expr $join_key_mapper $optional_fields $raw_data_cache_type $negative_sampling_filter_expr diff --git a/deploy/scripts/sgx/run_data_portal_master.sh b/deploy/scripts/sgx/run_data_portal_master.sh new file mode 100755 index 000000000..dcefe4fe0 --- /dev/null +++ b/deploy/scripts/sgx/run_data_portal_master.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +export CUDA_VISIBLE_DEVICES= +source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/env_to_args.sh + +input_file_wildcard=$(normalize_env_to_args "--input_file_wildcard" $FILE_WILDCARD) +kvstore_type=$(normalize_env_to_args '--kvstore_type' $KVSTORE_TYPE) +files_per_job_limit=$(normalize_env_to_args '--files_per_job_limit' $FILES_PER_JOB_LIMIT) + +source /app/deploy/scripts/sgx/enclave_env.sh +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ +unset HTTPS_PROXY https_proxy http_proxy ftp_proxy + +make_custom_env 4 + +taskset -c 0-3 stdbuf -o0 gramine-sgx python -m fedlearner.data_join.cmd.data_portal_master_service \ + --listen_port=50051 \ + --data_portal_name=$DATA_PORTAL_NAME \ + --data_portal_type=$DATA_PORTAL_TYPE \ + --output_partition_num=$OUTPUT_PARTITION_NUM \ + --input_base_dir=$INPUT_BASE_DIR \ + --output_base_dir=$OUTPUT_BASE_DIR \ + --raw_data_publish_dir=$RAW_DATA_PUBLISH_DIR \ + $input_file_wildcard $LONG_RUNNING $CHECK_SUCCESS_TAG \ + $kvstore_type $SINGLE_SUBFOLDER $files_per_job_limit diff --git a/deploy/scripts/sgx/run_data_portal_worker.sh b/deploy/scripts/sgx/run_data_portal_worker.sh new file mode 100755 index 000000000..e741860fd --- /dev/null +++ b/deploy/scripts/sgx/run_data_portal_worker.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +export CUDA_VISIBLE_DEVICES= +source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/env_to_args.sh + +MASTER_POD_NAMES=`python -c 'import json, os; print(json.loads(os.environ["CLUSTER_SPEC"])["clusterSpec"]["Master"][0])'` + +merger_read_ahead_size=$(normalize_env_to_args "--merger_read_ahead_size" $MERGE_READ_AHEAD_SIZE) +merger_read_batch_size=$(normalize_env_to_args "--merger_read_batch_size" $MERGE_READ_BATCH_SIZE) +input_data_file_iter=$(normalize_env_to_args "--input_data_file_iter" $INPUT_DATA_FORMAT) +compressed_type=$(normalize_env_to_args "--compressed_type" $COMPRESSED_TYPE) +read_ahead_size=$(normalize_env_to_args "--read_ahead_size" $READ_AHEAD_SIZE) +read_batch_size=$(normalize_env_to_args "--read_batch_size" $READ_BATCH_SIZE) +output_builder=$(normalize_env_to_args "--output_builder" $OUTPUT_DATA_FORMAT) +builder_compressed_type=$(normalize_env_to_args "--builder_compressed_type" $BUILDER_COMPRESSED_TYPE) +batch_size=$(normalize_env_to_args "--batch_size" $BATCH_SIZE) +kvstore_type=$(normalize_env_to_args '--kvstore_type' $KVSTORE_TYPE) +memory_limit_ratio=$(normalize_env_to_args '--memory_limit_ratio' $MEMORY_LIMIT_RATIO) +optional_fields=$(normalize_env_to_args '--optional_fields' $OPTIONAL_FIELDS) +input_data_validation_ratio=$(normalize_env_to_args '--input_data_validation_ratio' $INPUT_DATA_VALIDATION_RATIO) + +source /app/deploy/scripts/sgx/enclave_env.sh +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ +unset HTTPS_PROXY https_proxy http_proxy ftp_proxy + +make_custom_env 4 + +taskset -c 0-3 stdbuf -o0 gramine-sgx python -m fedlearner.data_join.cmd.data_portal_worker_cli \ + --rank_id=$INDEX \ + --master_addr=$MASTER_POD_NAMES \ + $input_data_file_iter $compressed_type $read_ahead_size $read_batch_size \ + $output_builder $builder_compressed_type \ + $batch_size $kvstore_type $memory_limit_ratio \ + $optional_fields $input_data_validation_ratio + diff --git a/deploy/scripts/sgx/run_psi_data_join_follower_worker_v2.sh b/deploy/scripts/sgx/run_psi_data_join_follower_worker_v2.sh new file mode 100755 index 000000000..549a45ab8 --- /dev/null +++ b/deploy/scripts/sgx/run_psi_data_join_follower_worker_v2.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +psi_preprocessor_cmd=/app/deploy/scripts/sgx/run_psi_preprocessor.sh +data_join_worker_cmd=/app/deploy/scripts/sgx/run_data_join_worker.sh + +echo "launch ras psi preprocessor at front ground" +${psi_preprocessor_cmd} +echo "ras psi preprocessor run finished" + +TCP_MSL=60 +if [ -f "/proc/sys/net/ipv4/tcp_fin_timeout" ] +then + TCP_MSL=`cat /proc/sys/net/ipv4/tcp_fin_timeout` +fi +SLEEP_TM=$((TCP_MSL * 3)) +echo "sleep 3msl($SLEEP_TM) to make sure tcp state at CLOSED" +sleep $SLEEP_TM + +echo "launch data join worker" +export RAW_DATA_ITER=$PSI_OUTPUT_BUILDER +export COMPRESSED_TYPE=$PSI_OUTPUT_BUILDER_COMPRESSED_TYPE +${data_join_worker_cmd} +echo "data join worker finished" diff --git a/deploy/scripts/sgx/run_psi_data_join_leader_worker_v2.sh b/deploy/scripts/sgx/run_psi_data_join_leader_worker_v2.sh new file mode 100755 index 000000000..7089390f7 --- /dev/null +++ b/deploy/scripts/sgx/run_psi_data_join_leader_worker_v2.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +psi_signer_cmd=/app/deploy/scripts/sgx/run_rsa_psi_signer.sh +psi_preprocessor_cmd=/app/deploy/scripts/sgx/run_psi_preprocessor.sh +data_join_worker_cmd=/app/deploy/scripts/sgx/run_data_join_worker.sh + + +if [ -z "$CPU_LIMIT" ] && ([ -z "$PREPROCESSOR_OFFLOAD_PROCESSOR_NUMBER" ] || [ -z $SIGNER_OFFLOAD_PROCESSOR_NUMBER ]) +then + echo "Can't infer preprocessor_offload_processor_number for psi preprocessor and signer_offload_processor_number for psi signer" + exit -1 +fi + +if [ "$PREPROCESSOR_OFFLOAD_PROCESSOR_NUMBER" ] +then + echo "the user set preprocessor_offload_processor_number($PREPROCESSOR_OFFLOAD_PROCESSOR_NUMBER)" +elif [ "$SIGNER_OFFLOAD_PROCESSOR_NUMBER" ] +then + export PREPROCESSOR_OFFLOAD_PROCESSOR_NUMBER=$(($CPU_LIMIT-$SIGNER_OFFLOAD_PROCESSOR_NUMBER-2)) + echo "we set preprocessor_offload_processor_number($PREPROCESSOR_OFFLOAD_PROCESSOR_NUMBER) by cpu_limit($CPU_LIMIT)-signer_offload_processor_number($SIGNER_OFFLOAD_PROCESSOR_NUMBER)-RESERVED_CPU(2)" +else + echo "we set preprocessor_offload_processor_number($PREPROCESSOR_OFFLOAD_PROCESSOR_NUMBER) by (cpu_limit($CPU_LIMIT)-reserved_cpu(2))/2" + export PREPROCESSOR_OFFLOAD_PROCESSOR_NUMBER=$((($CPU_LIMIT-2)/2)) +fi + +echo "launch the leader of psi preprocessor at background" +exec ${psi_preprocessor_cmd} & + +if [ "$SIGNER_OFFLOAD_PROCESSOR_NUMBER" ] +then + echo "the user set signer_offload_processor_number($SIGNER_OFFLOAD_PROCESSOR_NUMBER)" +else + export SIGNER_OFFLOAD_PROCESSOR_NUMBER=$(($CPU_LIMIT-$PREPROCESSOR_OFFLOAD_PROCESSOR_NUMBER-2)) + echo "we set signer_offload_processor_number($SIGNER_OFFLOAD_PROCESSOR_NUMBER) by cpu_limit($CPU_LIMIT)-preprocessor_offload_processor_number($PREPROCESSOR_OFFLOAD_PROCESSOR_NUMBER)-RESERVED_CPU(2)" +fi +echo "launch psi signer for follower of psi preprocessor at front ground" +${psi_signer_cmd} +echo "psi signer for follower of psi preprocessor finish" + +TCP_MSL=60 +if [ -f "/proc/sys/net/ipv4/tcp_fin_timeout" ] +then + TCP_MSL=`cat /proc/sys/net/ipv4/tcp_fin_timeout` +fi +SLEEP_TM=$((TCP_MSL * 3)) +echo "sleep 3msl($SLEEP_TM) to make sure tcp state at CLOSED" +sleep $SLEEP_TM + +echo "launch data join worker" +export RAW_DATA_ITER=$PSI_OUTPUT_BUILDER +export COMPRESSED_TYPE=$PSI_OUTPUT_BUILDER_COMPRESSED_TYPE +${data_join_worker_cmd} +echo "data join worker finish" + +echo "waiting for background psi preprocessor exit" +wait diff --git a/deploy/scripts/sgx/run_psi_data_join_master.sh b/deploy/scripts/sgx/run_psi_data_join_master.sh new file mode 100755 index 000000000..2ed436bfd --- /dev/null +++ b/deploy/scripts/sgx/run_psi_data_join_master.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +data_join_master_cmd=/app/deploy/scripts/sgx/run_data_join_master.sh + +export RAW_DATA_SUB_DIR="portal_publish_dir/${APPLICATION_ID}_psi_preprocess" + +# Reverse the role assignment for data join so that leader for PSI preprocessor +# becomes follower for data join. Data join's workers get their role from +# master so we don't need to do this for worker. +if [ $ROLE == "leader" ]; then + export ROLE="follower" +else + export ROLE="leader" +fi + +${data_join_master_cmd} diff --git a/deploy/scripts/sgx/run_psi_data_join_worker.sh b/deploy/scripts/sgx/run_psi_data_join_worker.sh new file mode 100755 index 000000000..222282682 --- /dev/null +++ b/deploy/scripts/sgx/run_psi_data_join_worker.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +psi_data_join_leader_worker_cmd=/app/deploy/scripts/sgx/run_psi_data_join_leader_worker_v2.sh +psi_data_join_follower_worker_cmd=/app/deploy/scripts/sgx/run_psi_data_join_follower_worker_v2.sh + +export INPUT_FILE_SUBSCRIBE_DIR=$RAW_DATA_SUB_DIR +export RAW_DATA_PUBLISH_DIR="portal_publish_dir/${APPLICATION_ID}_psi_preprocess" +if [ $ROLE == "leader" ]; then + ${psi_data_join_leader_worker_cmd} +else + ${psi_data_join_follower_worker_cmd} +fi diff --git a/deploy/scripts/sgx/run_psi_preprocessor.sh b/deploy/scripts/sgx/run_psi_preprocessor.sh new file mode 100755 index 000000000..d32f41bb9 --- /dev/null +++ b/deploy/scripts/sgx/run_psi_preprocessor.sh @@ -0,0 +1,84 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +export CUDA_VISIBLE_DEVICES= +source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/env_to_args.sh + +if [ -z "$INPUT_BASE_DIR" ] && [ -z "$INPUT_FILE_PATHS" ] && [ -z "$INPUT_FILE_SUBSCRIBE_DIR" ] +then + echo "no input files or directory for psi preprocessor or mysql subscrube dir" + exit -1 +fi + +FROLE=`echo $ROLE | tr 'a-z' 'A-Z'` +if [ "$FROLE" = "FOLLOWER" ] && [ -z "$PEER_ADDR" ] +then + echo "PEER_ADDR should be set for psi preprocessor follower" + exit -1 +fi + +preprocessor_name=$(normalize_env_to_args "--preprocessor_name" $APPLICATION_ID) +input_file_paths=$(normalize_env_to_args "--input_file_paths" $INPUT_FILE_PATHS) +if [ -z "$INPUT_BASE_DIR" ] +then + input_dir="" +else + input_dir="--input_dir=$INPUT_BASE_DIR/partition_`echo $INDEX|awk '{printf("%04d\n",$0)}'`" +fi +input_file_subscribe_dir=$(normalize_env_to_args "--input_file_subscribe_dir" $INPUT_FILE_SUBSCRIBE_DIR) +leader_rsa_psi_signer_addr=$(normalize_env_to_args "--leader_rsa_psi_signer_addr" $PEER_ADDR) +process_batch_size=$(normalize_env_to_args "--process_batch_size" $PSI_PROCESS_BATCH_SIZE) +max_flying_sign_batch=$(normalize_env_to_args "--max_flying_sign_batch" $MAX_FLYING_SIGNED_BATCH) +max_flying_sign_rpc=$(normalize_env_to_args "--max_flying_sign_rpc" $MAX_FLYING_SIGN_RPC) +sign_rpc_timeout_ms=$(normalize_env_to_args "--sign_rpc_timeout_ms" $SIGN_RPC_TIMEOUT_MS) +stub_fanout=$(normalize_env_to_args "--stub_fanout" $STUB_FANOUT) +slow_sign_threshold=$(normalize_env_to_args "--slow_sign_threshold" $SLOW_SIGN_THRESHOLD) +sort_run_merger_read_ahead_buffer=$(normalize_env_to_args "--sort_run_merger_read_ahead_buffer" $SORT_RUN_MERGER_READ_AHEAD_BUFFER) +raw_data_iter=$(normalize_env_to_args "--raw_data_iter" $PSI_RAW_DATA_ITER) +compressed_type=$(normalize_env_to_args "--compressed_type" $PSI_COMPRESSED_TYPE) +read_ahead_size=$(normalize_env_to_args "--read_ahead_size" $PSI_READ_AHEAD_SIZE) +read_batch_size=$(normalize_env_to_args "--read_batch_size" $PSI_READ_BATCH_SIZE) + +output_builder=$(normalize_env_to_args "--output_builder" $PSI_OUTPUT_BUILDER) +builder_compressed_type=$(normalize_env_to_args "--builder_compressed_type" $PSI_OUTPUT_BUILDER_COMPRESSED_TYPE) +preprocessor_offload_processor_number=$(normalize_env_to_args "--preprocessor_offload_processor_number" $PREPROCESSOR_OFFLOAD_PROCESSOR_NUMBER) +kvstore_type=$(normalize_env_to_args '--kvstore_type' $KVSTORE_TYPE) + + +# Turn off display to avoid RSA_KEY_PEM showing in log +set +x + +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ +unset HTTPS_PROXY https_proxy http_proxy ftp_proxy + +python -m fedlearner.data_join.cmd.rsa_psi_preprocessor_cli \ + --psi_role=$ROLE \ + --rsa_key_path="$RSA_KEY_PATH" \ + --rsa_key_pem="$RSA_KEY_PEM" \ + --output_file_dir="$OUTPUT_BASE_DIR/psi_output" \ + --raw_data_publish_dir=$RAW_DATA_PUBLISH_DIR \ + --partition_id=$INDEX \ + $preprocessor_name $input_file_paths $input_dir $input_file_subscribe_dir \ + $max_flying_sign_batch $slow_sign_threshold \ + $sort_run_merger_read_ahead_buffer \ + $leader_rsa_psi_signer_addr $max_flying_sign_rpc $sign_rpc_timeout_ms \ + $stub_fanout $process_batch_size \ + $raw_data_iter $compressed_type $read_ahead_size $read_batch_size \ + $output_builder $builder_compressed_type $preprocessor_offload_processor_number \ + $kvstore_type diff --git a/deploy/scripts/sgx/run_rsa_psi_signer.sh b/deploy/scripts/sgx/run_rsa_psi_signer.sh new file mode 100755 index 000000000..569842c7b --- /dev/null +++ b/deploy/scripts/sgx/run_rsa_psi_signer.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +export CUDA_VISIBLE_DEVICES= +source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/env_to_args.sh + +slow_sign_threshold=$(normalize_env_to_args "--slow_sign_threshold" $SLOW_SIGN_THRESHOLD) +worker_num=$(normalize_env_to_args "--worker_num" $WORKER_NUM) +signer_offload_processor_number=$(normalize_env_to_args "--signer_offload_processor_number" $SIGNER_OFFLOAD_PROCESSOR_NUMBER) + +# Turn off display to avoid RSA_KEY_PEM showing in log +set +x + +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ +unset HTTPS_PROXY https_proxy http_proxy ftp_proxy + +python -m fedlearner.data_join.cmd.rsa_psi_signer_service \ + --listen_port=50051 \ + --rsa_private_key_path="$RSA_PRIVATE_KEY_PATH" \ + --rsa_privet_key_pem="$RSA_KEY_PEM" \ + $slow_sign_threshold $worker_num $signer_offload_processor_number diff --git a/deploy/scripts/sgx/run_trainer_master_sgx.sh b/deploy/scripts/sgx/run_trainer_master_sgx.sh new file mode 100755 index 000000000..41f74b29a --- /dev/null +++ b/deploy/scripts/sgx/run_trainer_master_sgx.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex +source ~/.env +export CUDA_VISIBLE_DEVICES= +unset HTTPS_PROXY https_proxy http_proxy ftp_proxy +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ +source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true +source /app/deploy/scripts/env_to_args.sh + +mode=$(normalize_env_to_args "--mode" "$MODE") +sparse_estimator=$(normalize_env_to_args "--sparse-estimator" "$SPARSE_ESTIMATOR") +save_checkpoint_steps=$(normalize_env_to_args "--save-checkpoint-steps" "$SAVE_CHECKPOINT_STEPS") +save_checkpoint_secs=$(normalize_env_to_args "--save-checkpoint-secs" "$SAVE_CHECKPOINT_SECS") +summary_save_steps=$(normalize_env_to_args "--summary-save-steps" "$SUMMARY_SAVE_STEPS") +summary_save_secs=$(normalize_env_to_args "--summary-save-secs" "$SUMMARY_SAVE_SECS") +epoch_num=$(normalize_env_to_args "--epoch-num" $EPOCH_NUM) +start_date=$(normalize_env_to_args "--start-date" $START_DATE) +end_date=$(normalize_env_to_args "--end-date" $END_DATE) +extra_params=$(normalize_env_to_args "--extra-params" "$EXTRA_PARAMS") +export_model=$(normalize_env_to_args "--export-model" $EXPORT_MODEL) +shuffle=$(normalize_env_to_args "--shuffle" $SUFFLE_DATA_BLOCK) +shuffle_in_day=$(normalize_env_to_args "--shuffle-in-day" $SHUFFLE_IN_DAY) +local_data_source=$(normalize_env_to_args "--local-data-source" $LOCAL_DATA_SOURCE) +local_data_path=$(normalize_env_to_args "--local-data-path" $LOCAL_DATA_PATH) +local_start_date=$(normalize_env_to_args "--local-start-date" $LOCAL_START_DATE) +local_end_date=$(normalize_env_to_args "--local-end-date" $LOCAL_END_DATE) +using_mt_hadoop=$(normalize_env_to_args "--using_mt_hadoop" $USING_MT_HADOOP) + +if [ -n "$CHECKPOINT_PATH" ]; then + checkpoint_path="--checkpoint-path=$CHECKPOINT_PATH" +else + checkpoint_path="--checkpoint-path=$OUTPUT_BASE_DIR/checkpoints" +fi +load_checkpoint_path=$(normalize_env_to_args "--load-checkpoint-path" "$LOAD_CHECKPOINT_PATH") +load_checkpoint_filename=$(normalize_env_to_args "--load-checkpoint-filename" "$LOAD_CHECKPOINT_FILENAME") +load_checkpoint_filename_with_path=$(normalize_env_to_args "--load-checkpoint-filename-with-path" "$LOAD_CHECKPOINT_FILENAME_WITH_PATH") + +if [[ -n "$EXPORT_PATH" ]]; then + export_path="--export-path=$EXPORT_PATH" +else + export_path="--export-path=$OUTPUT_BASE_DIR/exported_models" +fi + +if [ -n "$CLUSTER_SPEC" ]; then + # rewrite tensorflow ClusterSpec for compatibility + # master port 50051 is used for fedlearner master server, so rewrite to 50052 + # worker port 50051 is used for fedlearner worker server, so rewrite to 50052 + CLUSTER_SPEC=`python -c """ +import json +def rewrite_port(address, old, new): + (host, port) = address.rsplit(':', 1) + if port == old: + return host + ':' + new + return address + +cluster_spec = json.loads('$CLUSTER_SPEC')['clusterSpec'] +for i, ps in enumerate(cluster_spec.get('PS', [])): + cluster_spec['PS'][i] = rewrite_port(ps, '50051', '50052') +for i, master in enumerate(cluster_spec.get('Master', [])): + cluster_spec['Master'][i] = rewrite_port(master, '50051', '50052') +for i, worker in enumerate(cluster_spec.get('Worker', [])): + cluster_spec['Worker'][i] = rewrite_port(worker, '50051', '50052') +if 'LocalWorker' in cluster_spec: + for i, worker in enumerate(cluster_spec.get('LocalWorker', [])): + cluster_spec['Worker'].append(rewrite_port(worker, '50051', '50052')) + del cluster_spec['LocalWorker'] +print(json.dumps({'clusterSpec': cluster_spec})) +"""` +fi + +if [[ -n "${CODE_KEY}" ]]; then + pull_code ${CODE_KEY} $PWD +else + pull_code ${CODE_TAR} $PWD +fi + +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py /gramine/follower/ +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py /gramine/leader/ +source /app/deploy/scripts/sgx/enclave_env.sh master + +unset HTTPS_PROXY https_proxy http_proxy ftp_proxy + +make_custom_env 4 +source /root/start_aesm_service.sh + +LISTEN_PORT=50051 +if [[ -n "${PORT0}" ]]; then + LISTEN_PORT=${PORT0} +fi + +server_port=$(normalize_env_to_args "--server-port" "$PORT1") + +cd $EXEC_DIR +if [[ -z "${START_CPU_SN}" ]]; then + START_CPU_SN=0 +fi +if [[ -z "${END_CPU_SN}" ]]; then + END_CPU_SN=3 +fi + +taskset -c $START_CPU_SN-$END_CPU_SN stdbuf -o0 gramine-sgx python /gramine/$ROLE/main.py --master \ + --application-id=$APPLICATION_ID \ + --data-source=$DATA_SOURCE \ + --data-path=$DATA_PATH \ + --data-path-wildcard=$DATA_PATH_WILDCARD \ + --master-addr=0.0.0.0:${LISTEN_PORT} \ + --cluster-spec="$CLUSTER_SPEC" \ + $server_port \ + $checkpoint_path $load_checkpoint_path \ + $load_checkpoint_filename $load_checkpoint_filename_with_path \ + $export_path \ + $mode $sparse_estimator \ + $save_checkpoint_steps $save_checkpoint_secs \ + $summary_save_steps $summary_save_secs \ + $local_data_source $local_data_path $local_start_date \ + $local_end_date $epoch_num $start_date $end_date \ + $shuffle $shuffle_in_day $extra_params $export_model \ + $using_mt_hadoop diff --git a/deploy/scripts/sgx/run_trainer_ps_sgx.sh b/deploy/scripts/sgx/run_trainer_ps_sgx.sh new file mode 100755 index 000000000..de156bf6b --- /dev/null +++ b/deploy/scripts/sgx/run_trainer_ps_sgx.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex +source ~/.env +export CUDA_VISIBLE_DEVICES= +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ +unset HTTPS_PROXY https_proxy http_proxy ftp_proxy +source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true +source /app/deploy/scripts/env_to_args.sh + +LISTEN_PORT=50052 +if [[ -n "${PORT1}" ]]; then + LISTEN_PORT=${PORT1} +fi + +if [[ -n "${CODE_KEY}" ]]; then + pull_code ${CODE_KEY} $PWD +else + pull_code ${CODE_TAR} $PWD +fi + +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py /gramine/leader +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py /gramine/follower +source /app/deploy/scripts/sgx/enclave_env.sh ps + +make_custom_env 4 +source /root/start_aesm_service.sh + +cd $EXEC_DIR +if [[ -z "${START_CPU_SN}" ]]; then + START_CPU_SN=0 +fi +if [[ -z "${END_CPU_SN}" ]]; then + END_CPU_SN=3 +fi + +taskset -c $START_CPU_SN-$END_CPU_SN stdbuf -o0 gramine-sgx python -m fedlearner.trainer.parameter_server $POD_IP:${LISTEN_PORT} diff --git a/deploy/scripts/sgx/run_trainer_worker_sgx.sh b/deploy/scripts/sgx/run_trainer_worker_sgx.sh new file mode 100755 index 000000000..1771f75fc --- /dev/null +++ b/deploy/scripts/sgx/run_trainer_worker_sgx.sh @@ -0,0 +1,125 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex +source ~/.env +export CUDA_VISIBLE_DEVICES= +export MODEL_NAME=${APPLICATION_ID} + +LISTEN_PORT=50051 +if [[ -n "${PORT0}" ]]; then + LISTEN_PORT=${PORT0} +fi +echo $LISTEN_PORT > /pod-data/listen_port + +PROXY_LOCAL_PORT=50053 +if [[ -n "${PORT2}" ]]; then + PROXY_LOCAL_PORT=${PORT2} +fi +echo $PROXY_LOCAL_PORT > /pod-data/proxy_local_port + +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ +unset HTTPS_PROXY https_proxy http_proxy ftp_proxy +source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true +source /app/deploy/scripts/env_to_args.sh + +PEER_ADDR="localhost:${PROXY_LOCAL_PORT}" + +if [[ -n "${CODE_KEY}" ]]; then + pull_code ${CODE_KEY} $PWD +else + pull_code ${CODE_TAR} $PWD +fi + +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py /gramine/follower/ +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py /gramine/leader/ +source /app/deploy/scripts/sgx/enclave_env.sh worker + +mode=$(normalize_env_to_args "--mode" "$MODE") +sparse_estimator=$(normalize_env_to_args "--sparse-estimator" "$SPARSE_ESTIMATOR") +batch_size=$(normalize_env_to_args "--batch-size" "$BATCH_SIZE") +learning_rate=$(normalize_env_to_args "--learning-rate" "$LEARNING_RATE") +extra_params=$(normalize_env_to_args "--extra-params" "$EXTRA_PARAMS") + +using_embedding_protection=$(normalize_env_to_args "--using_embedding_protection" $USING_EMBEDDING_PROTECTION) +using_marvell_protection=$(normalize_env_to_args "--using_marvell_protection" $USING_MARVELL_PROTECTION) +discorloss_weight=$(normalize_env_to_args "--discorloss_weight" $DISCORLOSS_WEIGHT) +sumkl_threshold=$(normalize_env_to_args "--sumkl_threshold" $SUMKL_THRESHOLD) +using_emb_attack=$(normalize_env_to_args "--using_emb_attack" $USING_EMB_ATTACK) +using_norm_attack=$(normalize_env_to_args "--using_norm_attack" $USING_NORM_ATTACK) +using_mt_hadoop=$(normalize_env_to_args "--using_mt_hadoop" $USING_MT_HADOOP) + + +if [ -n "$CLUSTER_SPEC" ]; then + # get master address from clusteSpec["master"] + MASTER_HOST=`python -c " +import json +cluster_spec = json.loads('$CLUSTER_SPEC')['clusterSpec'] +if 'Master' in cluster_spec: + print(cluster_spec['Master'][0].split(':')[0]) +"` + + # rewrite tensorflow ClusterSpec for compatibility + # master port 50051 is used for fedlearner master server, so rewrite to 50052 + # worker port 50051 is used for fedlearner worker server, so rewrite to 50052 + CLUSTER_SPEC=`python -c """ +import json +def rewrite_port(address, old, new): + (host, port) = address.rsplit(':', 1) + if port == old: + return host + ':' + new + return address + +cluster_spec = json.loads('$CLUSTER_SPEC')['clusterSpec'] +for i, ps in enumerate(cluster_spec.get('PS', [])): + cluster_spec['PS'][i] = rewrite_port(ps, '50051', '50052') +for i, master in enumerate(cluster_spec.get('Master', [])): + cluster_spec['Master'][i] = rewrite_port(master, '50051', '50052') +for i, worker in enumerate(cluster_spec.get('Worker', [])): + cluster_spec['Worker'][i] = rewrite_port(worker, '50051', '50052') +if 'LocalWorker' in cluster_spec: + for i, worker in enumerate(cluster_spec.get('LocalWorker', [])): + cluster_spec['Worker'].append(rewrite_port(worker, '50051', '50052')) + del cluster_spec['LocalWorker'] +print(json.dumps({'clusterSpec': cluster_spec})) +"""` +fi + +make_custom_env 4 +source /root/start_aesm_service.sh + +server_port=$(normalize_env_to_args "--server-port" "$PORT1") + +cd $EXEC_DIR +if [[ -z "${START_CPU_SN}" ]]; then + START_CPU_SN=0 +fi +if [[ -z "${END_CPU_SN}" ]]; then + END_CPU_SN=3 +fi + +taskset -c $START_CPU_SN-$END_CPU_SN stdbuf -o0 gramine-sgx python /gramine/$ROLE/main.py --worker \ + --application-id="$APPLICATION_ID" \ + --master-addr="$MASTER_HOST:50051" \ + --cluster-spec="$CLUSTER_SPEC" \ + --local-addr="$POD_IP:${LISTEN_PORT}" \ + --peer-addr="$PEER_ADDR" \ + --worker-rank="$INDEX" \ + $server_port $mode $batch_size \ + $sparse_estimator $learning_rate \ + $using_embedding_protection $using_marvell_protection $discorloss_weight $sumkl_threshold $using_emb_attack $using_norm_attack \ + $using_mt_hadoop diff --git a/deploy/scripts/trainer/run_fedavg.sh b/deploy/scripts/trainer/run_fedavg.sh new file mode 100755 index 000000000..00225fea7 --- /dev/null +++ b/deploy/scripts/trainer/run_fedavg.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -ex + +source /app/deploy/scripts/hdfs_common.sh +source /app/deploy/scripts/env_to_args.sh + +if [[ -n "${CODE_KEY}" ]]; then + pull_code ${CODE_KEY} $PWD +fi + +LISTEN_PORT=50051 +if [[ -n "${PORT0}" ]]; then + LISTEN_PORT=${PORT0} +fi + +if [[ $ROLE == "leader" ]]; then + export FL_LEADER_ADDRESS="0.0.0.0:${LISTEN_PORT}" +elif [[ -n $PEER_ADDR ]]; then + export FL_LEADER_ADDRESS=$PEER_ADDR +fi + +python $ROLE.py diff --git a/deploy/scripts/trainer/run_merge_scores.sh b/deploy/scripts/trainer/run_merge_scores.sh index 11dbc8258..a7a5f75ea 100644 --- a/deploy/scripts/trainer/run_merge_scores.sh +++ b/deploy/scripts/trainer/run_merge_scores.sh @@ -18,6 +18,7 @@ set -ex export CUDA_VISIBLE_DEVICES= source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true python example/tree_model/merge_scores.py \ --worker-rank=$WORKER_RANK \ diff --git a/deploy/scripts/trainer/run_trainer_local_worker.sh b/deploy/scripts/trainer/run_trainer_local_worker.sh new file mode 100755 index 000000000..78e0b974f --- /dev/null +++ b/deploy/scripts/trainer/run_trainer_local_worker.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +set -ex + +export CUDA_VISIBLE_DEVICES= +export MODEL_NAME=${APPLICATION_ID} + +source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true +source /app/deploy/scripts/env_to_args.sh + +if [[ -n "${CODE_KEY}" ]]; then + pull_code ${CODE_KEY} $PWD +else + pull_code ${CODE_TAR} $PWD +fi + +cd ${ROLE} + +mode=$(normalize_env_to_args "--mode" "$MODE") +sparse_estimator=$(normalize_env_to_args "--sparse-estimator" "$SPARSE_ESTIMATOR") +batch_size=$(normalize_env_to_args "--batch-size" "$BATCH_SIZE") +learning_rate=$(normalize_env_to_args "--learning-rate" "$LEARNING_RATE") + +if [ -n "$CLUSTER_SPEC" ]; then + # get master address from clusteSpec["master"] + MASTER_HOST=`python -c " +import json +cluster_spec = json.loads('$CLUSTER_SPEC')['clusterSpec'] +if 'Master' in cluster_spec: + print(cluster_spec['Master'][0].split(':')[0]) +"` + NUM_WORKER=`python -c """ +import json +cluster_spec = json.loads('$CLUSTER_SPEC')['clusterSpec'] +print(len(cluster_spec.get('Worker', []))) +"""` + + # rewrite tensorflow ClusterSpec for compatibility + # master port 50051 is used for fedlearner master server, so rewrite to 50052 + # worker port 50051 is used for fedlearner worker server, so rewrite to 50052 + CLUSTER_SPEC=`python -c """ +import json +def rewrite_port(address, old, new): + (host, port) = address.rsplit(':', 1) + if port == old: + return host + ':' + new + return address + +cluster_spec = json.loads('$CLUSTER_SPEC')['clusterSpec'] +for i, ps in enumerate(cluster_spec.get('PS', [])): + cluster_spec['PS'][i] = rewrite_port(ps, '50051', '50052') +for i, master in enumerate(cluster_spec.get('Master', [])): + cluster_spec['Master'][i] = rewrite_port(master, '50051', '50052') +for i, worker in enumerate(cluster_spec.get('Worker', [])): + cluster_spec['Worker'][i] = rewrite_port(worker, '50051', '50052') +if 'LocalWorker' in cluster_spec: + for i, worker in enumerate(cluster_spec.get('LocalWorker', [])): + cluster_spec['Worker'].append(rewrite_port(worker, '50051', '50052')) + del cluster_spec['LocalWorker'] +print(json.dumps({'clusterSpec': cluster_spec})) +"""` +fi + +server_port=$(normalize_env_to_args "--server-port" "$PORT1") + +WORKER_RANK=`python -c "print($INDEX + $NUM_WORKER)"` + +python main.py --worker \ + --local-worker \ + --application-id="$APPLICATION_ID" \ + --master-addr="$MASTER_HOST:50051" \ + --cluster-spec="$CLUSTER_SPEC" \ + --worker-rank="$WORKER_RANK" \ + $server_port $mode $batch_size \ + $sparse_estimator $learning_rate diff --git a/deploy/scripts/trainer/run_trainer_master.sh b/deploy/scripts/trainer/run_trainer_master.sh index c1dca584a..1b5d5e6cd 100755 --- a/deploy/scripts/trainer/run_trainer_master.sh +++ b/deploy/scripts/trainer/run_trainer_master.sh @@ -17,7 +17,10 @@ set -ex export CUDA_VISIBLE_DEVICES= + +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true source /app/deploy/scripts/env_to_args.sh mode=$(normalize_env_to_args "--mode" "$MODE") @@ -29,22 +32,31 @@ summary_save_secs=$(normalize_env_to_args "--summary-save-secs" "$SUMMARY_SAVE_S epoch_num=$(normalize_env_to_args "--epoch-num" $EPOCH_NUM) start_date=$(normalize_env_to_args "--start-date" $START_DATE) end_date=$(normalize_env_to_args "--end-date" $END_DATE) +extra_params=$(normalize_env_to_args "--extra-params" "$EXTRA_PARAMS") +export_model=$(normalize_env_to_args "--export-model" $EXPORT_MODEL) shuffle=$(normalize_env_to_args "--shuffle" $SUFFLE_DATA_BLOCK) +shuffle_in_day=$(normalize_env_to_args "--shuffle-in-day" $SHUFFLE_IN_DAY) +local_data_source=$(normalize_env_to_args "--local-data-source" $LOCAL_DATA_SOURCE) +local_data_path=$(normalize_env_to_args "--local-data-path" $LOCAL_DATA_PATH) +local_start_date=$(normalize_env_to_args "--local-start-date" $LOCAL_START_DATE) +local_end_date=$(normalize_env_to_args "--local-end-date" $LOCAL_END_DATE) if [ -n "$CHECKPOINT_PATH" ]; then - checkpoint_path="$CHECKPOINT_PATH" + checkpoint_path="--checkpoint-path=$CHECKPOINT_PATH" else - checkpoint_path="$OUTPUT_BASE_DIR/checkpoints" + checkpoint_path="--checkpoint-path=$OUTPUT_BASE_DIR/checkpoints" fi +load_checkpoint_path=$(normalize_env_to_args "--load-checkpoint-path" "$LOAD_CHECKPOINT_PATH") load_checkpoint_filename=$(normalize_env_to_args "--load-checkpoint-filename" "$LOAD_CHECKPOINT_FILENAME") load_checkpoint_filename_with_path=$(normalize_env_to_args "--load-checkpoint-filename-with-path" "$LOAD_CHECKPOINT_FILENAME_WITH_PATH") if [[ -n "$EXPORT_PATH" ]]; then - export_path="$EXPORT_PATH" + export_path="--export-path=$EXPORT_PATH" else - export_path="$OUTPUT_BASE_DIR/exported_models" + export_path="--export-path=$OUTPUT_BASE_DIR/exported_models" fi + if [ -n "$CLUSTER_SPEC" ]; then # rewrite tensorflow ClusterSpec for compatibility # master port 50051 is used for fedlearner master server, so rewrite to 50052 @@ -58,10 +70,16 @@ def rewrite_port(address, old, new): return address cluster_spec = json.loads('$CLUSTER_SPEC')['clusterSpec'] +for i, ps in enumerate(cluster_spec.get('PS', [])): + cluster_spec['PS'][i] = rewrite_port(ps, '50051', '50052') for i, master in enumerate(cluster_spec.get('Master', [])): cluster_spec['Master'][i] = rewrite_port(master, '50051', '50052') for i, worker in enumerate(cluster_spec.get('Worker', [])): cluster_spec['Worker'][i] = rewrite_port(worker, '50051', '50052') +if 'LocalWorker' in cluster_spec: + for i, worker in enumerate(cluster_spec.get('LocalWorker', [])): + cluster_spec['Worker'].append(rewrite_port(worker, '50051', '50052')) + del cluster_spec['LocalWorker'] print(json.dumps({'clusterSpec': cluster_spec})) """` fi @@ -72,16 +90,29 @@ else pull_code ${CODE_TAR} $PWD fi cd ${ROLE} +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ + +LISTEN_PORT=50051 +if [[ -n "${PORT0}" ]]; then + LISTEN_PORT=${PORT0} +fi + +server_port=$(normalize_env_to_args "--server-port" "$PORT1") python main.py --master \ --application-id=$APPLICATION_ID \ --data-source=$DATA_SOURCE \ - --master-addr=0.0.0.0:50051 \ + --data-path=$DATA_PATH \ + --data-path-wildcard=$DATA_PATH_WILDCARD \ + --master-addr=0.0.0.0:${LISTEN_PORT} \ --cluster-spec="$CLUSTER_SPEC" \ - --checkpoint-path=$checkpoint_path \ + $server_port \ + $checkpoint_path $load_checkpoint_path \ $load_checkpoint_filename $load_checkpoint_filename_with_path \ - --export-path=$export_path \ + $export_path \ $mode $sparse_estimator \ $save_checkpoint_steps $save_checkpoint_secs \ $summary_save_steps $summary_save_secs \ - $epoch_num $start_date $end_date $shuffle + $local_data_source $local_data_path $local_start_date \ + $local_end_date $epoch_num $start_date $end_date \ + $shuffle $shuffle_in_day $extra_params $export_model diff --git a/deploy/scripts/trainer/run_trainer_ps.sh b/deploy/scripts/trainer/run_trainer_ps.sh index 2ba469623..549109e81 100755 --- a/deploy/scripts/trainer/run_trainer_ps.sh +++ b/deploy/scripts/trainer/run_trainer_ps.sh @@ -17,6 +17,14 @@ set -ex export CUDA_VISIBLE_DEVICES= + +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true + +LISTEN_PORT=50052 +if [[ -n "${PORT1}" ]]; then + LISTEN_PORT=${PORT1} +fi -python -m fedlearner.trainer.parameter_server $POD_IP:50051 +python -m fedlearner.trainer.parameter_server $POD_IP:${LISTEN_PORT} diff --git a/deploy/scripts/trainer/run_trainer_worker.sh b/deploy/scripts/trainer/run_trainer_worker.sh index 3f311dfe7..3330ba562 100755 --- a/deploy/scripts/trainer/run_trainer_worker.sh +++ b/deploy/scripts/trainer/run_trainer_worker.sh @@ -19,29 +19,12 @@ set -ex export CUDA_VISIBLE_DEVICES= export MODEL_NAME=${APPLICATION_ID} +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true source /app/deploy/scripts/env_to_args.sh -# When the WORKER_GROUPS is "2,4", this script would update the WORKER_RANK -# to the worker's index within their own group, e.g. -# -# + WORKER_RANK 0 -> 0 -# + WORKER_RANK 1 -> 1 -# + WORKER_RANK 2 -> 0 -# + WORKER_RANK 3 -> 1 -# + WORKER_RANK 4 -> 2 -# + WORKER_RANK 5 -> 3 -# -if [ -n "$WORKER_GROUPS" ]; then -IFS=',' read -ra WORKER_GROUPS <<< "$WORKER_GROUPS" -for i in "${WORKER_GROUPS[@]}"; do - if (( $WORKER_RANK - $i < 0 )); then - break - else - WORKER_RANK=$( expr $WORKER_RANK - $i ) - fi -done -fi +PEER_ADDR=$SERVICE_ID if [[ -n "${CODE_KEY}" ]]; then pull_code ${CODE_KEY} $PWD @@ -50,11 +33,13 @@ else fi cd ${ROLE} +cp /app/sgx/gramine/CI-Examples/tensorflow_io.py ./ mode=$(normalize_env_to_args "--mode" "$MODE") sparse_estimator=$(normalize_env_to_args "--sparse-estimator" "$SPARSE_ESTIMATOR") batch_size=$(normalize_env_to_args "--batch-size" "$BATCH_SIZE") learning_rate=$(normalize_env_to_args "--learning-rate" "$LEARNING_RATE") +extra_params=$(normalize_env_to_args "--extra-params" "$EXTRA_PARAMS") if [ -n "$CLUSTER_SPEC" ]; then # get master address from clusteSpec["master"] @@ -77,20 +62,33 @@ def rewrite_port(address, old, new): return address cluster_spec = json.loads('$CLUSTER_SPEC')['clusterSpec'] +for i, ps in enumerate(cluster_spec.get('PS', [])): + cluster_spec['PS'][i] = rewrite_port(ps, '50051', '50052') for i, master in enumerate(cluster_spec.get('Master', [])): cluster_spec['Master'][i] = rewrite_port(master, '50051', '50052') for i, worker in enumerate(cluster_spec.get('Worker', [])): cluster_spec['Worker'][i] = rewrite_port(worker, '50051', '50052') +if 'LocalWorker' in cluster_spec: + for i, worker in enumerate(cluster_spec.get('LocalWorker', [])): + cluster_spec['Worker'].append(rewrite_port(worker, '50051', '50052')) + del cluster_spec['LocalWorker'] print(json.dumps({'clusterSpec': cluster_spec})) """` fi +LISTEN_PORT=50051 +if [[ -n "${PORT0}" ]]; then + LISTEN_PORT=${PORT0} +fi + +server_port=$(normalize_env_to_args "--server-port" "$PORT1") + python main.py --worker \ --application-id="$APPLICATION_ID" \ --master-addr="$MASTER_HOST:50051" \ --cluster-spec="$CLUSTER_SPEC" \ - --local-addr="$POD_IP:50051" \ + --local-addr="$POD_IP:${LISTEN_PORT}" \ --peer-addr="$PEER_ADDR" \ - --worker-rank="$WORKER_RANK" \ - $mode $batch_size \ + --worker-rank="$INDEX" \ + $server_port $mode $batch_size \ $sparse_estimator $learning_rate diff --git a/deploy/scripts/trainer/run_tree_worker.sh b/deploy/scripts/trainer/run_tree_worker.sh index 12183c67b..6a3c9c894 100755 --- a/deploy/scripts/trainer/run_tree_worker.sh +++ b/deploy/scripts/trainer/run_tree_worker.sh @@ -18,6 +18,7 @@ set -ex export CUDA_VISIBLE_DEVICES= source /app/deploy/scripts/hdfs_common.sh || true +source /app/deploy/scripts/pre_start_hook.sh || true source /app/deploy/scripts/env_to_args.sh NUM_WORKERS=`python -c 'import json, os; print(len(json.loads(os.environ["CLUSTER_SPEC"])["clusterSpec"]["Worker"]))'` @@ -26,11 +27,16 @@ if [[ -z "${DATA_PATH}" && -n "${DATA_SOURCE}" ]]; then export DATA_PATH="${STORAGE_ROOT_PATH}/data_source/${DATA_SOURCE}/data_block" fi +if [[ -z "${LOAD_MODEL_PATH}" && -n "${LOAD_MODEL_NAME}" ]]; then + export LOAD_MODEL_PATH="${STORAGE_ROOT_PATH}/job_output/${LOAD_MODEL_NAME}/exported_models" +fi + mode=$(normalize_env_to_args "--mode" "$MODE") data_path=$(normalize_env_to_args "--data-path" "$DATA_PATH") validation_data_path=$(normalize_env_to_args "--validation-data-path" "$VALIDATION_DATA_PATH") no_data=$(normalize_env_to_args "--no-data" "$NO_DATA") file_ext=$(normalize_env_to_args "--file-ext" "$FILE_EXT") +file_wildcard=$(normalize_env_to_args "--file-wildcard" "$FILE_WILDCARD") file_type=$(normalize_env_to_args "--file-type" "$FILE_TYPE") load_model_path=$(normalize_env_to_args "--load-model-path" "$LOAD_MODEL_PATH") verbosity=$(normalize_env_to_args "--verbosity" "$VERBOSITY") @@ -48,11 +54,16 @@ use_streaming=$(normalize_env_to_args "--use-streaming" "$USE_STREAMING") send_scores_to_follower=$(normalize_env_to_args "--send-scores-to-follower" "$SEND_SCORES_TO_FOLLOWER") send_metrics_to_follower=$(normalize_env_to_args "--send-metrics-to-follower" "$SEND_METRICS_TO_FOLLOWER") enable_packing=$(normalize_env_to_args "--enable-packing" "$ENABLE_PACKING") +label_field=$(normalize_env_to_args "--label-field" "$LABEL_FIELD") +LISTEN_PORT=50051 +if [[ -n "${PORT0}" ]]; then + LISTEN_PORT=${PORT0} +fi python -m fedlearner.model.tree.trainer \ "${ROLE}" \ - --local-addr="$POD_IP:50051" \ + --local-addr="$POD_IP:${LISTEN_PORT}" \ --peer-addr="$PEER_ADDR" \ --num-workers="$NUM_WORKERS" \ --worker-rank="$WORKER_RANK" \ @@ -66,4 +77,5 @@ python -m fedlearner.model.tree.trainer \ $max_depth $l2_regularization $max_bins \ $num_parallel $verify_example_ids $ignore_fields \ $cat_fields $use_streaming $send_scores_to_follower \ - $send_metrics_to_follower $enable_packing + $send_metrics_to_follower $enable_packing $label_field \ + $file_wildcard diff --git a/deploy/scripts/wait4pair_wrapper.sh b/deploy/scripts/wait4pair_wrapper.sh index 511ce34d5..5b6c03b38 100755 --- a/deploy/scripts/wait4pair_wrapper.sh +++ b/deploy/scripts/wait4pair_wrapper.sh @@ -12,6 +12,7 @@ while [[ true ]]; do export PEER_ADDR=`cat ${pair}` break else + echo "still waiting for peer addr" sleep 1 fi done diff --git a/example/fedavg/mnist/follower.py b/example/fedavg/mnist/follower.py new file mode 100644 index 000000000..4af30eb5d --- /dev/null +++ b/example/fedavg/mnist/follower.py @@ -0,0 +1,29 @@ +import os +from fedlearner.fedavg import train_from_keras_model +from .model import create_model, x_train, y_train, x_test, y_test + +fed_leader_address = os.getenv("FL_LEADER_ADDRESS", "0.0.0.0:6870") +fl_name = "follower" +fl_cluster = { + "leader": { + "name": "leader", + "address": fed_leader_address + }, + "followers": [{ + "name": "follower" + }] +} + +model = create_model() +x = x_train[len(x_train) // 2:] +y = y_train[len(y_train) // 2:] +train_from_keras_model(model, + x, + y, + batch_size=30, + epochs=1, + fl_name=fl_name, + fl_cluster=fl_cluster, + steps_per_sync=10) + +model.evaluate(x_test, y_test) diff --git a/example/fedavg/mnist/leader.py b/example/fedavg/mnist/leader.py new file mode 100644 index 000000000..176dfc3cd --- /dev/null +++ b/example/fedavg/mnist/leader.py @@ -0,0 +1,29 @@ +import os +from fedlearner.fedavg import train_from_keras_model +from .model import create_model, x_train, y_train, x_test, y_test + +fed_leader_address = os.getenv("FL_LEADER_ADDRESS", "0.0.0.0:6870") +fl_name = "leader" +fl_cluster = { + "leader": { + "name": "leader", + "address": fed_leader_address + }, + "followers": [{ + "name": "follower" + }] +} + +model = create_model() +x = x_train[:len(x_train) // 2] +y = y_train[:len(y_train) // 2] +train_from_keras_model(model, + x, + y, + batch_size=30, + epochs=1, + fl_name=fl_name, + fl_cluster=fl_cluster, + steps_per_sync=10) + +model.evaluate(x_test, y_test) diff --git a/example/fedavg/mnist/model.py b/example/fedavg/mnist/model.py new file mode 100644 index 000000000..83b7a700f --- /dev/null +++ b/example/fedavg/mnist/model.py @@ -0,0 +1,21 @@ +import tensorflow as tf +import numpy as np + +(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() +x_train = x_train.reshape(x_train.shape[0], -1).astype(np.float32) / 255.0 +y_train = y_train.astype(np.int32) + +x_test = x_test.reshape(x_test.shape[0], -1).astype(np.float32) / 255.0 +y_test = y_test.astype(np.int32) + + +def create_model(): + model = tf.keras.Sequential([ + tf.keras.layers.Dense(200, activation='relu', input_shape=(784, )), + tf.keras.layers.Dense(200, activation='relu'), + tf.keras.layers.Dense(10, activation='softmax'), + ]) + model.compile(optimizer=tf.keras.optimizers.SGD(0.01), + loss=tf.keras.losses.SparseCategoricalCrossentropy(), + metrics=['acc']) + return model diff --git a/example/mnist/test.sh b/example/mnist/test.sh index 228d7174a..295cd0f29 100755 --- a/example/mnist/test.sh +++ b/example/mnist/test.sh @@ -10,20 +10,25 @@ rm -rf data model python make_data.py -python leader.py --local-addr=localhost:50051 \ - --peer-addr=localhost:50052 \ - --data-path=data/leader \ - --save-checkpoint-steps=200 \ - --checkpoint-path=model/leader/checkpoint \ - --export-path=model/leader/saved_model \ - --epoch-num=5 & - -python follower.py --local-addr=localhost:50052 \ - --peer-addr=localhost:50051 \ - --data-path=data/follower/ \ - --save-checkpoint-steps=200 \ - --checkpoint-path=model/follower/checkpoint \ - --export-path=model/follower/saved_model +python leader.py --local-addr=localhost:50051 \ + --peer-addr=localhost:50052 \ + --data-path=data/leader \ + --checkpoint-path=log/leader/checkpoint \ + --export-path=log/leader/export \ + --save-checkpoint-steps=10 \ + --summary-save-steps=10 \ + --epoch-num=1 \ + --export-model=false & # not export model + +python follower.py --local-addr=localhost:50052 \ + --peer-addr=localhost:50051 \ + --data-path=data/follower/ \ + --checkpoint-path=log/follower/checkpoint \ + --export-path=log/follower/export \ + --save-checkpoint-steps=10 \ + --summary-save-steps=10 \ + --epoch-num=1 \ + --export-model=true # export model wait diff --git a/example/sparse_model/follower.py b/example/sparse_model/follower.py index f7d4efa7e..a9e72472f 100644 --- a/example/sparse_model/follower.py +++ b/example/sparse_model/follower.py @@ -70,7 +70,10 @@ def model_fn(model, features, labels, mode): embed_size = 16 for slot_id in slots: fs = model.add_feature_slot(slot_id, hash_size) - fc = model.add_feature_column(fs) + if slot_id < 1024: + fc = model.add_feature_column(fs) + else: + fc = model.add_feature_column_v2("fc_v2_%d"%slot_id, fs) fc.add_vector(embed_size) model.freeze_slots(features) diff --git a/example/sparse_model/leader.py b/example/sparse_model/leader.py index c9a40d4b8..0335a70b1 100644 --- a/example/sparse_model/leader.py +++ b/example/sparse_model/leader.py @@ -15,6 +15,8 @@ # coding: utf-8 # pylint: disable=no-else-return, inconsistent-return-statements +import logging + import tensorflow.compat.v1 as tf import fedlearner.trainer as flt @@ -25,6 +27,8 @@ help='Training batch size.') parser.add_argument('--fid_version', type=int, default=1, help="the version of fid") +parser.add_argument('--local-worker', action='store_true', + help="is local worker") args = parser.parse_args() def input_fn(bridge, trainer_master=None): @@ -35,6 +39,7 @@ def parse_fn(example): feature_map = dict() feature_map['fids'] = tf.VarLenFeature(tf.int64) feature_map['example_id'] = tf.FixedLenFeature([], tf.string) + feature_map["act1_f"] = tf.FixedLenFeature([64], tf.float32) feature_map["y"] = tf.FixedLenFeature([], tf.int64) features = tf.parse_example(example, features=feature_map) return features, dict(y=features.pop('y')) @@ -72,16 +77,21 @@ def model_fn(model, features, labels, mode): flt.feature.FeatureSlot.set_default_vec_optimizer( tf.train.AdagradOptimizer(learning_rate=0.01)) - slots = [0, 1, 2, 511] hash_size = 101 embed_size = 16 - if args.fid_version == 2: + if args.fid_version == 1: + slots = [0, 1, 2, 511] + else: model.set_use_fid_v2(True) + slots = [0, 1, 2, 511, 1025] for slot_id in slots: fs = model.add_feature_slot(slot_id, hash_size) - fc = model.add_feature_column(fs) + if slot_id < 1024: + fc = model.add_feature_column(fs) + else: + fc = model.add_feature_column_v2("fc_v2_%d"%slot_id, fs) fc.add_vector(embed_size) model.freeze_slots(features) @@ -109,12 +119,14 @@ def model_fn(model, features, labels, mode): act1_l = tf.nn.relu(tf.nn.bias_add(tf.matmul(embed_output, w1l), b1l)) act2_l = tf.nn.bias_add(tf.matmul(act1_l, w2), b2) - if mode == tf.estimator.ModeKeys.TRAIN: + if mode == tf.estimator.ModeKeys.TRAIN and not args.local_worker: act1_f = model.recv('act1_f', tf.float32, require_grad=True) else: act1_f = features['act1_f'] output = tf.concat([act2_l, act1_f], axis=1) logits = tf.matmul(output, w3) + if mode == tf.estimator.ModeKeys.PREDICT: + return model.make_spec(mode, predictions=logits) if mode == tf.estimator.ModeKeys.TRAIN: y = labels['y'] @@ -129,10 +141,10 @@ def model_fn(model, features, labels, mode): train_op = model.minimize(optimizer, loss, global_step=global_step) return model.make_spec(mode, loss=loss, train_op=train_op, training_hooks=[logging_hook]) - if mode == tf.estimator.ModeKeys.PREDICT: - return model.make_spec(mode, predictions=logits) + if __name__ == '__main__': + logging.getLogger().setLevel(logging.DEBUG) flt.trainer_worker.train( ROLE, args, input_fn, model_fn, serving_input_receiver_fn) diff --git a/example/sparse_model/make_data.py b/example/sparse_model/make_data.py index 67e953f8a..3060eb5ae 100644 --- a/example/sparse_model/make_data.py +++ b/example/sparse_model/make_data.py @@ -25,7 +25,9 @@ import numpy as np import tensorflow.compat.v1 as tf -from tensorflow.train import Example, Feature, Features, Int64List, BytesList +from tensorflow.core.example.example_pb2 import Example +from tensorflow.core.example.feature_pb2 import Features, Feature, \ + Int64List, BytesList, FloatList current_dir = os.path.dirname(__file__) shutil.rmtree(os.path.join(current_dir, 'data'), ignore_errors=True) @@ -42,7 +44,7 @@ FOLLOWER_SLOTS = [512, 1023] elif args.fid_version == 2: FEATURE_BITS = 48 - LEADER_SLOTS = [0, 1, 2, 511] + LEADER_SLOTS = [0, 1, 2, 511, 1025] FOLLOWER_SLOTS = [512, 1023, 32767] else: raise ValueError("fid_version should be 1 or 2") @@ -80,6 +82,9 @@ def _fake_sample(slots): Feature(int64_list=Int64List(value=[random.randint(0, 1)])) features_l['fids'] = \ Feature(int64_list=Int64List(value=_fake_sample(LEADER_SLOTS))) + features_l['act1_f'] = \ + Feature(float_list=FloatList(value=np.random.uniform( + low=0., high=1., size=(64,)))) fl.write(Example(features=Features(feature=features_l)) .SerializeToString()) diff --git a/example/sparse_model/test_local_worker.sh b/example/sparse_model/test_local_worker.sh new file mode 100755 index 000000000..06d98f12f --- /dev/null +++ b/example/sparse_model/test_local_worker.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +cd "$( dirname "${BASH_SOURCE[0]}" )" +rm -rf data model + +export CUDA_VISIBLE_DEVICES="" +set -e + +rm -rf data model +python make_data.py --fid_version=2 +python leader.py --local-addr=localhost:50011 \ + --local-worker \ + --data-path=data/leader/ \ + --checkpoint-path=model/leader \ + --save-checkpoint-steps=100 \ + --export-path=model/leader/saved_model \ + --sparse-estimator=True \ + --fid_version=2 +rm -rf data model diff --git a/example/tree_model/merge_scores.py b/example/tree_model/merge_scores.py index de7d39c41..5a51b6920 100644 --- a/example/tree_model/merge_scores.py +++ b/example/tree_model/merge_scores.py @@ -89,11 +89,13 @@ def run(args): logging.basicConfig(level=logging.INFO) left_loader = DataBlockLoader( - 'local', None, args.left_data_path, args.left_file_ext, + role='local', bridge=None, data_path=args.left_data_path, + ext=args.left_file_ext, file_wildcard=None, worker_rank=args.worker_rank, num_workers=args.num_workers, output_path=args.output_path) right_loader = DataBlockLoader( - 'local', None, args.right_data_path, args.right_file_ext, + role='local', bridge=None, data_path=args.right_data_path, + ext=args.right_file_ext, file_wildcard=None, worker_rank=args.worker_rank, num_workers=args.num_workers, output_path=args.output_path) @@ -112,5 +114,6 @@ def run(args): args.output_path, left_block.block_id + '.output') merge(args, left_block.data_path, right_block.data_path, output_file) + if __name__ == '__main__': run(create_argument_parser().parse_args()) diff --git a/example/tree_model/test.sh b/example/tree_model/test.sh index e92dce54f..923327899 100755 --- a/example/tree_model/test.sh +++ b/example/tree_model/test.sh @@ -12,8 +12,10 @@ python -m fedlearner.model.tree.trainer follower \ --verbosity=1 \ --local-addr=localhost:50052 \ --peer-addr=localhost:50051 \ + --num-parallel=4 \ --verify-example-ids=true \ --file-ext=.tfrecord \ + --file-wildcard=*tfrecord \ --file-type=tfrecord \ --data-path=data/follower_train.tfrecord \ --validation-data-path=data/follower_test \ @@ -25,8 +27,10 @@ python -m fedlearner.model.tree.trainer leader \ --verbosity=1 \ --local-addr=localhost:50051 \ --peer-addr=localhost:50052 \ + --num-parallel=4 \ --verify-example-ids=true \ --file-ext=.tfrecord \ + --file-wildcard=*tfrecord \ --file-type=tfrecord \ --data-path=data/leader_train.tfrecord \ --validation-data-path=data/leader_test \ @@ -40,10 +44,12 @@ python -m fedlearner.model.tree.trainer leader \ --verbosity=1 \ --local-addr=localhost:50051 \ --peer-addr=localhost:50052 \ + --num-parallel=4 \ --mode=test \ --verify-example-ids=true \ --file-type=tfrecord \ --file-ext=.tfrecord \ + --file-wildcard=*tfrecord \ --data-path=data/leader_test/ \ --cat-fields=f00001 \ --load-model-path=exp/leader_checkpoints/checkpoint-0004.proto \ @@ -53,10 +59,12 @@ python -m fedlearner.model.tree.trainer follower \ --verbosity=1 \ --local-addr=localhost:50052 \ --peer-addr=localhost:50051 \ + --num-parallel=4 \ --mode=test \ --verify-example-ids=true \ --file-type=tfrecord \ --file-ext=.tfrecord \ + --file-wildcard=*tfrecord \ --data-path=data/follower_test/ \ --cat-fields=f00001 \ --load-model-path=exp/follower_checkpoints/checkpoint-0004.proto \ @@ -73,7 +81,10 @@ python -m fedlearner.model.tree.trainer follower \ --verbosity=1 \ --local-addr=localhost:50052 \ --peer-addr=localhost:50051 \ + --num-parallel=4 \ + --file-ext=.csv \ --file-type=csv \ + --file-wildcard=*csv \ --data-path=data/follower_train.csv \ --cat-fields=f00001 \ --checkpoint-path=exp/follower_checkpoints \ @@ -83,7 +94,10 @@ python -m fedlearner.model.tree.trainer leader \ --verbosity=1 \ --local-addr=localhost:50051 \ --peer-addr=localhost:50052 \ + --num-parallel=4 \ + --file-ext=.csv \ --file-type=csv \ + --file-wildcard=*csv \ --data-path=data/leader_train.csv \ --ignore-fields=f00000,f00001 \ --checkpoint-path=exp/leader_checkpoints \ @@ -95,7 +109,10 @@ python -m fedlearner.model.tree.trainer follower \ --verbosity=2 \ --local-addr=localhost:50052 \ --peer-addr=localhost:50051 \ + --num-parallel=4 \ --mode=test \ + --file-ext=.csv \ + --file-wildcard=*csv \ --file-type=csv \ --data-path=data/follower_test/ \ --cat-fields=f00001 \ @@ -106,7 +123,10 @@ python -m fedlearner.model.tree.trainer leader \ --verbosity=2 \ --local-addr=localhost:50051 \ --peer-addr=localhost:50052 \ + --num-parallel=4 \ --mode=test \ + --file-ext=.csv \ + --file-wildcard=*csv \ --no-data=true \ --load-model-path=exp/leader_checkpoints/checkpoint-0004.proto \ --output-path=exp/leader_test_output diff --git a/example/wide_n_deep/leader_mask_loss.py b/example/wide_n_deep/leader_mask_loss.py new file mode 100644 index 000000000..7a1c728c8 --- /dev/null +++ b/example/wide_n_deep/leader_mask_loss.py @@ -0,0 +1,186 @@ +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +# pylint: disable=no-else-return, inconsistent-return-statements + +import tensorflow.compat.v1 as tf +import fedlearner.trainer as flt + +ROLE = 'leader' + +parser = flt.trainer_worker.create_argument_parser() +parser.add_argument('--batch-size', type=int, default=32, + help='Training batch size.') +args = parser.parse_args() + + +def input_fn(bridge, trainer_master=None): + dataset = flt.data.DataBlockLoader( + args.batch_size, ROLE, bridge, trainer_master).make_dataset() + + def parse_fn(example): + feature_map = {"x_{0}".format(i): tf.VarLenFeature( + tf.int64) for i in range(512)} + feature_map["example_id"] = tf.FixedLenFeature([], tf.string) + feature_map["y"] = tf.FixedLenFeature([], tf.int64) + feature_map["loss_mask"] = tf.FixedLenFeature([], tf.int64) + features = tf.parse_example(example, features=feature_map) + return features, dict(y=features.pop('y')) + + dataset = dataset.map(map_func=parse_fn, + num_parallel_calls=tf.data.experimental.AUTOTUNE) + + return dataset + + +def serving_input_receiver_fn(): + feature_map = {"x_{0}".format(i): tf.VarLenFeature( + tf.int64) for i in range(512)} + feature_map["example_id"] = tf.FixedLenFeature([], tf.string) + + record_batch = tf.placeholder(dtype=tf.string, name='examples') + features = tf.parse_example(record_batch, features=feature_map) + features['act1_f'] = tf.placeholder(dtype=tf.float32, name='act1_f') + receiver_tensors = { + 'examples': record_batch, + 'act1_f': features['act1_f'] + } + return tf.estimator.export.ServingInputReceiver( + features, receiver_tensors) + + +def model_fn(model, features, labels, mode): + """Model Builder of wide&deep learning models + Args: + Returns + """ + global_step = tf.train.get_or_create_global_step() + + # 新增一个特征,用于决定是否将loss设置为0 + loss_mask_feature = features.get('loss_mask', None) + + x = dict() + for i in range(512): + x_name = "x_{}".format(i) + x[x_name] = features[x_name] + + + num_slot = 512 + fid_size, embed_size = 101, 16 + embeddings = [ + tf.get_variable( + 'slot_emb{0}'.format(i), shape=[fid_size, embed_size], + dtype=tf.float32, + initializer=tf.random_uniform_initializer(-0.01, 0.01)) + for i in range(num_slot)] + embed_output = tf.concat( + [ + tf.nn.embedding_lookup_sparse( + embeddings[i], x['x_{}'.format(i)], sp_weights=None, + combiner='mean') + for i in range(512)], + axis=1) + + output_size = num_slot * embed_size + fc1_size, fc2_size = 256, 64 + w1l = tf.get_variable( + 'w1l', shape=[output_size, fc1_size], dtype=tf.float32, + initializer=tf.random_uniform_initializer(-0.01, 0.01)) + b1l = tf.get_variable( + 'b1l', shape=[fc1_size], dtype=tf.float32, + initializer=tf.zeros_initializer()) + w2 = tf.get_variable( + 'w2', shape=[fc1_size, fc2_size], dtype=tf.float32, + initializer=tf.random_uniform_initializer(-0.01, 0.01)) + b2 = tf.get_variable( + 'b2', shape=[fc2_size], dtype=tf.float32, + initializer=tf.zeros_initializer()) + w3 = tf.get_variable( + 'w3', shape=[fc2_size*2, 2], dtype=tf.float32, + initializer=tf.random_uniform_initializer(-0.01, 0.01)) + + act1_l = tf.nn.relu(tf.nn.bias_add(tf.matmul(embed_output, w1l), b1l)) + act2_l = tf.nn.bias_add(tf.matmul(act1_l, w2), b2) + + if mode == tf.estimator.ModeKeys.TRAIN: + act1_f = model.recv('act1_f', tf.float32, require_grad=True) + elif mode == tf.estimator.ModeKeys.EVAL: + act1_f = model.recv('act1_f', tf.float32, require_grad=False) + else: + act1_f = features['act1_f'] + + output = tf.concat([act2_l, act1_f], axis=1) + logits = tf.matmul(output, w3) + + + if mode == tf.estimator.ModeKeys.PREDICT: + return model.make_spec(mode, predictions=logits) + + y = labels['y'] + loss = tf.nn.sparse_softmax_cross_entropy_with_logits( + labels=y, logits=logits) + # 打印原始损失 + loss_print_op = tf.print("Original loss:", loss) + + # 判断loss_mask_feature是否存在,以及其值是否为1,如果为1,则将loss设置为0 + if loss_mask_feature is not None: + # 将loss_mask_feature的形状转换为与loss相同,以便进行元素乘法 + loss_mask = tf.cast(tf.reshape(loss_mask_feature, [-1]), tf.float32) + # 打印loss_mask + loss_mask_print_op = tf.print("Loss mask:", loss_mask) + + # 应用mask,如果loss_mask中的值为0,则相应的loss保持不变;如果为1,则将相应的loss设置为0 + loss = loss * (1 - loss_mask) + else: + loss_mask_print_op = tf.no_op() + + # 打印应用loss_mask后的损失 + loss_after_mask_print_op = tf.print("Loss after applying mask:", loss) + # 确保在计算平均损失之前打印出所有的信息 + with tf.control_dependencies([loss_print_op, loss_mask_print_op, loss_after_mask_print_op]): + loss = tf.math.reduce_mean(loss) + + + if mode == tf.estimator.ModeKeys.EVAL: + auc_pair = tf.metrics.auc(y, logits[:, 1]) + return model.make_spec( + mode, loss=loss, eval_metric_ops={'auc': auc_pair}) + + # mode == tf.estimator.ModeKeys.TRAIN: + logging_hook = tf.train.LoggingTensorHook( + {"loss" : loss}, every_n_iter=10) + metric_hook = flt.GlobalStepMetricTensorHook(tensor_dict={"loss": loss}, + every_steps=10) + optimizer = tf.train.GradientDescentOptimizer(0.1) + train_op = model.minimize(optimizer, loss, global_step=global_step) + return model.make_spec(mode, loss=loss, train_op=train_op, + training_hooks=[logging_hook, metric_hook]) + +class ExportModelHook(flt.trainer_worker.ExportModelHook): + def after_save(self, sess, model, export_dir, inputs, outputs): + print("**************export model hook**************") + print("sess :", sess) + print("model: ", model) + print("export_dir: ", export_dir) + print("inputs: ", inputs) + print("outpus: ", outputs) + print("*********************************************") + + +if __name__ == '__main__': + flt.trainer_worker.train( + ROLE, args, input_fn, + model_fn, serving_input_receiver_fn, + export_model_hook=ExportModelHook()) diff --git a/example/wide_n_deep/make_data.py b/example/wide_n_deep/make_data.py index e22a6dafc..6f88f8334 100644 --- a/example/wide_n_deep/make_data.py +++ b/example/wide_n_deep/make_data.py @@ -42,6 +42,8 @@ Feature(bytes_list=BytesList(value=[str(idx).encode()])) features_l['y'] = \ Feature(int64_list=Int64List(value=[random.randint(0, 1)])) + features_l['loss_mask'] = \ + Feature(int64_list=Int64List(value=[random.randint(0, 1)])) for k in range(512): features_l['x_{0}'.format(k)] = \ Feature(int64_list=Int64List(value=[random.randint(0, 100)])) diff --git a/fedlearner-sgx-dev.dockerfile b/fedlearner-sgx-dev.dockerfile index c76e91981..915c70c09 100644 --- a/fedlearner-sgx-dev.dockerfile +++ b/fedlearner-sgx-dev.dockerfile @@ -1,153 +1,207 @@ -# https://github.com/oscarlab/graphene/blob/master/Tools/gsc/images/graphene_aks.latest.dockerfile +# https://github.com/gramineproject/gramine/blob/master/.ci/ubuntu18.04.dockerfile FROM ubuntu:18.04 ENV DEBIAN_FRONTEND=noninteractive +ENV INSTALL_PREFIX=/usr/local +ENV LD_LIBRARY_PATH=${INSTALL_PREFIX}/lib:${INSTALL_PREFIX}/lib/x86_64-linux-gnu:${LD_LIBRARY_PATH} +ENV PATH=${INSTALL_PREFIX}/bin:${LD_LIBRARY_PATH}:${PATH} +# For Gramine RA-TLS +ENV PYTHONDONTWRITEBYTECODE=1 -COPY sgx/configs/etc/apt/sources.list /etc/apt/sources.list - -# Add steps here to set up dependencies +# Add steps here to set up common dependencies RUN apt-get update \ && apt-get install -y --no-install-recommends apt-utils \ && apt-get install -y \ + ca-certificates \ build-essential \ autoconf \ libtool \ python3-pip \ python3-dev \ - unzip \ git \ - zlib1g-dev \ - wget + wget \ + unzip \ + zlib1g-dev \ + jq -# Intel SGX +# Intel SGX PPA RUN echo "deb [trusted=yes arch=amd64] https://download.01.org/intel-sgx/sgx_repo/ubuntu bionic main" | tee /etc/apt/sources.list.d/intel-sgx.list \ && wget -qO - https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | apt-key add - \ && apt-get update # Install SGX-PSW -RUN apt-get install -y libsgx-pce-logic libsgx-ae-qve libsgx-quote-ex libsgx-qe3-logic sgx-aesm-service +RUN apt-get install -y libsgx-pce-logic libsgx-ae-qve libsgx-quote-ex libsgx-quote-ex libsgx-quote-ex-dev libsgx-qe3-logic sgx-aesm-service # Install SGX-DCAP -RUN apt-get install -y libsgx-dcap-ql-dev libsgx-dcap-default-qpl libsgx-dcap-quote-verify-dev +RUN apt-get install -y libsgx-dcap-ql-dev libsgx-dcap-default-qpl libsgx-dcap-quote-verify-dev libsgx-dcap-default-qpl-dev + +# Install CMAKE +RUN mkdir -p ${INSTALL_PREFIX} \ + && wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v3.19.6/cmake-3.19.6-Linux-x86_64.sh \ + && sh cmake-linux.sh -- --skip-license --prefix=${INSTALL_PREFIX} \ + && rm cmake-linux.sh -# Graphene -ENV GRAPHENEDIR=/graphene -ENV GRAPHENE_VERSION=2fdb529f81e839ef1d9638362c2c02a4e34af79f +# Install gramine +ENV GRAMINEDIR=/gramine +ENV SGX_DCAP_VERSION=DCAP_1.11 # ENV GRAPHENE_VERSION=master -ENV ISGX_DRIVER_PATH=${GRAPHENEDIR}/Pal/src/host/Linux-SGX/linux-sgx-driver -ENV SGX_SIGNER_KEY=${GRAPHENEDIR}/Pal/src/host/Linux-SGX/signer/enclave-key.pem +# ENV GRAMINE_VERSION=497847c0353a13c9e83c0ec4c0cbe99f11d4a75d +ENV GRAMINE_VERSION=devel-v1.3.1-2023-07-13 +ENV ISGX_DRIVER_PATH=${GRAMINEDIR}/driver +ENV SGX_SIGNER_KEY=/root/.config/gramine/enclave-key.pem ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 ENV WERROR=1 ENV SGX=1 -# https://graphene.readthedocs.io/en/latest/building.html +# https://gramine.readthedocs.io/en/latest/building.html # golang is needed by grpc/BoringSSL -RUN apt-get install -y gawk bison meson python3-click python3-jinja2 golang +RUN apt-get update +RUN apt-get install -y gawk bison python3-click python3-jinja2 golang ninja-build RUN apt-get install -y libcurl4-openssl-dev libprotobuf-c-dev python3-protobuf protobuf-c-compiler -RUN pip3 install toml>=0.10 +RUN apt-get install -y libgmp-dev libmpfr-dev libmpc-dev libisl-dev nasm protobuf-compiler + +RUN ln -s /usr/bin/python3 /usr/bin/python \ + && pip3 install --no-compile --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/ \ + && pip3 install --no-compile toml meson pyelftools -i https://mirrors.aliyun.com/pypi/simple/ -RUN git clone https://github.com/oscarlab/graphene.git ${GRAPHENEDIR} \ - && cd ${GRAPHENEDIR} \ - && git checkout ${GRAPHENE_VERSION} +RUN git clone https://github.com/analytics-zoo/gramine ${GRAMINEDIR} \ + && cd ${GRAMINEDIR} \ + && git checkout ${GRAMINE_VERSION} -# Create SGX driver for Graphene RUN git clone https://github.com/intel/SGXDataCenterAttestationPrimitives.git ${ISGX_DRIVER_PATH} \ && cd ${ISGX_DRIVER_PATH} \ - && git checkout DCAP_1.9 \ - && cp -r driver/linux/* ${ISGX_DRIVER_PATH} + && git checkout ${SGX_DCAP_VERSION} + +COPY sgx/gramine/patches ${GRAMINEDIR} +RUN cd ${GRAMINEDIR} \ + && git apply *.diff + +# https://gramine.readthedocs.io/en/latest/quickstart.html#quick-start-with-sgx-support +RUN mkdir -p /root/.config/gramine/ && openssl genrsa -3 -out ${SGX_SIGNER_KEY} 3072 +RUN cd ${GRAMINEDIR} \ + && LD_LIBRARY_PATH="" meson setup build/ --buildtype=release -Dprefix=${INSTALL_PREFIX} -Ddirect=enabled -Dsgx=enabled -Ddcap=enabled -Dsgx_driver=dcap1.10 -Dsgx_driver_include_path=${ISGX_DRIVER_PATH}/driver/linux/include \ + && LD_LIBRARY_PATH="" ninja -C build/ \ + && LD_LIBRARY_PATH="" ninja -C build/ install + +# Install mbedtls +RUN cd ${GRAMINEDIR}/build/subprojects/mbedtls-mbedtls* \ + && cp -r `find . -maxdepth 1 -name "*_gramine.a"` ${INSTALL_PREFIX}/lib \ + && cp -r ${GRAMINEDIR}/subprojects/mbedtls-mbedtls*/mbedtls-mbedtls*/include ${INSTALL_PREFIX} + +# Install cJSON +RUN cd ${GRAMINEDIR}/subprojects/cJSON* \ + && make static \ + && cp -r *.a ${INSTALL_PREFIX}/lib \ + && mkdir -p ${INSTALL_PREFIX}/include/cjson \ + && cp -r *.h ${INSTALL_PREFIX}/include/cjson + +# GRPC dependencies +ENV GRPC_PATH=/grpc +ENV GRPC_VERSION=v1.38.1 +# ENV GRPC_VERSION=b54a5b338637f92bfcf4b0bc05e0f57a5fd8fadd -# Build Graphene with SGX -# https://graphene.readthedocs.io/en/latest/quickstart.html#quick-start-with-sgx-support -RUN cd ${GRAPHENEDIR} \ - && make -j `nproc` ISGX_DRIVER_PATH="" SGX=0 \ - && make -j `nproc` \ - && meson build -Ddirect=enabled -Dsgx=enabled \ - && ninja -C build \ - && ninja -C build install +RUN git clone --recurse-submodules -b ${GRPC_VERSION} https://github.com/grpc/grpc ${GRPC_PATH} +RUN pip3 install --no-compile --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/ \ + && pip3 install --no-compile -r ${GRPC_PATH}/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ -# Translate runtime symlinks to files -RUN for f in $(find ${GRAPHENEDIR}/Runtime -type l); do cp --remove-destination $(realpath $f) $f; done +# Tensorflow dependencies +ENV BAZEL_VERSION=3.1.0 +ENV TF_VERSION=v2.4.2 +ENV TF_BUILD_PATH=/tf/src +ENV TF_BUILD_OUTPUT=/tf/output -# GRPC -ENV GRPC_PATH=/grpc -ENV INSTALL_PREFIX=/usr/local -ENV LD_LIBRARY_PATH=${INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH} -ENV PATH=${INSTALL_PREFIX}/bin:${LD_LIBRARY_PATH}:${PATH} +RUN pip3 install --no-compile --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/ \ + && pip3 install --no-compile numpy keras_preprocessing -i https://mirrors.aliyun.com/pypi/simple/ -RUN mkdir -p ${INSTALL_PREFIX} \ - && wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v3.19.6/cmake-3.19.6-Linux-x86_64.sh \ - && sh cmake-linux.sh -- --skip-license --prefix=${INSTALL_PREFIX} \ - && rm cmake-linux.sh +RUN wget "https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel_${BAZEL_VERSION}-linux-x86_64.deb" \ + && dpkg -i bazel_*.deb -#RUN git clone --recurse-submodules -b v1.36.0 https://github.com/grpc/grpc ${GRPC_PATH} -RUN git clone https://github.com/grpc/grpc ${GRPC_PATH} -RUN cd ${GRPC_PATH} && git checkout b54a5b338637f92bfcf4b0bc05e0f57a5fd8fadd && git submodule update --init +RUN git clone --recurse-submodules -b ${TF_VERSION} https://github.com/tensorflow/tensorflow ${TF_BUILD_PATH} -RUN cd ${GRPC_PATH} \ - && pip3 install --upgrade pip setuptools==44.1.1 \ - && pip3 install -r requirements.txt +# Fedlearner dependencies +ENV FEDLEARNER_PATH=/fedlearner -COPY sgx/graphene ${GRAPHENEDIR} -COPY sgx/fedlearner ${FEDLEARNER_PATH} -COPY sgx/grpc ${GRPC_PATH} -COPY sgx/configs / +RUN apt-get install -y libmysqlclient-dev -RUN openssl genrsa -3 -out ${SGX_SIGNER_KEY} 3072 +# Build gRPC +COPY sgx/grpc/common ${GRPC_PATH} +COPY sgx/grpc/v1.38.1 ${GRPC_PATH} -COPY sgx/grpc/build_install.sh ${GRPC_PATH} -RUN cd ${GRPC_PATH} && git apply grpc_skip_client_sanity_check.diff && ${GRPC_PATH}/build_install.sh +RUN pip3 install --no-compile 'cython==0.29.36' -i https://mirrors.aliyun.com/pypi/simple/ +RUN ${GRPC_PATH}/build_python.sh -# tensorflow -ENV BAZEL_VERSION=3.1.0 -RUN wget "https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel_${BAZEL_VERSION}-linux-x86_64.deb" \ - && dpkg -i bazel_*.deb +# Build tensorflow +COPY sgx/tf ${TF_BUILD_PATH} -## deps -RUN pip install numpy keras_preprocessing +RUN cd ${TF_BUILD_PATH} \ + && git apply sgx_tls_sample.diff -ENV TF_VERSION=v2.4.2 -ENV TF_BUILD_PATH=/tf/src -ENV TF_BUILD_OUTPUT=/tf/output -RUN git clone --recurse-submodules -b ${TF_VERSION} https://github.com/tensorflow/tensorflow ${TF_BUILD_PATH} +ARG TF_BUILD_CFG="--config=numa --config=mkl --config=mkl_threadpool --copt=-march=native --copt=-O3 --cxxopt=-march=native --cxxopt=-O3 --cxxopt=-D_GLIBCXX_USE_CXX11_ABI=0" +RUN cd ${TF_BUILD_PATH} \ + && bazel build --local_ram_resources=2048 -c opt ${TF_BUILD_CFG} //tensorflow/tools/pip_package:build_pip_package \ + && bazel-bin/tensorflow/tools/pip_package/build_pip_package ${TF_BUILD_OUTPUT} + +# Build and install fedlearner +COPY . ${FEDLEARNER_PATH} -# git apply diff -COPY sgx/tf ${TF_BUILD_PATH} -RUN cd ${TF_BUILD_PATH} && git apply sgx_tls_sample.diff +# For meituan hadoop +RUN if [ -f ${FEDLEARNER_PATH}/docker/hadoop-mt-2.7.0.tar.gz ]; then mkdir -p /opt/meituan/ && tar -xzf ${FEDLEARNER_PATH}/docker/hadoop-mt-2.7.0.tar.gz -C /opt/meituan/; fi -# mbedtls -RUN cd ${TF_BUILD_PATH} && ./build.sh +# For meituan hadoop auth +RUN apt-get install -y libkrb5-dev openjdk-8-jdk -RUN cd ${TF_BUILD_PATH} && bazel build -c opt //tensorflow/tools/pip_package:build_pip_package -RUN cd ${TF_BUILD_PATH} && bazel-bin/tensorflow/tools/pip_package/build_pip_package ${TF_BUILD_OUTPUT} && pip install ${TF_BUILD_OUTPUT}/tensorflow-*-cp36-cp36m-linux_x86_64.whl +RUN pip3 install --no-compile --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/ \ + && pip3 install --no-compile -r ${FEDLEARNER_PATH}/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ -## Fedlearner -ENV FEDLEARNER_PATH=/fedlearner -RUN apt-get install -y libgmp-dev libmpfr-dev libmpc-dev libmysqlclient-dev -COPY . ${FEDLEARNER_PATH} -RUN ln -s /usr/bin/python3.6 /usr/bin/python -RUN pip3 install --upgrade pip setuptools \ - && pip3 install -r ${FEDLEARNER_PATH}/requirements.txt -RUN ${FEDLEARNER_PATH}/sgx/fedlearner/build_install.sh -# uninstall tensorflow_io, mock it -RUN pip uninstall -y tensorflow-io +RUN cd ${FEDLEARNER_PATH} \ + && make protobuf \ + && python3 setup.py bdist_wheel \ + && pip3 install --no-compile ./dist/*.whl + +# Re-install tensorflow, uninstall tensorflow_io, mock it +RUN pip3 uninstall -y tensorflow tensorflow-io \ + && pip3 install --no-compile ${TF_BUILD_OUTPUT}/*.whl + +# Re-install fedlearner plugin +RUN cd ${FEDLEARNER_PATH} \ + && make op \ + && mkdir -p /usr/local/lib/python3.6/dist-packages/cc \ + && cp ./cc/embedding.so /usr/local/lib/python3.6/dist-packages/cc + +# Re-install grpcio +RUN pip3 uninstall -y grpcio \ + && pip3 install --no-compile ${GRPC_PATH}/dist/grpcio*.whl + +# For debug +RUN apt-get install -y strace gdb ctags vim + +COPY sgx/gramine/CI-Examples ${GRAMINEDIR}/CI-Examples +COPY sgx/configs / # https://askubuntu.com/questions/93457/how-do-i-enable-or-disable-apport RUN echo "enabled=0" > /etc/default/apport RUN echo "exit 0" > /usr/sbin/policy-rc.d +# For gramine ra-tls +RUN dpkg --remove --force-depends libgtk2.0-0 \ + && pip3 uninstall -y numpy keras_preprocessing protobuf \ + && pip3 install --no-compile numpy keras_preprocessing protobuf -i https://mirrors.aliyun.com/pypi/simple/ + # Clean tmp files RUN apt-get clean all \ && rm -rf /var/lib/apt/lists/* \ - && rm -rf ~/.cache/pip/* \ + && rm -rf ~/.cache/* \ && rm -rf /tmp/* # Workspace -ENV WORK_SPACE_PATH=${GRAPHENEDIR} +ENV WORK_SPACE_PATH=${GRAMINEDIR} WORKDIR ${WORK_SPACE_PATH} EXPOSE 6006 50051 50052 +RUN bash -x /fedlearner/deploy/scripts/sgx/get_token.sh + RUN chmod +x /root/entrypoint.sh # ENTRYPOINT ["/root/entrypoint.sh"] diff --git a/fedlearner-sgx-release.dockerfile b/fedlearner-sgx-release.dockerfile new file mode 100644 index 000000000..bcf3a8156 --- /dev/null +++ b/fedlearner-sgx-release.dockerfile @@ -0,0 +1,21 @@ +ARG base_image=fedlearner-sgx-dev:latest + +FROM ${base_image} AS builder + +RUN cp /grpc/examples/dynamic_config.json /tmp + +RUN rm -rf /tf /grpc + +RUN mkdir -p /grpc/examples && mv /tmp/dynamic_config.json /grpc/examples + +RUN unset PWD HOSTNAME http_proxy https_proxy + +RUN env && env > ~/.env && sed -i "s/^/export ${i}\t&/g" ~/.env && echo "source ~/.env" >> ~/.bashrc + +RUN rm -rf /gramine/driver && rm -rf /gramine/build + +FROM scratch + +COPY --from=builder / / + +RUN mv /fedlearner /app \ No newline at end of file diff --git a/fedlearner/__init__.py b/fedlearner/__init__.py index 20aa6fc19..ce73456c1 100644 --- a/fedlearner/__init__.py +++ b/fedlearner/__init__.py @@ -19,3 +19,5 @@ from fedlearner import data_join from fedlearner import proxy from fedlearner import trainer +from fedlearner import fedavg +from fedlearner import privacy diff --git a/fedlearner/channel/channel.py b/fedlearner/channel/channel.py index 1c5c55733..111358aba 100644 --- a/fedlearner/channel/channel.py +++ b/fedlearner/channel/channel.py @@ -24,8 +24,8 @@ import grpc from fedlearner.common import fl_logging, stats, common from fedlearner.channel import channel_pb2, channel_pb2_grpc -from fedlearner.proxy.channel import make_insecure_channel, \ - make_secure_channel, ChannelType +from fedlearner.common.metric_collector import metric_collector +from fedlearner.proxy.channel import make_insecure_channel, make_secure_channel, ChannelType from fedlearner.channel.client_interceptor import ClientInterceptor from fedlearner.channel.server_interceptor import ServerInterceptor @@ -131,7 +131,7 @@ def __init__(self, listen_address, remote_address, token=None, - max_workers=16, + max_workers=2, compression=grpc.Compression.Gzip, heartbeat_timeout=120, retry_interval=2, @@ -181,7 +181,7 @@ def __init__(self, ('grpc.max_receive_message_length', -1), ('grpc.max_reconnect_backoff_ms', 1000), ) - use_tls, creds = common.use_tls() + use_tls = common.use_tls() if use_tls: self._channel = make_secure_channel( self._remote_address, @@ -201,8 +201,7 @@ def __init__(self, identifier=self._identifier, retry_interval=self._retry_interval, wait_fn=self.wait_for_ready, - check_fn=self._channel_response_check_fn, - stats_client=stats_client) + check_fn=self._channel_response_check_fn) self._channel = grpc.intercept_channel(self._channel, self._channel_interceptor) @@ -223,8 +222,8 @@ def __init__(self, # channel client & server self._channel_call = channel_pb2_grpc.ChannelStub(self._channel) if use_tls: - server_credentials = grpc.ssl_server_credentials( - ((creds[1], creds[2]), ), creds[0], True) + server_credentials = \ + grpc.sgxratls_server_credentials("dynamic_config.json") self._server.add_secure_port( self._listen_address, server_credentials) else: @@ -423,13 +422,14 @@ def _call_locked(self, call_type): token=self._token, identifier=self._identifier, peer_identifier=self._peer_identifier) - timer = self._stats_client.timer("channel.call_timing").start() - res = self._channel_call.Call(req, - timeout=self._heartbeat_interval, - wait_for_ready=True) - timer.stop() + with metric_collector.emit_timing( + 'model.grpc.channel.call_timing' + ): + res = self._channel_call.Call(req, + timeout=self._heartbeat_interval, + wait_for_ready=True) except Exception as e: - self._stats_client.incr("channel.call_error") + metric_collector.emit_counter('model.grpc.channel.call_error', 1) if isinstance(e, grpc.RpcError): fl_logging.warning("[Channel] grpc error, code: %s, " "details: %s.(call type: %s)", @@ -488,7 +488,8 @@ def _state_fn(self): saved_state = self._state wait_timeout = 10 - self._stats_client.gauge("channel.status", self._state.value) + metric_collector.emit_store('model.grpc.channel.status', + self._state.value) if self._state in (Channel.State.DONE, Channel.State.ERROR): break diff --git a/fedlearner/channel/client_interceptor.py b/fedlearner/channel/client_interceptor.py index 3cd949607..226fb1606 100644 --- a/fedlearner/channel/client_interceptor.py +++ b/fedlearner/channel/client_interceptor.py @@ -20,7 +20,8 @@ import time import grpc -from fedlearner.common import fl_logging, stats +from fedlearner.common import fl_logging +from fedlearner.common.metric_collector import metric_collector from fedlearner.channel import channel_pb2 class _MethodDetail( @@ -46,8 +47,7 @@ def __init__(self, identifier, retry_interval, wait_fn=None, - check_fn=None, - stats_client=None): + check_fn=None): self._retry_interval = retry_interval self._identifer = identifier self._wait_fn = wait_fn @@ -56,7 +56,6 @@ def __init__(self, self._method_details = dict() self._fl_metadata = ("fl-channel-id", self._identifer) - self._stats_client = stats_client or stats.NoneClient() def _wait(self): if self._wait_fn: @@ -102,8 +101,10 @@ def call(): self._wait() return continuation(client_call_details, request) - with self._stats_client.timer("channel.client.unary_unary_timing", - tags={"grpc_method": method_details.method}): + with metric_collector.emit_timing( + 'model.grpc.interceptor.channel.client.unary_unary_timing', + tags={'grpc_method': method_details.method} + ): _call = _grpc_with_retry(call, self._retry_interval) return _UnaryOutcome( method_details.response_deserializer, _call, self._check_fn) @@ -124,10 +125,7 @@ def call(): self._wait() return continuation(client_call_details, request) - timer = self._stats_client.timer( - "channel.client.unary_stream_timing", - tags={"grpc_method": method_details.method} - ).start() + start = time.time() stream_response = _grpc_with_retry(call, self._retry_interval) @@ -135,7 +133,12 @@ def response_iterator(): for response in stream_response: self._check_fn(response) yield method_details.response_deserializer(response.payload) - timer.stop() + value = (time.time() - start) * 1000 + metric_collector.emit_store( + f'model.grpc.interceptor.channel.client.unary_stream_timing', + value, + tags={'grpc_method': method_details.method} + ) return response_iterator() @@ -156,8 +159,10 @@ def call(): consumer = srq.consumer() return continuation(client_call_details, iter(consumer)) - with self._stats_client.timer("channel.client.stream_unary_timing", - tags={"grpc_method": method_details.method}): + with metric_collector.emit_timing( + 'model.grpc.interceptor.channel.client.stream_unary_timing', + tags={'grpc_method': method_details.method} + ): _call = _grpc_with_retry(call, self._retry_interval) return _UnaryOutcome(method_details.response_deserializer, _call, self._check_fn) @@ -173,9 +178,7 @@ def intercept_stream_stream(self, continuation, client_call_details, srq = _SingleConsumerSendRequestQueue( request_iterator, method_details.request_serializer, - stats_client=self._stats_client.with_tags( - tags={"grpc_method": method_details.method} - ), + stats_tags={'grpc_method': method_details.method}, stats_prefix="channel.client.stream_stream") consumer = None @@ -228,7 +231,7 @@ def __next__(self): next = __next__ def __init__(self, request_iterator, request_serializer, - stats_client=None, stats_prefix=""): + stats_tags=None, stats_prefix=""): self._lock = threading.Lock() self._seq = 0 self._offset = 0 @@ -238,13 +241,16 @@ def __init__(self, request_iterator, request_serializer, self._request_lock = threading.Lock() self._request_iterator = request_iterator self._request_serializer = request_serializer - self._stats_client = stats_client or stats.NoneClient() + self._stats_tags = stats_tags or {} self._stats_prefix = stats_prefix def _reset(self): if self._offset > 0: - self._stats_client.incr( - "%s_resend"%self._stats_prefix, self._offset) + metric_collector.emit_counter( + f'model.grpc.interceptor.{self._stats_prefix}_resend', + self._offset, + tags=self._stats_tags + ) self._offset = 0 def _empty(self): @@ -284,12 +290,16 @@ def ack(self, consumer, ack): return False now = time.time() n = self._seq - ack - with self._stats_client.pipeline() as pipe: - while len(self._deque) >= n: - req = self._deque.popleft() - self._offset -= 1 - pipe.timing("%s_timing"%self._stats_prefix, - (now-req.ts)*1000) + while len(self._deque) >= n: + req = self._deque.popleft() + self._offset -= 1 + name_prefix = 'model.grpc.interceptor' + value = (now - req.ts) * 1000 + metric_collector.emit_store( + f'{name_prefix}.{self._stats_prefix}_timing', + value, + tags=self._stats_tags + ) return True def next(self, consumer): @@ -354,7 +364,10 @@ def _grpc_error_need_recover(e): #if 400 <= httpstatus < 500: # return True return True - return False + if e.code() == grpc.StatusCode.UNAUTHENTICATED: + return False + return True # recover in any case + #return False def _grpc_error_get_http_status(details): try: diff --git a/fedlearner/common/common.py b/fedlearner/common/common.py index c5ac423f4..4f5c7ebd1 100644 --- a/fedlearner/common/common.py +++ b/fedlearner/common/common.py @@ -11,7 +11,7 @@ class Config(object): DATA_JOIN_METRICS_SAMPLE_RATE = \ float(os.environ.get('DATA_JOIN_METRICS_SAMPLE_RATE', 0.3)) RAW_DATA_METRICS_SAMPLE_RATE = \ - float(os.environ.get('RAW_DATA_METRICS_SAMPLE_RATE', 0.02)) + float(os.environ.get('RAW_DATA_METRICS_SAMPLE_RATE', 0.0)) ES_BATCH_SIZE = int(float(os.environ.get('ES_BATCH_SIZE', 1000))) TZ = pytz.timezone(os.environ.get('TZ', 'UTC')) ES_USERNAME = os.environ.get('ES_USERNAME', 'elastic') @@ -19,6 +19,7 @@ class Config(object): METRICS_TO_STDOUT = int(float(os.environ.get('METRICS_TO_STDOUT', 0))) +INVALID_DATETIME = datetime.datetime.fromtimestamp(0) # YYYY-MM-DD'T'hh:mm:ss.SSSSSSZ _es_datetime_format = 'strict_date_optional_time' # WARNING: MAPPINGS BELOW ARE COMPATIBILITY MEASURES AND SHOULD NOT BE MODIFIED. @@ -227,8 +228,8 @@ def convert_to_datetime(value, enable_tz=False): except ValueError: # might be a non-number str # 3. default to 0 fl_logging.warning('Unable to parse time %s to iso format, ' - 'defaults to 0.', value) - date_time = datetime.datetime.fromtimestamp(0) + 'defaults to 0.', value) + date_time = INVALID_DATETIME if enable_tz: date_time = set_timezone(date_time) return date_time @@ -270,18 +271,20 @@ def time_diff(minuend, sub): ts_sub = convert_to_datetime(sub, enable_tz=False).timestamp() return ts_minuend - ts_sub + def use_tls(): - enable = os.environ.get("TF_OPTIONAL_TLS_ENABLE", False) + enable = os.getenv("FL_GRPC_SGX_RA_TLS_ENABLE") == "on" if not enable: - return False, None + return False + return True + - key = os.environ.get("TF_OPTIONAL_TLS_CERT_KEY", False) - with open(key, 'rb') as f: - private_key = f.read() - cert = os.environ.get("TF_OPTIONAL_TLS_CERT", False) - with open(cert, 'rb') as f: - certificate_chain = f.read() - root_key = os.environ.get("TF_OPTIONAL_TLS_ROOT_CERT", False) - with open(root_key, 'rb') as f: - root_certificates = f.read() - return True, (root_certificates, private_key, certificate_chain) +def get_tf_config(): + return { + "intra_op_parallelism_threads": \ + int(os.environ.get("INTRA_OP_PARALLELISM_THREADS", 16)), + "inter_op_parallelism_threads": \ + int(os.environ.get("INTER_OP_PARALLELISM_THREADS", 16)), + "grpc_server_channel_threads": \ + int(os.environ.get("GRPC_SERVER_CHANNEL_THREADS", 16)) + } diff --git a/fedlearner/common/grpc_utils.py b/fedlearner/common/grpc_utils.py new file mode 100644 index 000000000..c32d511d7 --- /dev/null +++ b/fedlearner/common/grpc_utils.py @@ -0,0 +1,157 @@ +import time +import collections +import grpc +from . import fl_logging as logging + + +class LocalServicerContext(grpc.ServicerContext): + + def invocation_metadata(self): + return () + + def peer(self): + return "local" + + def peer_identities(self): + return None + + def peer_identity_key(self): + return None + + def auth_context(self): + return dict() + + def set_compression(self, compression): + return grpc.Compression.NoCompression + + def send_initial_metadata(self, initial_metadata): + pass + + def set_trailing_metadata(self, trailing_metadata): + pass + + def abort(self, code, details): + pass + + def abort_with_status(self, status): + pass + + def set_code(self, code): + pass + + def set_details(self, details): + pass + + def disable_next_message_compression(self): + pass + + def is_active(self): + return True + + def time_remaining(self): + return None + + def cancel(self): + pass + + def add_callback(self, callback): + pass + + +def call_with_retry(call, max_retry_times=None, retry_interval=1): + retry_times = 0 + while True: + try: + retry_times += 1 + return call() + except grpc.RpcError as e: + if max_retry_times is None or retry_times < max_retry_times: + logging.warning( + "grpc call error, status: %s" + ", details: %s, wait %ds for retry", e.code(), e.details(), + retry_interval) + time.sleep(retry_interval) + else: + raise e + + +#def remote_insecure_channel(address, options=None, compression=None): +# EGRESS_URL = os.getenv('EGRESS_URL', None) +# EGRESS_HOST = os.environ.get('EGRESS_HOST', None) +# EGRESS_DOMAIN = os.environ.get('EGRESS_DOMAIN', None) +# if not EGRESS_URL: +# return grpc.insecure_channel(address, options, compression) +# +# options = list(options) if options else list() +# default_authority = EGRESS_HOST or address +# options.append(('grpc.default_authority', default_authority)) +# channel = grpc.insecure_channel(EGRESS_URL, options, compression) +# +# if EGRESS_DOMAIN: +# address = address + '.' + EGRESS_DOMAIN +# channel = grpc.intercept_channel( +# channel, add_metadata_interceptor({'x-host': address})) +# +# return channel +# +# +#def add_metadata_interceptor(headers): +# if not isinstance(headers, dict): +# raise TypeError("headers must be a dict") +# headers = list(headers.items()) +# +# def add_metadata_fn(client_call_details, request_iterator, +# request_streaming, response_streaming): +# metadata = list(client_call_details.metadata or []) +# metadata.extend(headers) +# client_call_details = _ClientCallDetails( +# client_call_details.method, client_call_details.timeout, metadata, +# client_call_details.credentials) +# return client_call_details, request_iterator, None +# +# return _GenericClientInterceptor(add_metadata_fn) + + +class _ClientCallDetails( + collections.namedtuple( + '_ClientCallDetails', + ('method', 'timeout', 'metadata', 'credentials')), + grpc.ClientCallDetails): + pass + + +class _GenericClientInterceptor(grpc.UnaryUnaryClientInterceptor, + grpc.UnaryStreamClientInterceptor, + grpc.StreamUnaryClientInterceptor, + grpc.StreamStreamClientInterceptor): + + def __init__(self, interceptor_function): + self._fn = interceptor_function + + def intercept_unary_unary(self, continuation, client_call_details, + request): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, iter((request, )), False, False) + response = continuation(new_details, next(new_request_iterator)) + return postprocess(response) if postprocess else response + + def intercept_unary_stream(self, continuation, client_call_details, + request): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, iter((request, )), False, True) + response_it = continuation(new_details, next(new_request_iterator)) + return postprocess(response_it) if postprocess else response_it + + def intercept_stream_unary(self, continuation, client_call_details, + request_iterator): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, request_iterator, True, False) + response = continuation(new_details, new_request_iterator) + return postprocess(response) if postprocess else response + + def intercept_stream_stream(self, continuation, client_call_details, + request_iterator): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, request_iterator, True, True) + response_it = continuation(new_details, new_request_iterator) + return postprocess(response_it) if postprocess else response_it diff --git a/fedlearner/common/hdfs_util.py b/fedlearner/common/hdfs_util.py new file mode 100644 index 000000000..9cd5499b5 --- /dev/null +++ b/fedlearner/common/hdfs_util.py @@ -0,0 +1,163 @@ +# Copyright 2023 The FedLearner Authors. All Rights Reserved. +# +# 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. +# + +import os +from typing import Optional, Dict, List +import json +import logging +import re + +import fsspec +from urllib.parse import urlparse +from hdfs.ext.kerberos import KerberosClient +from collections import namedtuple + +KEYTAB_FILE_ENV = "KRB5CCNAME" +DEFAULT_SCHEME_TYPE = 'file' +KRB_FILE_PATH = 'KRB_FILE_PATH' +STORAGE_ROOT_PATH = 'MT_HDFS_ROOT_PATH' +HADOOP_SUPPORTED_FILE_PREFIXES = r'\.+\/|^\/|^viewfs:\/\/' +MT_HADOOP_SUPPORTED_FILE_PREFIXES = 'viewfs:' +client = KerberosClient(url='http://data-httpfs.vip.sankuai.com:15000') +File = namedtuple('File', ['path', 'size', 'is_directory']) + + +def init_env(): + if KEYTAB_FILE_ENV not in os.environ: + os.environ[KEYTAB_FILE_ENV] = os.environ[KRB_FILE_PATH] + logging.info(f'Kerberos env : {os.environ[KEYTAB_FILE_ENV]}') + + +def get_root_path(): + return os.environ[STORAGE_ROOT_PATH] + + +def parse_to_mt_path(path: str): + url_parser = urlparse(path) + path = url_parser.path + if path.startswith('/'): + if path.startswith('/data'): + path = path[5:] + if path.startswith(_get_path_no_protocol(get_root_path())): + return f'{MT_HADOOP_SUPPORTED_FILE_PREFIXES}//{path}' + return f'{get_root_path()}{path}' + else: + if path.startswith('data'): + path = path[4:] + if path.startswith(_get_path_no_protocol(get_root_path())): + return f'{MT_HADOOP_SUPPORTED_FILE_PREFIXES}//{path}' + return f'{get_root_path()}/{path}' + + +def upload_to_mt_hdfs(path: str): + fs = fsspec.filesystem('file') + if fs.isdir(path): + mt_path = parse_to_mt_path(remove_last_path(path)) + else: + mt_path = parse_to_mt_path(path) + logging.info(f'upload local path : {path} to mt hdfs path : {mt_path}') + upload(path, mt_path) + + +def _get_path_no_protocol(path: str): + return re.sub(r'^\w+://', '', path) + + +def mkdir(path: str) -> bool: + if path.endswith("*"): + path = remove_last_path(path) + if is_mt_hdfs(path): + if not exists(path): + return client.makedirs(_get_path_no_protocol(path)) + elif not fsspec.get_mapper(path).fs.exists(path): + return fsspec.get_mapper(path).fs.mkdir(path) + return True + + +def is_mt_hdfs(path: str) -> bool: + return path.startswith(MT_HADOOP_SUPPORTED_FILE_PREFIXES) + + +def mt_hadoop_download(hdfs_path: str, is_dir=True) -> str: + if is_mt_hdfs(hdfs_path): + local_input_batch_path = get_local_temp_path(hdfs_path) + logging.info(f'download hdfs file : {hdfs_path} to local path : {local_input_batch_path}') + local_path = remove_last_path(local_input_batch_path) + mkdir(local_path) + if is_dir: + download(local_path, hdfs_path) + elif local_input_batch_path.endswith("*"): + local_path = remove_last_path(local_path) + hdfs_path = remove_last_path(hdfs_path) + download(local_path, hdfs_path) + else: + download(local_input_batch_path, hdfs_path) + return local_input_batch_path + else: + return hdfs_path + + +def remove_last_path(path: str) -> str: + # 如果路径以 "/" 结尾,先去掉末尾的 "/" + if path.endswith("/"): + path = path[:-1] + new_path = "/".join(path.split("/")[:-1]) + # 如果新的路径为空,说明原路径只有一层,直接返回 "/" + if not new_path: + return "/" + # 如果原路径以 "//" 结尾,新路径也要以 "//" 结尾 + if path.endswith("//"): + new_path += "/" + return new_path + + +def exists(path: str) -> bool: + if is_mt_hdfs(path): + info = client.status(_get_path_no_protocol(path), False) + return info is not None + else: + return fsspec.get_mapper(path).fs.exists(path) + + +def isdir(path: str) -> bool: + info = client.status(_get_path_no_protocol(path), False) + if info and info['type'] == 'DIRECTORY': + return True + return False + + +def download(local_path: str, hdfs_path: str) -> bool: + try: + logging.info(f'real download hdfs file : {hdfs_path} to local path : {local_path}') + client.download(_get_path_no_protocol(hdfs_path), _get_path_no_protocol(local_path), overwrite=True) + return True + except Exception as e: + logging.error(f'download file error : {str(e)}') + return False + + +def upload(source: str, destination: str) -> bool: + try: + client.upload(_get_path_no_protocol(destination), _get_path_no_protocol(source), overwrite=True) + return True + except Exception as e: + logging.error(f'upload file error : {str(e)}') + return False + + +def get_local_temp_path(path: str) -> str: + if not path.startswith(DEFAULT_SCHEME_TYPE): + return f'{DEFAULT_SCHEME_TYPE}:///data{_get_path_no_protocol(path)}' + return path diff --git a/fedlearner/common/hooks.py b/fedlearner/common/hooks.py new file mode 100644 index 000000000..b2becbfb7 --- /dev/null +++ b/fedlearner/common/hooks.py @@ -0,0 +1,35 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +import os +import importlib +from typing import Any + + +def parse_and_call_fn(module_fn_path: str) -> Any: + if module_fn_path.find(':') == -1: + raise RuntimeError(f'Invalid module_fn_path: {module_fn_path}') + + module_path, func_name = module_fn_path.split(':') + module = importlib.import_module(module_path) + # Dynamically run the function + return getattr(module, func_name)() + + +def pre_start_hook() -> Any: + before_hook_path = os.getenv('PRE_START_HOOK', None) + if before_hook_path: + return parse_and_call_fn(before_hook_path) + return None diff --git a/fedlearner/common/metric_collector.py b/fedlearner/common/metric_collector.py new file mode 100644 index 000000000..8117aa019 --- /dev/null +++ b/fedlearner/common/metric_collector.py @@ -0,0 +1,269 @@ +# Copyright 2022 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +import logging +from abc import ABC, abstractmethod + +from os import environ +from threading import Lock +from typing import Optional, Union, Dict, Iterator + +from opentelemetry import trace, _metrics as metrics +from opentelemetry._metrics.instrument import UpDownCounter +from opentelemetry._metrics.measurement import Measurement +from opentelemetry.sdk.resources import Resource +from opentelemetry.sdk.trace import TracerProvider, Span +from opentelemetry.sdk._metrics import MeterProvider +from opentelemetry.sdk._metrics.export import \ + ConsoleMetricExporter, PeriodicExportingMetricReader +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter \ + import OTLPSpanExporter +from opentelemetry.exporter.otlp.proto.grpc._metric_exporter \ + import OTLPMetricExporter +from opentelemetry.sdk.trace.export import \ + BatchSpanProcessor, ConsoleSpanExporter + +_logger = logging.getLogger(__name__) + + +class AbstractCollector(ABC): + + @abstractmethod + def add_global_tags(self, global_tags: Dict[str, str]): + pass + + @abstractmethod + def emit_single_point(self, + name: str, + value: Union[int, float], + tags: Dict[str, str] = None): + pass + + @abstractmethod + def emit_timing(self, + name: str, + tags: Dict[str, str] = None): + pass + + @abstractmethod + def emit_counter(self, + name: str, + value: Union[int, float], + tags: Dict[str, str] = None): + pass + + @abstractmethod + def emit_store(self, + name: str, + value: Union[int, float], + tags: Dict[str, str] = None): + pass + + +class StubCollector(AbstractCollector): + + class EmptyTrace(object): + def __init__(self): + pass + + def __enter__(self): + pass + + def __exit__(self, *a): + pass + + def add_global_tags(self, global_tags: Dict[str, str]): + pass + + def emit_single_point(self, + name: str, + value: Union[int, float], + tags: Dict[str, str] = None): + pass + + def emit_timing(self, + name: str, + tags: Dict[str, str] = None): + return self.EmptyTrace() + + def emit_counter(self, + name: str, + value: Union[int, float], + tags: Dict[str, str] = None): + pass + + def emit_store(self, + name: str, + value: Union[int, float], + tags: Dict[str, str] = None): + pass + + +class MetricCollector(AbstractCollector): + _DEFAULT_EXPORT_INTERVAL = 60000 + + class Callback: + + def __init__(self) -> None: + self._measurement_list = [] + + def record(self, value: Union[int, float], tags: dict): + self._measurement_list.append( + Measurement(value=value, attributes=tags)) + + def __iter__(self): + return self + + def __next__(self): + if len(self._measurement_list) == 0: + raise StopIteration + return self._measurement_list.pop(0) + + def __call__(self): + return iter(self) + + def __init__( + self, + service_name: Optional[str] = None, + export_interval_millis: Optional[float] = None, + custom_service_label: Optional[dict] = None, + ): + if service_name is None: + service_name = environ.get('METRIC_COLLECTOR_SERVICE_NAME', + 'default_metric_service') + cluster_name = environ.get('CLUSTER', 'default_cluster') + if export_interval_millis is None: + try: + export_interval_millis = float( + environ.get('METRIC_COLLECTOR_EXPORT_INTERVAL_MILLIS', + self._DEFAULT_EXPORT_INTERVAL) + ) + except ValueError: + _logger.error( + 'Invalid value for export interval, using default %s ms', + self._DEFAULT_EXPORT_INTERVAL) + export_interval_millis = self._DEFAULT_EXPORT_INTERVAL + + # for example, 'http://apm-server-apm-server:8200' + endpoint = environ.get('METRIC_COLLECTOR_EXPORT_ENDPOINT') + if endpoint is not None: + exporter = OTLPMetricExporter(endpoint=endpoint, insecure=True) + else: + exporter = ConsoleMetricExporter() + + reader = PeriodicExportingMetricReader( + exporter=exporter, + export_interval_millis=export_interval_millis) + service_label = { + 'service.name': service_name, + 'deployment.environment': cluster_name + } + if custom_service_label is not None: + service_label.update(custom_service_label) + resource = Resource.create(service_label) + self._meter_provider = MeterProvider( + metric_readers=[reader], + resource=resource + ) + metrics.set_meter_provider(self._meter_provider) + self._meter = metrics.get_meter_provider().get_meter(service_name) + + if endpoint is not None: + exporter = OTLPSpanExporter(endpoint=endpoint) + else: + exporter = ConsoleSpanExporter() + tracer_provider = TracerProvider(resource=resource) + tracer_provider.add_span_processor( + BatchSpanProcessor(exporter) + ) + trace.set_tracer_provider(tracer_provider) + self._tracer = trace.get_tracer_provider().get_tracer(service_name) + + self._lock = Lock() + self._cache: \ + Dict[str, Union[UpDownCounter, MetricCollector.Callback]] = {} + + self._global_tags = {} + + def add_global_tags(self, global_tags: Dict[str, str]): + self._global_tags.update(global_tags) + + def emit_single_point(self, + name: str, + value: Union[int, float], + tags: Dict[str, str] = None): + cb = self.Callback() + self._meter.create_observable_gauge( + name=f'values.{name}', callback=cb + ) + cb.record(value=value, tags=self._get_merged_tags(tags)) + + def emit_timing(self, + name: str, + tags: Dict[str, str] = None) -> Iterator[Span]: + return self._tracer.start_as_current_span( + name=name, attributes=self._get_merged_tags(tags)) + + def emit_counter(self, + name: str, + value: Union[int, float], + tags: Dict[str, str] = None): + if name not in self._cache: + with self._lock: + # Double check `self._cache` content. + if name not in self._cache: + counter = self._meter.create_up_down_counter( + name=f'values.{name}' + ) + self._cache[name] = counter + assert isinstance(self._cache[name], UpDownCounter) + self._cache[name].add(value, attributes=self._get_merged_tags(tags)) + + def emit_store(self, + name: str, + value: Union[int, float], + tags: Dict[str, str] = None): + if name not in self._cache: + with self._lock: + # Double check `self._cache` content. + if name not in self._cache: + cb = self.Callback() + self._meter.create_observable_gauge( + name=f'values.{name}', callback=cb + ) + self._cache[name] = cb + assert isinstance(self._cache[name], self.Callback) + self._cache[name].record(value=value, + tags=self._get_merged_tags(tags)) + + def _get_merged_tags(self, tags: Dict[str, str] = None): + merged = self._global_tags.copy() + if tags is not None: + merged.update(tags) + return merged + + +enable = True +enable_env = environ.get('METRIC_COLLECTOR_ENABLE') +if enable_env is None: + enable = False +elif enable_env.lower() in ['false', 'f']: + enable = False + +k8s_job_name = environ.get('APPLICATION_ID', + 'default_k8s_job_name') +global_service_label = {'k8s_job_name': k8s_job_name} +metric_collector = MetricCollector( + custom_service_label=global_service_label) if enable else StubCollector() diff --git a/fedlearner/common/mysql_client.py b/fedlearner/common/mysql_client.py index 00e30ae2a..cb3708f50 100644 --- a/fedlearner/common/mysql_client.py +++ b/fedlearner/common/mysql_client.py @@ -17,12 +17,25 @@ import os from contextlib import contextmanager -from sqlalchemy import create_engine +from sqlalchemy import create_engine, Column, Integer, String, Text from sqlalchemy.orm import sessionmaker, scoped_session from sqlalchemy.orm.exc import NoResultFound -from sqlalchemy.ext.automap import automap_base +from sqlalchemy.ext.declarative import declarative_base from . import fl_logging +Base = declarative_base() + + +class DatasourceMeta(Base): + __tablename__ = 'datasource_meta' + __table_args__ = {'comment': 'data source meta kvstore'} + + id = Column(Integer, primary_key=True, comment='row id') + kv_key = Column(String(255), nullable=False, unique=True, + comment='key for kv store') + kv_value = Column(Text, comment='value for kv store') + + class MySQLClient(object): def __init__(self, database, addr, user, password, base_dir): self._unix_socket = os.environ.get('DB_SOCKET_PATH', None) @@ -41,9 +54,9 @@ def __init__(self, database, addr, user, password, base_dir): def get_data(self, key): with self.closing(self._engine) as sess: try: - table = self._datasource_meta - value = sess.query(table).filter(table.kv_key == - self._generate_key(key)).one().kv_value + value = sess.query(DatasourceMeta).filter( + DatasourceMeta.kv_key == self._generate_key(key) + ).one().kv_value if isinstance(value, str): return value.encode() return value @@ -57,14 +70,13 @@ def get_data(self, key): def set_data(self, key, data): with self.closing(self._engine) as sess: try: - table = self._datasource_meta - context = sess.query(table).filter(table.kv_key == - self._generate_key(key)).first() + context = sess.query(DatasourceMeta).filter( + DatasourceMeta.kv_key == self._generate_key(key)).first() if context: context.kv_value = data sess.commit() else: - context = self._datasource_meta( + context = DatasourceMeta( kv_key=self._generate_key(key), kv_value=data) sess.add(context) @@ -79,9 +91,8 @@ def set_data(self, key, data): def delete(self, key): with self.closing(self._engine) as sess: try: - table = self._datasource_meta - for context in sess.query(table).filter(table.kv_key == - self._generate_key(key)): + for context in sess.query(DatasourceMeta).filter( + DatasourceMeta.kv_key == self._generate_key(key)): sess.delete(context) sess.commit() return True @@ -93,9 +104,8 @@ def delete(self, key): def delete_prefix(self, key): with self.closing(self._engine) as sess: try: - table = self._datasource_meta - for context in sess.query(table).filter(table.kv_key.\ - like(self._generate_key(key) + '%')): + for context in sess.query(DatasourceMeta).filter( + DatasourceMeta.kv_key.like(self._generate_key(key) + '%')): sess.delete(context) sess.commit() return True @@ -107,16 +117,16 @@ def delete_prefix(self, key): def cas(self, key, old_data, new_data): with self.closing(self._engine) as sess: try: - table = self._datasource_meta flag = True if old_data is None: - context = self._datasource_meta( + context = DatasourceMeta( kv_key=self._generate_key(key), kv_value=new_data) sess.add(context) sess.commit() else: - context = sess.query(table).filter(table.kv_key ==\ + context = sess.query(DatasourceMeta).filter( + DatasourceMeta.kv_key ==\ self._generate_key(key)).one() if context.kv_value != old_data: flag = False @@ -134,9 +144,9 @@ def get_prefix_kvs(self, prefix, ignor_prefix=False): path = self._generate_key(prefix) with self.closing(self._engine) as sess: try: - table = self._datasource_meta - for context in sess.query(table).filter(table.kv_key.\ - like(path + '%')).order_by(table.kv_key): + for context in sess.query(DatasourceMeta).filter( + DatasourceMeta.kv_key.like(path + '%')).order_by( + DatasourceMeta.kv_key): if ignor_prefix and context.kv_key == path: continue nkey = self._normalize_output_key(context.kv_key, @@ -186,9 +196,9 @@ def _create_engine_inner(self): conn_string = conn_string + sub self._engine = create_engine(conn_string, echo=False, pool_recycle=180) - Base = automap_base() - Base.prepare(self._engine, reflect=True) - self._datasource_meta = Base.classes.datasource_meta + # Creates table if not exists + Base.metadata.create_all(bind=self._engine, + checkfirst=True) except Exception as e: raise ValueError('create mysql engine failed; [{}]'.\ format(e)) diff --git a/fedlearner/data_join/cmd/data_portal_master_service.py b/fedlearner/data_join/cmd/data_portal_master_service.py index 306f9c87b..0e2e40fc7 100644 --- a/fedlearner/data_join/cmd/data_portal_master_service.py +++ b/fedlearner/data_join/cmd/data_portal_master_service.py @@ -15,6 +15,8 @@ # coding: utf-8 import argparse +import logging +import sys from google.protobuf import text_format from fedlearner.common import data_portal_service_pb2 as dp_pb @@ -55,18 +57,23 @@ help='Only process one subfolder at a time') parser.add_argument('--files_per_job_limit', type=int, default=None, help='Max number of files in a job') + parser.add_argument('--start_date', type=str, default=None, + help='Start date of input data, format %Y%m%d') + parser.add_argument('--end_date', type=str, default=None, + help='End date of input data, format %Y%m%d') args = parser.parse_args() set_logger() use_mock_etcd = (args.kvstore_type == 'mock') kvstore = DBClient(args.kvstore_type, use_mock_etcd) kvstore_key = common.portal_kvstore_base_dir(args.data_portal_name) - if kvstore.get_data(kvstore_key) is None: + portal_manifest = kvstore.get_data(kvstore_key) + data_portal_type = dp_pb.DataPortalType.PSI if \ + args.data_portal_type == 'PSI' else dp_pb.DataPortalType.Streaming + if portal_manifest is None: portal_manifest = dp_pb.DataPortalManifest( name=args.data_portal_name, - data_portal_type=(dp_pb.DataPortalType.PSI if - args.data_portal_type == 'PSI' else - dp_pb.DataPortalType.Streaming), + data_portal_type=data_portal_type, output_partition_num=args.output_partition_num, input_file_wildcard=args.input_file_wildcard, input_base_dir=args.input_base_dir, @@ -76,13 +83,36 @@ ) kvstore.set_data(kvstore_key, text_format.\ MessageToString(portal_manifest)) + else: # validation parameter consistency + passed = True + portal_manifest = \ + text_format.Parse(portal_manifest, dp_pb.DataPortalManifest(), + allow_unknown_field=True) + parameter_pairs = [ + (portal_manifest.data_portal_type, data_portal_type), + (portal_manifest.output_partition_num, args.output_partition_num), + (portal_manifest.input_file_wildcard, args.input_file_wildcard), + (portal_manifest.input_base_dir, args.input_base_dir), + (portal_manifest.output_base_dir, args.output_base_dir), + (portal_manifest.raw_data_publish_dir, args.raw_data_publish_dir) + ] + for old, new in parameter_pairs: + if old != new: + logging.fatal( + "Parameters of the job changed (%s vs %s) which is " + "forbidden, you should create a new job to do this", + old, new) + sys.exit(-1) options = dp_pb.DataPotraMasterlOptions( use_mock_etcd=use_mock_etcd, long_running=args.long_running, check_success_tag=args.check_success_tag, single_subfolder=args.single_subfolder, - files_per_job_limit=args.files_per_job_limit) + files_per_job_limit=args.files_per_job_limit, + start_date=args.start_date, + end_date=args.end_date + ) portal_master_srv = DataPortalMasterService(args.listen_port, args.data_portal_name, diff --git a/fedlearner/data_join/cmd/rsa_psi_preprocessor_cli.py b/fedlearner/data_join/cmd/rsa_psi_preprocessor_cli.py index 0cc2a96b7..6af346170 100644 --- a/fedlearner/data_join/cmd/rsa_psi_preprocessor_cli.py +++ b/fedlearner/data_join/cmd/rsa_psi_preprocessor_cli.py @@ -17,7 +17,6 @@ import argparse import logging import os -import traceback import tensorflow_io # pylint: disable=unused-import from tensorflow.compat.v1 import gfile @@ -118,9 +117,7 @@ if offload_processor_number < 0: offload_processor_number = int(os.environ.get('CPU_LIMIT', '2')) - 1 if offload_processor_number < 1: - logging.fatal("we should at least retain 1 cpu for compute task") - traceback.print_stack() - os._exit(-1) # pylint: disable=protected-access + offload_processor_number = 1 preprocessor_options = dj_pb.RsaPsiPreProcessorOptions( preprocessor_name=args.preprocessor_name, rsa_key_pem=rsa_key_pem, diff --git a/fedlearner/data_join/cmd/rsa_psi_signer_service.py b/fedlearner/data_join/cmd/rsa_psi_signer_service.py index b43f959e3..99e9538f1 100644 --- a/fedlearner/data_join/cmd/rsa_psi_signer_service.py +++ b/fedlearner/data_join/cmd/rsa_psi_signer_service.py @@ -48,7 +48,8 @@ rsa_private_key = rsa.PrivateKey.load_pkcs1(rsa_private_key_pem) offload_processor_number = args.signer_offload_processor_number if offload_processor_number < 0: - offload_processor_number = int(os.environ.get('CPU_LIMIT', '1')) - 1 + offload_processor_number = max( + 1, int(os.environ.get('CPU_LIMIT', '1')) - 1) rsa_psi_signer = RsaPsiSigner(rsa_private_key, offload_processor_number, args.slow_sign_threshold) diff --git a/fedlearner/data_join/common.py b/fedlearner/data_join/common.py index c5bf89db5..e9950a48a 100644 --- a/fedlearner/data_join/common.py +++ b/fedlearner/data_join/common.py @@ -234,7 +234,7 @@ def convert_tf_example_to_dict(src_tf_example): else: assert False, "feat type must in int64, byte, float" assert isinstance(csv_val, list) - dst_dict[key] = csv_val[0] if len(csv_val) == 1 else csv_val + dst_dict[key] = csv_val return dst_dict def int2bytes(digit, byte_len, byteorder='little'): @@ -302,6 +302,11 @@ def get_heap_mem_usage(self): return hpy().heap().size def _update_rss_mem_usage(self): + use_sgx = os.getenv('SGX') == '1' + # cannot get Process in sgx enclave + if use_sgx: + self._rss_mem_usage = 0 + return self._rss_mem_usage with self._lock: if time.time() - self._rss_updated_tm >= 0.25: self._rss_mem_usage = psutil.Process().memory_info().rss diff --git a/fedlearner/data_join/data_join_master.py b/fedlearner/data_join/data_join_master.py index c2485f012..5ab5686f2 100644 --- a/fedlearner/data_join/data_join_master.py +++ b/fedlearner/data_join/data_join_master.py @@ -532,7 +532,10 @@ def __init__(self, listen_port, peer_addr, data_source_name, peer_client = dj_grpc.DataJoinMasterServiceStub(channel) self._data_source_name = data_source_name self._listen_port = listen_port - self._server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + self._server = grpc.server( + futures.ThreadPoolExecutor(max_workers=10), + options=[('grpc.max_send_message_length', 2**31-1), + ('grpc.max_receive_message_length', 2**31-1)]) self._data_join_master = DataJoinMaster( peer_client, data_source_name, kvstore_type, options ) diff --git a/fedlearner/data_join/data_join_worker.py b/fedlearner/data_join/data_join_worker.py index c13e23c3b..a903e55ab 100644 --- a/fedlearner/data_join/data_join_worker.py +++ b/fedlearner/data_join/data_join_worker.py @@ -232,7 +232,11 @@ def __init__(self, listen_port, peer_addr, master_addr, rank_id, data_source = self._sync_data_source() self._data_source_name = data_source.data_source_meta.name self._listen_port = listen_port - self._server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + self._server = grpc.server( + futures.ThreadPoolExecutor(max_workers=10), + options=[('grpc.max_send_message_length', 2**31-1), + ('grpc.max_receive_message_length', 2**31-1)]) + peer_channel = make_insecure_channel( peer_addr, ChannelType.REMOTE, options=[('grpc.max_send_message_length', 2**31-1), diff --git a/fedlearner/data_join/data_portal_job_manager.py b/fedlearner/data_join/data_portal_job_manager.py index 4d85aa0f1..d01858214 100644 --- a/fedlearner/data_join/data_portal_job_manager.py +++ b/fedlearner/data_join/data_portal_job_manager.py @@ -25,15 +25,17 @@ from fedlearner.common import data_portal_service_pb2 as dp_pb +from fedlearner.common.common import convert_to_datetime, INVALID_DATETIME from fedlearner.data_join import common from fedlearner.data_join.raw_data_publisher import RawDataPublisher from fedlearner.data_join.sort_run_merger import MergedSortRunMeta class DataPortalJobManager(object): + def __init__(self, kvstore, portal_name, long_running, check_success_tag, single_subfolder, files_per_job_limit, - max_files_per_job=8000): + max_files_per_job=8000, start_date=None, end_date=None): self._lock = threading.Lock() self._kvstore = kvstore self._portal_name = portal_name @@ -41,6 +43,8 @@ def __init__(self, kvstore, portal_name, long_running, check_success_tag, self._single_subfolder = single_subfolder self._files_per_job_limit = files_per_job_limit self._max_files_per_job = max_files_per_job + self._start_date = convert_to_datetime(start_date) + self._end_date = convert_to_datetime(end_date) self._portal_manifest = None self._processing_job = None self._sync_portal_manifest() @@ -335,6 +339,17 @@ def _list_dir_helper(self, root): res.append(fname) return res + def _is_wanted_date(self, cur_date_str): + cur_date = convert_to_datetime(cur_date_str) + if cur_date != INVALID_DATETIME: + if self._start_date != INVALID_DATETIME and \ + cur_date < self._start_date: + return False + if self._end_date != INVALID_DATETIME and \ + cur_date >= self._end_date: + return False + return True + def _list_input_dir(self): logging.info("List input directory, it will take some time...") root = self._portal_manifest.input_base_dir @@ -351,7 +366,6 @@ def _list_input_dir(self): by_folder = {} for fname in all_files: splits = path.split(path.relpath(fname, root)) - basename = splits[-1] dirnames = splits[:-1] # ignore files and dirs starting with _ or . @@ -368,7 +382,6 @@ def _list_input_dir(self): # check wildcard if wildcard and not fnmatch(fname, wildcard): continue - num_target_files += 1 # check success tag if self._check_success_tag: @@ -376,14 +389,20 @@ def _list_input_dir(self): if succ_fname not in all_files: continue + # check dirname is wanted date + folder_name = path.basename(dirnames[-1]) + if not self._is_wanted_date(folder_name): + continue + + num_target_files += 1 + if fname in self._processed_fpath: continue num_new_files += 1 - folder = path.join(*dirnames) - if folder not in by_folder: - by_folder[folder] = [] - by_folder[folder].append(fname) + if folder_name not in by_folder: + by_folder[folder_name] = [] + by_folder[folder_name].append(fname) if not by_folder: rest_fpaths = [] @@ -410,7 +429,7 @@ def _list_input_dir(self): logging.info( 'Listing %s: found %d dirs, %d files, %d tmp files ignored, ' - '%d files matching wildcard, %d new files to process. ' + '%d files matching condition, %d new files to process. ' 'Processing %d files in this iteration.', root, len(by_folder), len(all_files), num_ignored, num_target_files, num_new_files, len(rest_fpaths)) diff --git a/fedlearner/data_join/data_portal_master.py b/fedlearner/data_join/data_portal_master.py index 2543baa8b..7607a2bec 100644 --- a/fedlearner/data_join/data_portal_master.py +++ b/fedlearner/data_join/data_portal_master.py @@ -40,7 +40,9 @@ def __init__(self, portal_name, kvstore, portal_options): self._portal_options.long_running, self._portal_options.check_success_tag, self._portal_options.single_subfolder, - self._portal_options.files_per_job_limit + self._portal_options.files_per_job_limit, + start_date=self._portal_options.start_date, + end_date=self._portal_options.end_date ) self._bg_worker = None diff --git a/fedlearner/data_join/joiner_impl/example_joiner.py b/fedlearner/data_join/joiner_impl/example_joiner.py index 69951e76d..975abcd3d 100644 --- a/fedlearner/data_join/joiner_impl/example_joiner.py +++ b/fedlearner/data_join/joiner_impl/example_joiner.py @@ -156,6 +156,7 @@ def _sync_state(self): logging.warning("leader visitor finished") try: self._follower_visitor.seek(meta.follower_restart_index) + self._follower_restart_index = meta.follower_restart_index except StopIteration: logging.warning("follower visitor finished") else: @@ -177,9 +178,10 @@ def _get_data_block_builder(self, create_if_no_existed): self._data_block_builder.set_data_block_manager( self._data_block_manager ) + if self._data_block_builder: self._data_block_builder.set_follower_restart_index( - self._follower_restart_index - ) + self._follower_restart_index + ) return self._data_block_builder def _finish_data_block(self): diff --git a/fedlearner/data_join/joiner_impl/optional_stats.py b/fedlearner/data_join/joiner_impl/optional_stats.py index 598720f40..c481280ec 100644 --- a/fedlearner/data_join/joiner_impl/optional_stats.py +++ b/fedlearner/data_join/joiner_impl/optional_stats.py @@ -7,6 +7,7 @@ import pytz +import fedlearner.data_join.common as djc import fedlearner.common.data_join_service_pb2 as dj_pb from fedlearner.common.common import convert_to_datetime from fedlearner.common.metrics import emit, Config @@ -72,8 +73,10 @@ def update_stats(self, item, kind='joined'): if random.random() < self._sample_rate: tags = copy.deepcopy(self._tags) tags.update(item_stat) - tags['event_time'] = convert_to_datetime(item.event_time, True) \ - .isoformat(timespec='microseconds') + if item.event_time != djc.InvalidEventTime: + tags['event_time'] = convert_to_datetime( + item.event_time, True + ).isoformat(timespec='microseconds') tags['process_time'] = datetime.now(tz=pytz.utc) \ .isoformat(timespec='microseconds') emit(name='', value=0, tags=tags, index_type='data_join') diff --git a/fedlearner/data_join/raw_data_iter_impl/csv_dict_iter.py b/fedlearner/data_join/raw_data_iter_impl/csv_dict_iter.py index 26b0bdcdf..32faf34a9 100644 --- a/fedlearner/data_join/raw_data_iter_impl/csv_dict_iter.py +++ b/fedlearner/data_join/raw_data_iter_impl/csv_dict_iter.py @@ -50,14 +50,15 @@ def make(cls, example_id, event_time, raw_id, fname=None, fvalue=None): def __getattr__(self, item): if item not in self._features and common.ALLOWED_FIELDS[item].must: - logging.warning("%s misses field %s:%s", + logging.debug("%s misses field %s:%s", self.__class__.__name__, item, common.ALLOWED_FIELDS[item]) value = self._features.get(item, common.ALLOWED_FIELDS[item].default_value) # csv doesn't support bytes and int field = common.ALLOWED_FIELDS[item] - if field.type == bytes: + # value is b'' if field not exist' + if field.type == bytes and isinstance(value, str): return value.encode() if field.type == int: return int(value) diff --git a/fedlearner/data_join/raw_data_iter_impl/metric_stats.py b/fedlearner/data_join/raw_data_iter_impl/metric_stats.py index 95824ad8d..5fec60d21 100644 --- a/fedlearner/data_join/raw_data_iter_impl/metric_stats.py +++ b/fedlearner/data_join/raw_data_iter_impl/metric_stats.py @@ -4,6 +4,7 @@ import pytz +import fedlearner.data_join.common as djc from fedlearner.common import metrics, common from fedlearner.data_join.common import convert_to_str from fedlearner.common.common import convert_to_datetime @@ -21,9 +22,13 @@ def emit_metric(self, item): for field in self._stat_fields: value = convert_to_str(getattr(item, field, '#None#')) tags[field] = value - tags['example_id'] = convert_to_str(item.example_id) - tags['event_time'] = convert_to_datetime(item.event_time, True) \ - .isoformat(timespec='microseconds') + if item.example_id != djc.InvalidExampleId: + tags['example_id'] = convert_to_str(item.example_id) + if item.event_time != djc.InvalidEventTime: + tags['event_time'] = convert_to_datetime( + item.event_time, True + ).isoformat(timespec='microseconds') + tags['process_time'] = datetime.now(tz=pytz.utc) \ .isoformat(timespec='microseconds') metrics.emit_store(name='input_data', value=0, tags=tags, diff --git a/fedlearner/data_join/raw_data_iter_impl/tf_record_iter.py b/fedlearner/data_join/raw_data_iter_impl/tf_record_iter.py index ec975582f..2f3c9dfb0 100644 --- a/fedlearner/data_join/raw_data_iter_impl/tf_record_iter.py +++ b/fedlearner/data_join/raw_data_iter_impl/tf_record_iter.py @@ -34,7 +34,11 @@ def __init__(self, record_str, cache_type=None, index=None): self._parse_example_error = False example = self._parse_example(record_str) dic = common.convert_tf_example_to_dict(example) - self._features.update({key: dic[key] for key in dic + # should not be list for data block + new_dict = {} + for key, val in dic.items(): + new_dict[key] = val[0] if len(val) == 1 else val + self._features.update({key: new_dict[key] for key in new_dict if key in common.ALLOWED_FIELDS.keys()}) self._set_tf_record(record_str) self._csv_record = None diff --git a/fedlearner/data_join/raw_data_iter_impl/validator.py b/fedlearner/data_join/raw_data_iter_impl/validator.py index e43b4c0f6..4bb8ddbe9 100644 --- a/fedlearner/data_join/raw_data_iter_impl/validator.py +++ b/fedlearner/data_join/raw_data_iter_impl/validator.py @@ -50,8 +50,11 @@ def check_tfrecord(self, raw_data): try: example = tf.train.Example() example.ParseFromString(raw_data) - example_dict = \ + org_dict = \ convert_tf_example_to_dict(example) + example_dict = {} + for key, val in org_dict.items(): + example_dict[key] = val[0] if len(val) == 1 else val if not self._check(example_dict): return False except Exception as e: # pylint: disable=broad-except diff --git a/fedlearner/data_join/rsa_psi/rsa_psi_preprocessor.py b/fedlearner/data_join/rsa_psi/rsa_psi_preprocessor.py index f36310431..f2faa414f 100644 --- a/fedlearner/data_join/rsa_psi/rsa_psi_preprocessor.py +++ b/fedlearner/data_join/rsa_psi/rsa_psi_preprocessor.py @@ -159,11 +159,11 @@ def _bye_for_signer(self): except Exception as e: # pylint: disable=broad-except logging.warning("Failed to say bye to signer at "\ "round %d, sleep 10s and retry", rnd) - time.sleep(10) + time.sleep(2) logging.warning("Give up to say bye to signer after try 60"\ "times, rsa_psi_preprocessor will exit as -1") traceback.print_stack() - os._exit(-1) # pylint: disable=protected-access + os._exit(-1) # pylint: disable=protected-access def _id_batch_fetcher_name(self): return self._repr + ':id_batch_fetcher' diff --git a/fedlearner/data_join/rsa_psi/rsa_psi_signer.py b/fedlearner/data_join/rsa_psi/rsa_psi_signer.py index a3d531cb5..e890e5df0 100644 --- a/fedlearner/data_join/rsa_psi/rsa_psi_signer.py +++ b/fedlearner/data_join/rsa_psi/rsa_psi_signer.py @@ -135,7 +135,9 @@ def start(self, listen_port, worker_num): logging.info('RsaPsiSigner Server start on port[%d].', listen_port) def stop(self): - self._server.stop(None) + # Sometimes the client does not receive the server's bye response, + # stops gracefully to wait client's retries. + self._server.stop(30) if self._process_pool_executor is not None: self._process_pool_executor.shutdown(True) logging.info('RsaPsiSigner Server stopped') diff --git a/fedlearner/data_join/sort_run_dumper.py b/fedlearner/data_join/sort_run_dumper.py index a69c6995f..0eba90b73 100644 --- a/fedlearner/data_join/sort_run_dumper.py +++ b/fedlearner/data_join/sort_run_dumper.py @@ -179,7 +179,7 @@ def _sync_manager_state(self, init): if gfile.Exists(self._fly_sort_run_dumper.tmp_fpath): gfile.Remove(self._fly_sort_run_dumper.tmp_fpath) fpath = self._fly_sort_run_dumper.fpath - if fpath is None and gfile.Exists(fpath): + if fpath is not None and gfile.Exists(fpath): fname = path.basename(fpath) meta = SortRunMeta.decode_sort_run_meta_from_fname(fname) self._dumped_sort_run_metas.append(meta) diff --git a/fedlearner/fedavg/__init__.py b/fedlearner/fedavg/__init__.py new file mode 100644 index 000000000..685b590ee --- /dev/null +++ b/fedlearner/fedavg/__init__.py @@ -0,0 +1,2 @@ + +from .fedavg import train_from_keras_model diff --git a/fedlearner/fedavg/_global_context.py b/fedlearner/fedavg/_global_context.py new file mode 100644 index 000000000..e6cc71b92 --- /dev/null +++ b/fedlearner/fedavg/_global_context.py @@ -0,0 +1,50 @@ +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +import os +import threading +from fedlearner.common import stats + +class _GlobalContext: + def __init__(self): + self.job = os.getenv("FL_JOB") \ + or os.getenv("APPLICATION_ID") \ + or "unknow" + self.task = os.getenv("FL_TASK") \ + or "unknow" + self.task_index = os.getenv("FL_TASK_INDEX") \ + or os.getenv("INDEX") \ + or "0" + self.task_index = int(self.task_index) + + self._stats_client = None + + self._lock = threading.Lock() + + @property + def stats_client(self): + if self._stats_client: + return self._stats_client + + with self._lock: + if not self._stats_client: + self._stats_client = stats.with_tags({ + "job": self.job, + "task": self.task, + "task_index": self.task_index, + }) + + return self._stats_client + +global_context = _GlobalContext() diff --git a/fedlearner/fedavg/cluster/__init__.py b/fedlearner/fedavg/cluster/__init__.py new file mode 100644 index 000000000..67f02f678 --- /dev/null +++ b/fedlearner/fedavg/cluster/__init__.py @@ -0,0 +1,3 @@ + +from .cluster_pb2 import FLNodeDef, FLClusterDef +from .cluster_spec import FLClusterSpec diff --git a/fedlearner/fedavg/cluster/cluster.proto b/fedlearner/fedavg/cluster/cluster.proto new file mode 100644 index 000000000..3cd8495f9 --- /dev/null +++ b/fedlearner/fedavg/cluster/cluster.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package fedlearner.cluster; + +message FLNodeDef { + string name = 1; + string address = 2; +} + +message FLClusterDef { + FLNodeDef leader = 1; + repeated FLNodeDef followers = 2; +} \ No newline at end of file diff --git a/fedlearner/fedavg/cluster/cluster_spec.py b/fedlearner/fedavg/cluster/cluster_spec.py new file mode 100644 index 000000000..ab9f469d3 --- /dev/null +++ b/fedlearner/fedavg/cluster/cluster_spec.py @@ -0,0 +1,66 @@ +import json + +from google.protobuf import json_format +from .cluster_pb2 import FLClusterDef + + +class FLClusterSpec(): + + def __init__(self, cluster): + if isinstance(cluster, FLClusterSpec): + self._cluster_def = FLClusterDef() + self._cluster_def.CopyFrom(cluster.as_cluster_def()) + elif isinstance(cluster, dict): + self._cluster_def = json_format.Parse(json.dumps(cluster), + FLClusterDef()) + elif isinstance(cluster, str): + self._cluster_def = json_format.Parse(cluster, FLClusterDef()) + else: + raise TypeError("'cluster' must be a FederatedClusterSpec," + " or dict, or a str of json") + + self._check_and_load() + + def _check_and_load(self): + if not self._cluster_def.leader: + raise ValueError("leader not found") + + self._leader = self._cluster_def.leader + if not self._leader.name: + raise ValueError("leader name not found") + if not self._leader.address: + raise ValueError("leader address not found") + + self._follower_mapping = {} + for f in self._cluster_def.followers: + if not f.name: + raise ValueError("follower name not found") + if f.name == self._leader.name: + raise ValueError("ambiguity follower and leader: {}".format( + f.name)) + if f.name in self._follower_mapping: + raise ValueError("duplicated follower: {}".format(f.name)) + self._follower_mapping[f.name] = f + + def as_cluster_def(self): + return self._cluster_def + + def as_json(self): + return json_format.MessageToJson(self._cluster_def) + + @property + def leader(self): + return self._leader + + @property + def followers(self): + return list(self._cluster_def.followers) + + def follower(self, name: str): + return self._follower_mapping.get(name, None) + + def is_leader(self, name: str): + return self._leader.name == name + + def is_follower(self, name: str): + return name in self._follower_mapping diff --git a/fedlearner/fedavg/fedavg.py b/fedlearner/fedavg/fedavg.py new file mode 100644 index 000000000..2983756ea --- /dev/null +++ b/fedlearner/fedavg/fedavg.py @@ -0,0 +1,100 @@ +import os +import tensorflow as tf +from fedlearner.common import metrics +from fedlearner.common.metric_collector import metric_collector +from fedlearner.fedavg.master import LeaderMaster, FollowerMaster +from fedlearner.fedavg.cluster.cluster_spec import FLClusterSpec +from fedlearner.fedavg._global_context import global_context as _gtx + + +class MasterControlKerasCallback(tf.keras.callbacks.Callback): + + def __init__(self, master): + self._master = master + super().__init__() + self._global_step = None + self._metrics = {} + + def on_train_begin(self, logs): + self._master.on_train_begin() + + def on_train_end(self, logs): + self._master.on_train_end() + self.emit_metrics() + + def on_train_batch_begin(self, batch, logs=None): + self._master.on_train_batch_begin() + + def on_train_batch_end(self, batch, logs=None): + self._master.on_train_batch_end() + self.update_metrics(logs) + + def update_metrics(self, logs): + if 'batch' not in logs: + return + + self._global_step = logs['batch'] + self._metrics = logs + if self._global_step % 10 == 0: + self.emit_metrics() + + def emit_metrics(self): + if self._global_step is None: + return + stats_pipe = _gtx.stats_client.pipeline() + stats_pipe.gauge("trainer.metric_global_step", self._global_step) + for key, value in self._metrics.items(): + if key in ('size', 'batch'): + continue + stats_pipe.gauge("trainer.metric_value", + value, tags={"metric": key}) + metrics.emit_store(name=key, value=value) + + name_prefix = 'model.train.nn_horizontal' + metric_collector.emit_store( + f'{name_prefix}.{key}', value) + # for compatibility, also emit one with metric name in tags + metric_collector.emit_store(f'{name_prefix}.metric_value', + value, tags={'metric': key}) + stats_pipe.send() + + +def train_from_keras_model(model, + x=None, + y=None, + batch_size=None, + epochs=1, + fl_name=None, + fl_cluster=None, + steps_per_sync=None, + save_filepath=None): + + if not fl_name: + fl_name = os.getenv("FL_NAME") + if not fl_cluster: + fl_cluster = os.getenv("FL_CLUSTER") + if not steps_per_sync: + steps_per_sync = int(os.getenv("FL_STPES_PER_SYNC")) + if not save_filepath: + save_filepath = os.getenv("FL_SAVE_FILEPATH") or os.getenv( + "EXPORT_PATH") + + fl_cluster_spec = FLClusterSpec(fl_cluster) + if fl_cluster_spec.is_leader(fl_name): + master_class = LeaderMaster + elif fl_cluster_spec.is_follower(fl_name): + master_class = FollowerMaster + else: + raise ValueError("unknow fl_name: {}".format(fl_name)) + + master = master_class(model, fl_name, fl_cluster_spec, steps_per_sync, + save_filepath) + master.start() + history = model.fit(x, + y, + batch_size=batch_size, + epochs=epochs, + callbacks=[MasterControlKerasCallback(master)]) + master.wait() + + return history diff --git a/fedlearner/fedavg/master.py b/fedlearner/fedavg/master.py new file mode 100644 index 000000000..aa55fb70c --- /dev/null +++ b/fedlearner/fedavg/master.py @@ -0,0 +1,503 @@ +import os +import time +import threading +from io import BytesIO +from concurrent.futures import ThreadPoolExecutor +import grpc +import numpy as np + +import fedlearner.common.fl_logging as logging +import fedlearner.common.grpc_utils as grpc_utils +from fedlearner.proxy.channel import make_insecure_channel, ChannelType +from .training_service_pb2 import \ + JoinRequest, JoinResponse, QuitRequest, QuitResponse, \ + PullRequest, PullResponse, PushRequest, PushResponse, Weight, Status +from .training_service_pb2_grpc import TrainingServiceServicer, \ + add_TrainingServiceServicer_to_server, TrainingServiceStub + + +class _Master: + + def __init__(self, model, steps_per_sync, save_filepath): + self._model = model + + self._version = 0 + self._timestamp = 0 + self._step = 0 + self._steps_per_sync = steps_per_sync if steps_per_sync > 0 else 1 + self._save_filepath = save_filepath + self._trainable_weights = \ + {v.name for v in self._model.trainable_weights} + + def on_train_begin(self): + self._initialize() + + def on_train_batch_begin(self): + self._step += 1 + return self._step + + def on_train_batch_end(self): + if self._step % self._steps_per_sync == 0: + self._sync() + + def on_train_end(self): + self._save_model() + self._done() + + def _join(self): + raise NotImplementedError("_join") + + def _quit(self): + raise NotImplementedError("_quit") + + def _pull(self, version, is_last_pull=False): + raise NotImplementedError("_pull") + + def _push(self, step, weights, version, is_train_end): + raise NotImplementedError("_push") + + def _initialize(self): + logging.debug("master initialize") + self._join() + + weight_mapping, version, timestamp = self._pull(self._version) + self._set_weights(weight_mapping) + self._version = version + self._timestamp = timestamp + + def _sync(self): + logging.debug("master sync") + weight_mapping = self._get_weights() + self._version = self._push(self._step, weight_mapping, self._version, + False) + weight_mapping, version, timestamp = self._pull(self._version) + assert version == self._version + self._set_weights(weight_mapping) + self._timestamp = timestamp + + def _save_model(self): + logging.debug("master save model") + weight_mapping = self._get_weights() + self._version = self._push(self._step, weight_mapping, self._version, + True) + weight_mapping, version, timestamp = self._pull(self._version, True) + self._set_weights(weight_mapping) + self._version = version + self._timestamp = timestamp + + if self._save_filepath: + filepath = os.path.join(self._save_filepath, str(self._timestamp)) + self._model.save(filepath, save_format='tf') + + def _done(self): + logging.debug("master quit") + self._quit() + + def _get_weights(self): + weight_mapping = {} + for w, v in zip(self._model.weights, self._model.get_weights()): + if w.name in self._trainable_weights: + weight_mapping[w.name] = v + return weight_mapping + + def _set_weights(self, weight_mapping): + weights = [] + for w, v in zip(self._model.weights, self._model.get_weights()): + if w.name in self._trainable_weights \ + and w.name in weight_mapping: + weights.append(np.reshape(weight_mapping.get(w.name), v.shape)) + else: + weights.append(v) + self._model.set_weights(weights) + + +class _TrainingServiceServicer(TrainingServiceServicer): + + def __init__(self, impl): + self._impl = impl + + def Join(self, request, context): + return self._impl._grpc_join_handler(request) # pylint: disable=protected-access + + def Quit(self, request, context): + return self._impl._grpc_quit_handler(request) # pylint: disable=protected-access + + def Pull(self, request, context): + return self._impl._grpc_pull_handler(request) # pylint: disable=protected-access + + def Push(self, request, context): + return self._impl._grpc_push_handler(request) # pylint: disable=protected-access + + +class _FollowerSession: + + def __init__(self, name): + self.name = name + self.step = 0 + self.join_time = None + self.quit_time = None + self.is_train_end = False + self.latest_version = 0 + + +class LeaderMaster(_Master): + + def __init__(self, model, fl_name, fl_cluster_spec, steps_per_sync, + save_filepath): + super().__init__(model, steps_per_sync, save_filepath) + + self._model = model + self._fl_name = fl_name + self._fl_cluster_spec = fl_cluster_spec + self._leader = self._fl_cluster_spec.leader + + self._follower_mapping = dict() + for f in self._fl_cluster_spec.followers: + self._follower_mapping[f.name] = _FollowerSession(f.name) + + self._latest_version = 0 + self._latest_weight_mapping = self._get_weights() + self._latest_timestamp = int(time.time()) + self._aggregating_version = self._latest_version + 1 + self._aggregating_weight_mapping = dict() + self._aggregating_weight_count_mapping = dict() + self._is_quitted = False + self._lock = threading.RLock() + self._cv = threading.Condition(self._lock) + + def start(self): + self._start_grpc_server(self._leader.address) + + def wait(self): + self._grpc_server.stop(None) + + def _start_grpc_server(self, address): + self._grpc_server = grpc.server( + ThreadPoolExecutor( + max_workers=8, + thread_name_prefix="LeaderMasterGrpcServerThreadPoolExecutor")) + add_TrainingServiceServicer_to_server(_TrainingServiceServicer(self), + self._grpc_server) + self._grpc_server.add_insecure_port(address) + self._grpc_server.start() + logging.info('leader master server start on address: %s', address) + + def _follower_join_info(self): + joined, unjoin = list(), list() + with self._lock: + for f in self._follower_mapping.values(): + if f.join_time is not None: + joined.append(f.name) + else: + unjoin.append(f.name) + return joined, unjoin + + def _follower_quit_info(self): + quitted, unquit = list(), list() + with self._lock: + for f in self._follower_mapping.values(): + if f.quit_time is not None: + quitted.append(f.name) + else: + unquit.append(f.name) + return quitted, unquit + + def _follower_push_info(self): + pushed, unpush, train_end = list(), list(), list() + with self._lock: + for f in self._follower_mapping.values(): + if f.is_train_end: + train_end.append(f.name) + elif f.latest_version == self._aggregating_version: + pushed.append(f.name) + else: + unpush.append(f.name) + return pushed, unpush, train_end + + def _join(self): + with self._lock: + while True: + joined, unjoin = self._follower_join_info() + if not unjoin: + logging.info("all followers joined, followers: %s", joined) + return + + logging.info( + "wait followers join, joined followers: %s," + " unjoin followers: %s", joined, unjoin) + self._cv.wait(1) + + def _quit(self): + with self._lock: + self._is_quitted = True + while True: + quitted, unquit = self._follower_quit_info() + if not unquit: + logging.info("all followers quitted, followers: %s", + quitted) + return + + logging.info( + "wait followers quit, quitted followers: %s," + " unquit followers: %s", quitted, unquit) + self._cv.wait(1) + + def _pull(self, version, is_last_pull=False): + return self._latest_weight_mapping, self._latest_version, \ + self._latest_timestamp + + def _push(self, step, weight_mapping, version, is_train_end): + self._sum_weights(weight_mapping) + while True: + with self._lock: + while True: + pushed, unpush, train_end = self._follower_push_info() + if not unpush: + logging.info( + "all followers pushed, version: %d," + " pushed: %s, train_end: %s", + self._aggregating_version, pushed, train_end) + break + + logging.info( + "wait followers push, pushed followers: %s," + " unpushed followers: %s," + " train_end followers: %s", pushed, unpush, train_end) + self._cv.wait(1) + + self._aggregate_weights() + if not is_train_end: + break + + _, unpush, _ = self._follower_push_info() + if not unpush: + break + + return self._latest_version + + def _sum_weights(self, weight_mapping): + with self._lock: + for name, weight in weight_mapping.items(): + if name in self._aggregating_weight_mapping: + self._aggregating_weight_mapping[name] += weight + self._aggregating_weight_count_mapping[name] += 1 + else: + self._aggregating_weight_mapping[name] = np.copy(weight) + self._aggregating_weight_count_mapping[name] = 1 + + def _aggregate_weights(self): + with self._lock: + for name in self._aggregating_weight_mapping: + self._aggregating_weight_mapping[name] /= \ + self._aggregating_weight_count_mapping[name] + + self._latest_weight_mapping = self._aggregating_weight_mapping + self._latest_version = self._aggregating_version + self._latest_timestamp = int(time.time()) + + self._aggregating_weight_mapping = dict() + self._aggregating_weight_count_mapping = dict() + self._aggregating_version += 1 + logging.info("leader update latest version to %d", + self._latest_version) + + def _grpc_join_handler(self, request): + follower = self._follower_mapping.get(request.name) + if not follower: + return JoinResponse( + Status(code=Status.Code.ERROR, + message="invaild follower: {}".format(request.name))) + + with self._lock: + if not follower.join_time: + follower.join_time = time.time() + logging.info("follower: %s join", follower.name) + self._cv.notify() + elif follower.quit_time: + return JoinResponse(status=Status(code=Status.Code.ERROR), + message="quit already") + else: + logging.warning("follower: %s join duplicated", follower.name) + + return JoinResponse(status=Status(code=Status.Code.OK)) + + def _grpc_quit_handler(self, request): + follower = self._follower_mapping.get(request.name) + if not follower: + return JoinResponse( + Status(code=Status.Code.ERROR, + message="invaild follower: {}".format(request.name))) + with self._lock: + if not follower.join_time: + return QuitResponse( + status=Status(code=Status.Code.ERROR, message="not join")) + + if not follower.quit_time: + follower.quit_time = time.time() + logging.info("follower: %s quit", follower.name) + self._cv.notify() + else: + logging.warning("follower: %s quit duplicated", follower.name) + + return QuitResponse(status=Status(code=Status.Code.OK)) + + def _grpc_pull_handler(self, request): + follower = self._follower_mapping.get(request.name) + if not follower: + return PullResponse( + Status(code=Status.Code.ERROR, + message="invaild follower: {}".format(request.name))) + + with self._lock: + if not follower.join_time: + return QuitResponse( + status=Status(code=Status.Code.ERROR, message="not join")) + if follower.quit_time: + return JoinResponse(status=Status(code=Status.Code.ERROR), + message="quit already") + + if request.is_last_pull: + if not self._is_quitted: + return PullResponse(status=Status( + code=Status.Code.NOT_READY)) + elif request.version != self._latest_version: + return PullResponse(status=Status(code=Status.Code.NOT_READY)) + + return PullResponse(status=Status(code=Status.Code.OK), + weights=_weight_mapping_to_proto_weights( + self._latest_weight_mapping), + version=self._latest_version, + timestamp=self._latest_timestamp) + + def _grpc_push_handler(self, request): + follower = self._follower_mapping.get(request.name) + if not follower: + return PushResponse( + Status(code=Status.Code.ERROR, + message="invaild follower: {}".format(request.name))) + + with self._lock: + if not follower.join_time: + return PushResponse( + status=Status(code=Status.Code.ERROR, message="not join")) + if follower.quit_time: + return PushResponse(status=Status(code=Status.Code.ERROR, + message="quit already")) + + if request.version != follower.latest_version: + return PushResponse(status=Status(code=Status.Code.ERROR, + message="invaild version")) + + weight_mapping = dict() + for w in request.weights: + weight_mapping[w.name] = _load_ndarray_from_bytes(w.ndarray) + + self._sum_weights(weight_mapping) + follower.latest_version = self._aggregating_version + follower.is_train_end = request.is_train_end + logging.info("follower: %s push version: %s", follower.name, + follower.latest_version) + self._cv.notify_all() + + return PushResponse(status=Status(code=Status.Code.OK), + version=self._aggregating_version) + + +class FollowerMaster(_Master): + + def __init__(self, model, fl_name, fl_cluster_spec, steps_per_sync, + save_filepath): + super().__init__(model, steps_per_sync, save_filepath) + + self._model = model + self._fl_name = fl_name + self._fl_cluster_spec = fl_cluster_spec + self._leader = self._fl_cluster_spec.leader + + def start(self): + self._grpc_channel = make_insecure_channel( + self._leader.address, ChannelType.REMOTE) + self._grpc_client = TrainingServiceStub(self._grpc_channel) + + def wait(self): + self._grpc_channel.close() + + def _join(self): + req = JoinRequest(name=self._fl_name) + resp = grpc_utils.call_with_retry(lambda: self._grpc_client.Join(req)) + if resp.status.code != Status.Code.OK: + raise RuntimeError( + "join fed cluster error, code: {}, message: {}".format( + resp.status.code, resp.status.message)) + logging.info("join fed cluster success, fl_name: %s", self._fl_name) + + def _quit(self): + req = QuitRequest(name=self._fl_name) + resp = grpc_utils.call_with_retry(lambda: self._grpc_client.Quit(req)) + if resp.status.code != Status.Code.OK: + raise RuntimeError( + "quit fed cluster error, code: {}, message: {}".format( + resp.status.code, resp.status.message)) + logging.info("quit fed cluster success, fl_name: %s", self._fl_name) + + def _pull(self, version, is_last_pull=False): + req = PullRequest(name=self._fl_name, + version=version, + is_last_pull=is_last_pull) + while True: + resp = grpc_utils.call_with_retry( + lambda: self._grpc_client.Pull(req)) + if resp.status.code == Status.Code.OK: + break + if resp.status.code == Status.Code.NOT_READY: + logging.info("leader not ready for pull") + time.sleep(0.2) + else: + raise RuntimeError( + "pull weights error, code: {}, message: {}".format( + resp.status.code, resp.status.message)) + + logging.info("pull weights success") + return _proto_weights_to_weight_mapping(resp.weights), \ + resp.version, resp.timestamp + + def _push(self, step, weight_mapping, version, is_train_end): + req = PushRequest( + name=self._fl_name, + step=step, + weights=_weight_mapping_to_proto_weights(weight_mapping), + version=version, + is_train_end=is_train_end) + resp = grpc_utils.call_with_retry(lambda: self._grpc_client.Push(req)) + if resp.status.code != Status.Code.OK: + raise RuntimeError( + "push weights error, code: {}, message: {}".format( + resp.status.code, resp.status.message)) + + logging.info("push weights success") + return resp.version + + +def _save_ndarray_to_bytes(ndarray): + b = BytesIO() + np.save(b, ndarray, allow_pickle=False) + return b.getvalue() + + +def _load_ndarray_from_bytes(b): + return np.load(BytesIO(b), allow_pickle=False) + + +def _proto_weights_to_weight_mapping(weights): + weight_mapping = dict() + for w in weights: + weight_mapping[w.name] = _load_ndarray_from_bytes(w.ndarray) + return weight_mapping + + +def _weight_mapping_to_proto_weights(weight_mapping): + weights = list() + for name, ndarray in weight_mapping.items(): + weights.append( + Weight(name=name, ndarray=_save_ndarray_to_bytes(ndarray))) + return weights diff --git a/fedlearner/fedavg/training_service.proto b/fedlearner/fedavg/training_service.proto new file mode 100644 index 000000000..0d813ed94 --- /dev/null +++ b/fedlearner/fedavg/training_service.proto @@ -0,0 +1,68 @@ +syntax = "proto3"; + +package fedlearner.fedavg; + +service TrainingService { + rpc Join(JoinRequest) returns (JoinResponse); + rpc Quit(QuitRequest) returns (QuitResponse); + + rpc Pull(PullRequest) returns (PullResponse); + rpc Push(PushRequest) returns (PushResponse); +} + +message Status { + enum Code { + OK = 0; + ERROR = 1; + NOT_READY = 2; + } + Code code = 1; + string message = 2; +} + +message JoinRequest { + string name = 1; +} + +message JoinResponse { + Status status = 1; +} + +message QuitRequest { + string name = 1; +} + +message QuitResponse { + Status status = 1; +} + +message PullRequest { + string name = 1; + int64 version = 2; + bool is_last_pull = 3; +} + +message PullResponse { + Status status = 1; + repeated Weight weights = 2; + int64 version = 3; + int64 timestamp = 4; +} + +message PushRequest { + string name = 1; + int64 step = 2; + repeated Weight weights = 3; + int64 version = 4; + bool is_train_end = 5; +} + +message PushResponse { + Status status = 1; + int64 version = 2; +} + +message Weight { + string name = 1; + bytes ndarray = 2; +} \ No newline at end of file diff --git a/fedlearner/model/crypto/secret_sharing.py b/fedlearner/model/crypto/secret_sharing.py new file mode 100644 index 000000000..90a00f2f8 --- /dev/null +++ b/fedlearner/model/crypto/secret_sharing.py @@ -0,0 +1,52 @@ +from typing import Tuple, Optional +import numpy as np +import pandas as pd +from fedlearner.trainer.bridge import Bridge + + +class MultiTriplets: + + def __init__(self, path: str): + self._reader = pd.read_csv(path, header=None, + index_col=False, iterator=True) + + def get_multi_triplets(self, num: int) -> Tuple[np.ndarray, np.ndarray, + np.ndarray]: + df = self._reader.get_chunk(num) + x = df[0].to_numpy() + y = df[1].to_numpy() + z = df[2].to_numpy() + return x, y, z + + +class SecretSharing: + + def __init__(self, data: np.ndarray, role: str, bridge: Bridge, + multi_triplets: Optional[MultiTriplets] = None): + self.data = data + self._num = data.size + self._multi_triplets = multi_triplets + self._role = role + self._bridge = bridge + + def __mul__(self, other): + x, y, z = self._multi_triplets.get_multi_triplets(self._num) + a = self.data + b = other.data + e = a - x + f = b - y + E = SecretSharing(e, self._role, self._bridge).reveal() + F = SecretSharing(f, self._role, self._bridge).reveal() + + if self._role == 'leader': + c = F * x + E * y + z + else: + c = F * x + E * y + z + E * F + return c + + def reveal(self) -> np.ndarray: + self._bridge.start() + self._bridge.send('reveal_data', self.data) + peer_data = self._bridge.receive('reveal_data') + self._bridge.commit() + return self.data + peer_data diff --git a/fedlearner/model/tree/loss.py b/fedlearner/model/tree/loss.py index a4e1c4e81..c0f66acfd 100644 --- a/fedlearner/model/tree/loss.py +++ b/fedlearner/model/tree/loss.py @@ -16,6 +16,7 @@ import numpy as np from scipy import special as sp_special +import pandas as pd def _roc_auc_score(label, pred): @@ -55,11 +56,40 @@ def gradient(self, x, pred, label): def hessian(self, x, pred, label): return np.maximum(pred * (1.0 - pred), 1e-16) + @staticmethod + def confusion_matrix(pred, label): + tp = (label * pred).sum() + tn = ((1 - label) * (1 - pred)).sum() + fp = ((1 - label) * pred).sum() + fn = (label * (1 - pred)).sum() + return {'tp': tp, 'tn': tn, 'fp': fp, 'fn': fn} + + def top_metrics(self, pred, label): + dt = pd.DataFrame({'preds': pred, 'labels': label}) + dt = dt.sort_values('preds', ascending=False) + + _total_tp = sum(dt['labels']) + _total = len(dt) + + per_metrics = {} + + for i in range(10, 30, 10): + idx = (i * _total // 100) + tp = sum(dt.iloc[:idx]['labels']) + recall = tp / _total_tp + precise = tp / idx + diff = tp / (idx * _total_tp / _total) + per_metrics['{}_per_recall'.format(i)] = recall + per_metrics['{}_per_precise'.format(i)] = precise + per_metrics['{}_per_diff'.format(i)] = (diff - 1) * 100 + + return per_metrics + def metrics(self, pred, label): y_pred = (pred > 0.5).astype(label.dtype) precision, recall, f1 = _precision_recall_f1(label, y_pred) ks, auc = _roc_auc_score(label, pred) - return { + metrics = { 'acc': np.isclose(y_pred, label).sum() / len(label), 'precision': precision, 'recall': recall, @@ -67,6 +97,13 @@ def metrics(self, pred, label): 'auc': auc, 'ks': ks, } + conf_mat = self.confusion_matrix(y_pred, label) + metrics.update(conf_mat) + + per_metrics = self.top_metrics(pred, label) + metrics.update(per_metrics) + + return metrics class MSELoss(object): diff --git a/fedlearner/model/tree/trainer.py b/fedlearner/model/tree/trainer.py index fd2246c99..214a6b287 100644 --- a/fedlearner/model/tree/trainer.py +++ b/fedlearner/model/tree/trainer.py @@ -16,20 +16,25 @@ import os import csv +import time import queue import logging import argparse import traceback import itertools +from typing import Optional +from concurrent.futures import ProcessPoolExecutor +import multiprocessing import numpy as np import tensorflow.compat.v1 as tf +from fedlearner.common.argparse_util import str_as_bool from fedlearner.trainer.bridge import Bridge from fedlearner.model.tree.tree import BoostingTreeEnsamble from fedlearner.model.tree.trainer_master_client import LocalTrainerMasterClient from fedlearner.model.tree.trainer_master_client import DataBlockInfo - +from fedlearner.model.tree.utils import filter_files def create_argument_parser(): parser = argparse.ArgumentParser( @@ -57,10 +62,15 @@ def create_argument_parser(): parser.add_argument('--validation-data-path', type=str, default=None, help='Path to validation data file. ' \ 'Only used in train mode.') - parser.add_argument('--no-data', type=bool, default=False, + parser.add_argument('--no-data', type=str_as_bool, + default=False, const=True, nargs='?', help='Run prediction without data.') - parser.add_argument('--file-ext', type=str, default='.csv', - help='File extension to use') + parser.add_argument('--file-ext', type=str, default='', + help='File extension to use including .' \ + 'for example: .csv') + # TODO(gezhengqiang): delete file_ext + parser.add_argument('--file-wildcard', type=str, default='', + help='the wildcard filter for the file') parser.add_argument('--file-type', type=str, default='csv', help='input file type: csv or tfrecord') parser.add_argument('--load-model-path', @@ -112,8 +122,8 @@ def create_argument_parser(): default=1, help='Number of parallel threads.') parser.add_argument('--verify-example-ids', - type=bool, - default=False, + type=str_as_bool, + default=False, const=True, nargs='?', help='If set to true, the first column of the ' 'data will be treated as example ids that ' 'must match between leader and follower') @@ -127,21 +137,25 @@ def create_argument_parser(): help='Field names of categorical features. Feature' ' values should be non-negtive integers') parser.add_argument('--use-streaming', - type=bool, - default=False, + type=str_as_bool, + default=False, const=True, nargs='?', help='Whether to use streaming transmit.') parser.add_argument('--send-scores-to-follower', - type=bool, - default=False, + type=str_as_bool, + default=False, const=True, nargs='?', help='Whether to send prediction scores to follower.') parser.add_argument('--send-metrics-to-follower', - type=bool, - default=False, + type=str_as_bool, + default=False, const=True, nargs='?', help='Whether to send metrics to follower.') parser.add_argument('--enable-packing', - type=bool, - default=False, + type=str_as_bool, + default=False, const=True, nargs='?', help='Whether to enable packing grad and hess') + parser.add_argument('--label-field', + type=str, + default='label', + help='selected label name') return parser @@ -154,16 +168,16 @@ def parse_tfrecord(record): for key, value in example.features.feature.items(): kind = value.WhichOneof('kind') if kind == 'float_list': - assert len(value.float_list.value) == 1, "Invalid tfrecord format" + assert len(value.float_list.value) == 1, 'Invalid tfrecord format' parsed[key] = value.float_list.value[0] elif kind == 'int64_list': - assert len(value.int64_list.value) == 1, "Invalid tfrecord format" + assert len(value.int64_list.value) == 1, 'Invalid tfrecord format' parsed[key] = value.int64_list.value[0] elif kind == 'bytes_list': - assert len(value.bytes_list.value) == 1, "Invalid tfrecord format" + assert len(value.bytes_list.value) == 1, 'Invalid tfrecord format' parsed[key] = value.bytes_list.value[0] else: - raise ValueError("Invalid tfrecord format") + raise ValueError('Invalid tfrecord format') return parsed @@ -173,12 +187,12 @@ def extract_field(field_names, field_name, required): return [] assert not required, \ - "Field %s is required but missing in data"%field_name + 'Field %s is required but missing in data'%field_name return None -def read_data(file_type, filename, require_example_ids, - require_labels, ignore_fields, cat_fields): +def read_data(file_type, filename, require_example_ids, require_labels, + ignore_fields, cat_fields, label_field): logging.debug('Reading data file from %s', filename) if file_type == 'tfrecord': @@ -196,13 +210,13 @@ def read_data(file_type, filename, require_example_ids, raw_ids = extract_field( field_names, 'raw_id', False) labels = extract_field( - field_names, 'label', require_labels) + field_names, label_field, require_labels) ignore_fields = set(filter(bool, ignore_fields.strip().split(','))) - ignore_fields.update(['example_id', 'raw_id', 'label']) + ignore_fields.update(['example_id', 'raw_id', label_field]) cat_fields = set(filter(bool, cat_fields.strip().split(','))) for name in cat_fields: - assert name in field_names, "cat_field %s missing"%name + assert name in field_names, 'cat_field %s missing'%name cont_columns = list(filter( lambda x: x not in ignore_fields and x not in cat_fields, field_names)) @@ -213,6 +227,9 @@ def read_data(file_type, filename, require_example_ids, features = [] cat_features = [] + + def to_float(x): + return float(x if x not in ['', None] else 'nan') for line in reader: if file_type == 'tfrecord': line = parse_tfrecord(line) @@ -221,8 +238,8 @@ def read_data(file_type, filename, require_example_ids, if raw_ids is not None: raw_ids.append(str(line['raw_id'])) if labels is not None: - labels.append(float(line['label'])) - features.append([float(line[i]) for i in cont_columns]) + labels.append(float(line[label_field])) + features.append([to_float(line.get(i)) for i in cont_columns]) cat_features.append([int(line[i]) for i in cat_columns]) features = np.array(features, dtype=np.float) @@ -234,56 +251,80 @@ def read_data(file_type, filename, require_example_ids, labels, example_ids, raw_ids -def read_data_dir(file_ext, file_type, path, require_example_ids, - require_labels, ignore_fields, cat_fields): +def read_data_dir(file_ext: str, file_wildcard: str, file_type: str, path: str, + require_example_ids: bool, require_labels: bool, + ignore_fields: str, cat_fields: str, label_field: str, + num_parallel: Optional[int]): + if not tf.io.gfile.isdir(path): return read_data( file_type, path, require_example_ids, - require_labels, ignore_fields, cat_fields) - - files = [] - for dirname, _, filenames in tf.io.gfile.walk(path): - for filename in filenames: - _, ext = os.path.splitext(filename) - if file_ext and ext != file_ext: - continue - subdirname = os.path.join(path, os.path.relpath(dirname, path)) - files.append(os.path.join(subdirname, filename)) + require_labels, ignore_fields, cat_fields, label_field) + files = filter_files(path, file_ext, file_wildcard) files.sort() + assert len(files) > 0, f'No file exsists in directory(path={path} ' \ + f'extension={file_ext} wildcard={file_wildcard})' + + if num_parallel: + assert num_parallel >= 1, 'Invalid num_parallel' + else: + num_parallel = 1 + + if num_parallel > len(files): + logging.info('Number of files(%s) is less than num_parallel(%s), ' + 'switch num_parallel to %s', + len(files), num_parallel, len(files)) + num_parallel = len(files) + features = None - for fullname in files: - ifeatures, icat_features, icont_columns, icat_columns, \ - ilabels, iexample_ids, iraw_ids = read_data( - file_type, fullname, require_example_ids, - require_labels, ignore_fields, cat_fields - ) - if features is None: - features = ifeatures - cat_features = icat_features - cont_columns = icont_columns - cat_columns = icat_columns - labels = ilabels - example_ids = iexample_ids - raw_ids = iraw_ids - else: - assert cont_columns == icont_columns, \ - "columns mismatch between files %s vs %s"%( - cont_columns, icont_columns) - assert cat_columns == icat_columns, \ - "columns mismatch between files %s vs %s"%( - cat_columns, icat_columns) - features = np.concatenate((features, ifeatures), axis=0) - cat_features = np.concatenate( - (cat_features, icat_features), axis=0) - if labels is not None: - labels = np.concatenate((labels, ilabels), axis=0) - if example_ids is not None: - example_ids.extend(iexample_ids) - if raw_ids is not None: - raw_ids.extend(iraw_ids) - - assert features is not None, "No data found in %s"%path + + start_time = time.time() + logging.info('taskes start time: %s', str(start_time)) + logging.info('Data loader count = %s', str(num_parallel)) + + with ProcessPoolExecutor(max_workers=num_parallel) as pool: + futures = [] + for fullname in files: + future = pool.submit( + read_data, file_type, fullname, + require_example_ids, require_labels, + ignore_fields, cat_fields, label_field) + futures.append(future) + for future in futures: + ifeatures, icat_features, icont_columns, icat_columns, \ + ilabels, iexample_ids, iraw_ids = future.result() + if features is None: + features = ifeatures + cat_features = icat_features + cont_columns = icont_columns + cat_columns = icat_columns + labels = ilabels + example_ids = iexample_ids + raw_ids = iraw_ids + else: + assert cont_columns == icont_columns, \ + 'columns mismatch between files %s vs %s'%( + cont_columns, icont_columns) + assert cat_columns == icat_columns, \ + 'columns mismatch between files %s vs %s'%( + cat_columns, icat_columns) + features = np.concatenate((features, ifeatures), axis=0) + cat_features = np.concatenate( + (cat_features, icat_features), axis=0) + if labels is not None: + labels = np.concatenate((labels, ilabels), axis=0) + if example_ids is not None: + example_ids.extend(iexample_ids) + if raw_ids is not None: + raw_ids.extend(iraw_ids) + + end_time = time.time() + elapsed_time = end_time - start_time + logging.info('taskes end time: %s', str(end_time)) + logging.info('elapsed time for reading data: %ss', str(elapsed_time)) + + assert features is not None, 'No data found in %s'%path return features, cat_features, cont_columns, cat_columns, \ labels, example_ids, raw_ids @@ -291,22 +332,24 @@ def read_data_dir(file_ext, file_type, path, require_example_ids, def train(args, booster): X, cat_X, X_names, cat_X_names, y, example_ids, _ = read_data_dir( - args.file_ext, args.file_type, args.data_path, args.verify_example_ids, - args.role != 'follower', args.ignore_fields, args.cat_fields) + args.file_ext, args.file_wildcard, args.file_type, args.data_path, + args.verify_example_ids, args.role != 'follower', args.ignore_fields, + args.cat_fields, args.label_field, args.num_parallel) if args.validation_data_path: val_X, val_cat_X, val_X_names, val_cat_X_names, val_y, \ val_example_ids, _ = \ read_data_dir( - args.file_ext, args.file_type, args.validation_data_path, - args.verify_example_ids, args.role != 'follower', - args.ignore_fields, args.cat_fields) + args.file_ext, args.file_wildcard, args.file_type, + args.validation_data_path, args.verify_example_ids, + args.role != 'follower', args.ignore_fields, + args.cat_fields, args.label_field, args.num_parallel) assert X_names == val_X_names, \ - "Train data and validation data must have same features" + 'Train data and validation data must have same features' assert cat_X_names == val_cat_X_names, \ - "Train data and validation data must have same features" + 'Train data and validation data must have same features' else: - val_X = val_cat_X = X_names = val_y = val_example_ids = None + val_X = val_cat_X = val_y = val_example_ids = None if args.output_path: tf.io.gfile.makedirs(os.path.dirname(args.output_path)) @@ -328,7 +371,7 @@ def train(args, booster): def write_predictions(filename, pred, example_ids=None, raw_ids=None): - logging.debug("Writing predictions to %s.tmp", filename) + logging.debug('Writing predictions to %s.tmp', filename) headers = [] lines = [] if example_ids is not None: @@ -347,7 +390,7 @@ def write_predictions(filename, pred, example_ids=None, raw_ids=None): fout.write(','.join([str(i) for i in line]) + '\n') fout.close() - logging.debug("Renaming %s.tmp to %s", filename, filename) + logging.debug('Renaming %s.tmp to %s', filename, filename) tf.io.gfile.rename(filename+'.tmp', filename, overwrite=True) def test_one_file(args, bridge, booster, data_file, output_file): @@ -357,7 +400,7 @@ def test_one_file(args, bridge, booster, data_file, output_file): X, cat_X, X_names, cat_X_names, y, example_ids, raw_ids = \ read_data( args.file_type, data_file, args.verify_example_ids, - False, args.ignore_fields, args.cat_fields) + False, args.ignore_fields, args.cat_fields, args.label_field) pred = booster.batch_predict( X, @@ -368,9 +411,10 @@ def test_one_file(args, bridge, booster, data_file, output_file): if y is not None: metrics = booster.loss.metrics(pred, y) + booster.iter_metrics_handler(metrics, 'eval') else: metrics = {} - logging.info("Test metrics: %s", metrics) + logging.info('Test metrics: %s', metrics) if args.role == 'follower': bridge.start() @@ -388,8 +432,10 @@ def test_one_file(args, bridge, booster, data_file, output_file): class DataBlockLoader(object): - def __init__(self, role, bridge, data_path, ext, - worker_rank=0, num_workers=1, output_path=None): + def __init__(self, role: str, bridge: Optional[Bridge], data_path: str, + ext: Optional[str], file_wildcard: Optional[str], + worker_rank: int = 0, num_workers: int = 1, + output_path: Optional[str] = None): self._role = role self._bridge = bridge self._num_workers = num_workers @@ -404,8 +450,10 @@ def __init__(self, role, bridge, data_path, ext, files = [os.path.basename(data_path)] data_path = os.path.dirname(data_path) self._trainer_master = LocalTrainerMasterClient( - self._tm_role, data_path, files=files, ext=ext, - skip_datablock_checkpoint=True) + role=self._tm_role, path=data_path, files=files, + ext=ext, file_wildcard=file_wildcard, + skip_datablock_checkpoint=True, + from_data_source=False) else: self._trainer_master = None @@ -471,13 +519,15 @@ def get_next_block(self): def test(args, bridge, booster): if not args.no_data: - assert args.data_path, "Data path must not be empty" + assert args.data_path, 'Data path must not be empty' else: assert not args.data_path and args.role == 'leader' data_loader = DataBlockLoader( - args.role, bridge, args.data_path, args.file_ext, - args.worker_rank, args.num_workers, args.output_path) + role=args.role, bridge=bridge, data_path=args.data_path, + ext=args.file_ext, file_wildcard=args.file_wildcard, + worker_rank=args.worker_rank, num_workers=args.num_workers, + output_path=args.output_path) while True: data_block = data_loader.get_next_block() @@ -501,9 +551,9 @@ def run(args): logging.basicConfig(level=logging.DEBUG) assert args.role in ['leader', 'follower', 'local'], \ - "role must be leader, follower, or local" + 'role must be leader, follower, or local' assert args.mode in ['train', 'test', 'eval'], \ - "mode must be train, test, or eval" + 'mode must be train, test, or eval' if args.role != 'local': bridge = Bridge(args.role, int(args.local_addr.split(':')[1]), @@ -546,4 +596,10 @@ def run(args): if __name__ == '__main__': + # Experiments show `spawn` method is essential for ProcessPoolExecutor + # to get stable performance in multiprocessing HDFS data read. + # Otherwise, forked processes may lead to deadlock problems. + # Similar cases reported: https://github.com/crs4/pydoop/issues/311 + # Reason discussed: https://github.com/dask/hdfs3/issues/100 + multiprocessing.set_start_method('spawn') run(create_argument_parser().parse_args()) diff --git a/fedlearner/model/tree/trainer_master_client.py b/fedlearner/model/tree/trainer_master_client.py index 85f741c85..12f091543 100644 --- a/fedlearner/model/tree/trainer_master_client.py +++ b/fedlearner/model/tree/trainer_master_client.py @@ -19,11 +19,9 @@ import logging import collections import traceback -try: - import tensorflow.compat.v1 as tf -except ImportError: - import tensorflow.compat.v1 as tf +from typing import List, Optional +from fedlearner.model.tree.utils import filter_files from fedlearner.common import trainer_master_service_pb2 as tm_pb from fedlearner.common import trainer_master_service_pb2_grpc as tm_grpc from fedlearner.proxy.channel import make_insecure_channel, ChannelType @@ -38,15 +36,16 @@ class LocalTrainerMasterClient(object): """Non-thread safe""" def __init__(self, - role, - path, - files=None, - ext='.tfrecord', - start_time=None, - end_time=None, - from_data_source=False, - skip_datablock_checkpoint=False, - epoch_num=1): + role: str, + path: str, + files: Optional[List[str]] = None, + ext: Optional[str] = '.tfrecord', + file_wildcard: Optional[str] = None, + start_time: Optional[int] = None, + end_time: Optional[int] = None, + from_data_source: bool = False, + skip_datablock_checkpoint: bool = False, + epoch_num: int = 1): self._role = role self._path = path self._block_queue = [] @@ -62,22 +61,14 @@ def __init__(self, self._block_map[block_id] = block_item else: if files is None: - files = [] - for dirname, _, filenames in tf.io.gfile.walk(path): - for filename in filenames: - _, fileext = os.path.splitext(filename) - if ext and fileext != ext: - continue - subdirname = os.path.relpath(dirname, path) - files.append(os.path.join(subdirname, filename)) + files = filter_files(path=path, file_ext=ext, file_wildcard=file_wildcard) files.sort() # Hack way for supporting multiple epochs blocks = [] for filename in files: - block_id, _ = os.path.splitext(os.path.basename(filename)) - fullname = os.path.join(path, filename) - block = DataBlockInfo(block_id, fullname) + block_id = os.path.relpath(filename, path) + block = DataBlockInfo(block_id, filename) blocks.append(block) self._block_map = {block.block_id: block for block in blocks} for rnd in range(epoch_num): diff --git a/fedlearner/model/tree/tree.py b/fedlearner/model/tree/tree.py index f817158e4..c015907c4 100644 --- a/fedlearner/model/tree/tree.py +++ b/fedlearner/model/tree/tree.py @@ -24,6 +24,7 @@ import numpy as np from google.protobuf import text_format import tensorflow.compat.v1 as tf +from fedlearner.common.metric_collector import metric_collector from fedlearner.model.tree.packing import GradHessPacker from fedlearner.model.tree.loss import LogisticLoss, MSELoss from fedlearner.model.crypto import paillier, fixed_point_number @@ -424,6 +425,10 @@ def _compare_split(self, split_info, default_left, gain = left_g*left_g/(left_h + lam) + \ right_g*right_g/(right_h + lam) - \ sum_g*sum_g/(sum_h + lam) + if not gain >= 0: + logging.warning("the value of gain %f is invalid, left_h: %f, " + "right_h: %f, left_g: %f, right_g: %f, lam: %f", + gain, left_g, right_g, left_h, right_h, lam) if gain > split_info.gain: split_info.gain = gain split_info.feature_id = feature_id @@ -443,6 +448,8 @@ def _find_split_and_push(self, node): else: self._find_cont_split(node, fid, split_info) + assert len(split_info.split_point) != 0, \ + 'the length of split point must not be 0' self._split_candidates.put((-split_info.gain, split_info)) return split_info.gain, split_info @@ -1286,8 +1293,15 @@ def _write_training_log(self, filename, header, metrics, pred): def iter_metrics_handler(self, metrics, mode): for name, value in metrics.items(): + # TODO(lixiaoguang.01) old version, to be deleted emit_store(name=name, value=value, tags={'iteration': len(self._trees), 'mode': mode}) + # new version + metrics_name = f'model.{mode}.tree_vertical.{name}' + metrics_label = { + 'iteration': len(self._trees) + } + metric_collector.emit_store(metrics_name, value, metrics_label) def fit(self, features, diff --git a/fedlearner/model/tree/utils.py b/fedlearner/model/tree/utils.py new file mode 100644 index 000000000..1c6e8bb42 --- /dev/null +++ b/fedlearner/model/tree/utils.py @@ -0,0 +1,21 @@ +import os +from fnmatch import fnmatch +from typing import List, Optional + +import tensorflow.compat.v1 as tf + + +def filter_files(path: str, file_ext: Optional[str], + file_wildcard: Optional[str]) -> List[str]: + files = [] + for dirname, _, filenames in tf.io.gfile.walk(path): + for filename in filenames: + _, ext = os.path.splitext(filename) + subdirname = os.path.join(path, os.path.relpath(dirname, path)) + fpath = os.path.join(subdirname, filename) + if file_ext and ext != file_ext: + continue + if file_wildcard and not fnmatch(fpath, file_wildcard): + continue + files.append(fpath) + return files diff --git a/fedlearner/privacy/__init__.py b/fedlearner/privacy/__init__.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/fedlearner/privacy/__init__.py @@ -0,0 +1 @@ + diff --git a/fedlearner/privacy/splitnn/__init__.py b/fedlearner/privacy/splitnn/__init__.py new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/fedlearner/privacy/splitnn/__init__.py @@ -0,0 +1 @@ + diff --git a/fedlearner/privacy/splitnn/discorloss.py b/fedlearner/privacy/splitnn/discorloss.py new file mode 100644 index 000000000..a47fa4205 --- /dev/null +++ b/fedlearner/privacy/splitnn/discorloss.py @@ -0,0 +1,61 @@ +import tensorflow as tf +import logging +import time + +# DisCorLoss论文详见:https://arxiv.org/abs/2203.01451 + +class DisCorLoss(tf.keras.losses.Loss): + def __init__(self, **kwargs): + super(DisCorLoss, self).__init__(**kwargs) + + def _pairwise_dist(self, A, B): + # squared norms of each row in A and B + na = tf.reduce_sum(tf.square(A), 1) + nb = tf.reduce_sum(tf.square(B), 1) + + # na as a row and nb as a column vectors + na = tf.reshape(na, [-1, 1]) + nb = tf.reshape(nb, [1, -1]) + + # return pairwise euclidead difference matrix + D = tf.sqrt(tf.maximum(na - 2 * tf.matmul(A, B, False, True) + nb + 1e-20, + 0.0)) + return D + + def tf_distance_cor(self, embeddings, labels, debug=False): + start = time.time() + + embeddings = tf.debugging.check_numerics(embeddings, "embeddings contains nan/inf") + labels = tf.debugging.check_numerics(labels, "labels contains nan/inf") + labels = tf.expand_dims(labels, 1) + + n = tf.cast(tf.shape(embeddings)[0], tf.float32) + a = self._pairwise_dist(embeddings, embeddings) + b = self._pairwise_dist(labels, labels) + + # X = x - x的行均值 - x的列均值 + x的总均值 + A = a - tf.reduce_mean(a, + axis=1) - tf.expand_dims(tf.reduce_mean(a, + axis=0), + axis=1) + tf.reduce_mean(a) + B = b - tf.reduce_mean(b, + axis=1) - tf.expand_dims(tf.reduce_mean(b, + axis=0), + axis=1) + tf.reduce_mean(b) + # 计算协方差 + dCovXY = tf.sqrt(tf.abs(tf.reduce_sum(A * B) / (n ** 2))) + # 计算方差 + dVarXX = tf.sqrt(tf.abs(tf.reduce_sum(A * A) / (n ** 2))) + dVarYY = tf.sqrt(tf.abs(tf.reduce_sum(B * B) / (n ** 2))) + # 计算相关性 + dCorXY = dCovXY / tf.sqrt(dVarXX * dVarYY) + end = time.time() + if debug: + print(("tf distance cov: {} and cor: {}, dVarXX: {}, " + "dVarYY:{} uses: {}").format( + dCovXY, dCorXY, + dVarXX, dVarYY, + end - start)) + return dCorXY + + diff --git a/fedlearner/privacy/splitnn/emb_attack.py b/fedlearner/privacy/splitnn/emb_attack.py new file mode 100644 index 000000000..de5b7b669 --- /dev/null +++ b/fedlearner/privacy/splitnn/emb_attack.py @@ -0,0 +1,23 @@ +import tensorflow.compat.v1 as tf + +# Emb Attack见论文:https://arxiv.org/pdf/2203.01451.pdf + +def get_emb_pred(emb): + mean_emb = tf.reduce_mean(emb, axis=0) + # 规范化处理emb + mean_reduced_emb = emb - mean_emb + # 对规范化矩阵做奇异值分解 + s, u, v = tf.linalg.svd(mean_reduced_emb) + # 最大奇异值对应的右奇异向量与矩阵做内积 + top_singular_vector = tf.transpose(v)[0] + pred = tf.linalg.matvec(mean_reduced_emb, top_singular_vector) + # 内积之后的结果可以分为两个簇 + pred = tf.math.sigmoid(pred) + return pred + +def emb_attack_auc(emb, y): + emb_pred = get_emb_pred(emb) + emb_pred = tf.reshape(emb_pred, y.shape) + # 计算emb attack auc + _, emb_auc = tf.metrics.auc(y, emb_pred) + return emb_auc diff --git a/fedlearner/privacy/splitnn/marvell.py b/fedlearner/privacy/splitnn/marvell.py new file mode 100644 index 000000000..e40c53ac1 --- /dev/null +++ b/fedlearner/privacy/splitnn/marvell.py @@ -0,0 +1,660 @@ +import math +import random +import numpy as np +import tensorflow.compat.v1 as tf +import logging +import time +import sys + +#论文见:https://arxiv.org/pdf/2102.08504.pdf + +sys.setrecursionlimit(100000) + +# OBJECTIVE_EPSILON为优化过程的结束条件 +OBJECTIVE_EPSILON = np.float32(1e-16) + +# CONVEX_EPSILON为二值优化问题的结束条件 +CONVEX_EPSILON = np.float32(1e-20) + +# NUM_CANDIDATE为优化过程候选数量 +NUM_CANDIDATE = 1 + +# ZERO_REPLACE用来应对除零错误 +# 为了应对除零问题,将所有除数替换成了div_{x} +ZERO_REPLACE = 1e-3 + +@tf.function +def KL_gradient_perturb(g, batch_y, sumKL_threshold=0.25): + # 算法流程: + # 1.根据gradient对label=0和label=1的gradient的分布进行统计:得到均值和方差 + # 2.调用compute_lambdas解决 四变量优化 问题:得到四个变量lambda + # 3.根据噪声添加公式计算噪声:得到noise + # 4.添加噪声并返回 + + # Step 1: 分布统计 + uv_choice = "uv" + init_scale = 1.0 + + p_frac = 'pos_frac' + dynamic = True + error_prob_lower_bound = None + + if dynamic and (error_prob_lower_bound is not None): + sumKL_threshold = (2 - 4 * error_prob_lower_bound) ** 2 + # elif dynamic: + # print('using sumKL_threshold', sumKL_threshold) + + y = tf.reshape(tf.cast(batch_y, dtype=tf.float32), [-1, 1]) + # 正例的gradient + pos_g = tf.boolean_mask(g, tf.tile(tf.cast(y, dtype=tf.int32), [1, tf.shape(g)[1]])) + pos_g = tf.reshape(pos_g, [-1, tf.shape(g)[1]]) + + # 正例gradient的均值和方差 + pos_g_mean = tf.math.reduce_mean(pos_g, axis=0, keepdims=True) # shape [1, d] + pos_coordinate_var = tf.reduce_mean(tf.math.square(pos_g - pos_g_mean), axis=0) # use broadcast + + # 负例的gradient + neg_g = tf.boolean_mask(g, tf.tile(1 - tf.cast(y, dtype=tf.int32), [1, tf.shape(g)[1]])) + neg_g = tf.reshape(neg_g, [-1, tf.shape(g)[1]]) + + # 负例gradient的均值和方差 + neg_g_mean = tf.math.reduce_mean(neg_g, axis=0, keepdims=True) # shape [1, d] + neg_coordinate_var = tf.reduce_mean(tf.math.square(neg_g - neg_g_mean), axis=0) + + avg_pos_coordinate_var = tf.reduce_mean(pos_coordinate_var) + avg_neg_coordinate_var = tf.reduce_mean(neg_coordinate_var) + + if tf.math.is_nan(avg_pos_coordinate_var) or tf.math.is_nan( + avg_neg_coordinate_var): + return g + + # 对应论文 \delta g + g_diff = pos_g_mean - neg_g_mean + # 对应论文 \delta g的二范数 + g_diff_norm = tf.norm(tensor=g_diff) + + if tf.math.is_nan(g_diff_norm): + return g + + if uv_choice == 'uv': + u = avg_neg_coordinate_var + v = avg_pos_coordinate_var + elif uv_choice == 'same': + u = (avg_neg_coordinate_var + avg_pos_coordinate_var) / 2.0 + v = (avg_neg_coordinate_var + avg_pos_coordinate_var) / 2.0 + elif uv_choice == 'zero': + u, v = 0.0, 0.0 + + # d是gradient的维度 + d = tf.cast(tf.shape(g)[1], dtype=tf.float32) + + # p是标签y中正例的占比 + if p_frac == 'pos_frac': + p = tf.math.reduce_mean(y) + else: + p = float(p_frac) + + scale = init_scale + g_norm_square = g_diff_norm ** 2 + + # debug用 + def print_tensor(pos_g_mean, neg_g_mean, g_diff): + logging.info("gradient pos_g_mean: {}, neg_g_mean: {}".format(np.mean(pos_g_mean), np.mean(neg_g_mean))) + logging.info("gradient pos_g_max: {}, neg_g_max: {}".format(np.amax(pos_g_mean), np.amax(neg_g_mean))) + logging.info("gradient pos_g_min: {}, neg_g_min: {}".format(np.amin(pos_g_mean), np.amin(neg_g_mean))) + logging.info( + "gradient pos_g_norm: {}, neg_g_norm: {}".format(np.linalg.norm(pos_g_mean), np.linalg.norm(neg_g_mean))) + logging.info("gradient g_diff_mean: {}, g_diff_min: {}, g_diff_max: {}, g_diff_norm: {}".format(np.mean(g_diff), + np.amin(g_diff), + np.amax(g_diff), + np.linalg.norm( + g_diff))) + # Step 2: 计算论文中4个lambda + def compute_lambdas(u, v, scale, d, g_norm_square, p, sumKL_threshold, pos_g_mean, neg_g_mean, g_diff): + lam10, lam20, lam11, lam21 = None, None, None, None + start = time.time() + while True: + # P 对应论文中“Additional details of Marvell.”所讲述的power constarint hyperparameter + P = scale * g_norm_square + lam10, lam20, lam11, lam21, sumKL = solve_isotropic_covariance(u=u, + v=v, + d=d, + g_norm_square=g_norm_square, + p=p, + P=P, + lam10_init=lam10, + lam20_init=lam20, + lam11_init=lam11, + lam21_init=lam21) + # logging.info('scale: {}, sumKL: {}, P:{}, type_scale: {}, type_sumKL: {}, type_P:{}'.format(scale, sumKL, P, type(scale), type(sumKL), type(P))) + if not dynamic or sumKL <= sumKL_threshold: + break + scale *= np.float32(1.5) # loosen the power constraint + # logging.info('solve_isotropic_covariance solving time: {}'.format(time.time() - start)) + return lam10, lam20, lam11, lam21, sumKL + + + lam10, lam20, lam11, lam21, sumKL = tf.py_function(compute_lambdas, + [u, v, scale, d, g_norm_square, p, sumKL_threshold, pos_g_mean, + neg_g_mean, g_diff], + [tf.float32, tf.float32, tf.float32, tf.float32, tf.float32]) + lam10, lam20, lam11, lam21, sumKL = tf.reshape(lam10, shape=[1]), tf.reshape(lam20, shape=[1]), \ + tf.reshape(lam11,shape=[1]), tf.reshape(lam21, shape=[1]), \ + tf.reshape(sumKL, shape=[1]) + + perturbed_g = g + y_float = tf.cast(y, dtype=tf.float32) + + div_g = g_diff_norm + if div_g == 0.: + div_g = ZERO_REPLACE + + # Step 3: 计算噪声 + # 四个noise的公式详见论文Theorem 2 + # noise_1和noise_2给 label=1 的gradient添加噪声,对应论文中 \Sigma 1 + # noise_1中采样标准高斯噪声x,保留对应 label=1 的部分,扩大 sqrt( (lambda11 - lmabda21) / ||\Delta g||_2^2 ) * ||\Delta g||_2,对应\Sigma 1的前一个加项 + noise_1 = tf.reshape(tf.multiply(x=tf.random.normal(shape=tf.shape(y)), y=y_float), shape=(-1, 1)) * g_diff * ( + tf.math.sqrt(tf.math.abs(lam11 - lam21)) / div_g) + noise_1 = tf.debugging.check_numerics(noise_1, "noise_1 ERROR", name="noise_1_debugging") + + # noise_2对应\Sigma 1的后一个加项 + noise_2 = tf.random.normal(shape=tf.shape(g)) * tf.reshape(y_float, shape=(-1, 1)) * tf.math.sqrt( + tf.math.maximum(lam21, 0.0)) + noise_2 = tf.debugging.check_numerics(noise_2, "noise_2 ERROR", name="noise_2_debugging") + + # noise_3和noise_4给 label=2 的gradient添加噪声,对应论文中的 \Sigma 0 + # noise_3对应\Sigma 0的前一个加项(与noise_1类似) + noise_3 = tf.reshape(tf.multiply(x=tf.random.normal(shape=tf.shape(y)), y=1 - y_float), shape=(-1, 1)) * g_diff * ( + tf.math.sqrt(tf.math.abs(lam10 - lam20)) / div_g) + noise_3 = tf.debugging.check_numerics(noise_3, "noise_3 ERROR", name="noise_3_debugging") + + # noise_4对应\Sigma 0的后一个加项 + noise_4 = tf.random.normal(shape=tf.shape(g)) * tf.reshape(1 - y_float, shape=(-1, 1)) * tf.math.sqrt( + tf.math.maximum(lam20, 0.0)) + noise_4 = tf.debugging.check_numerics(noise_4, "noise_4 ERROR", name="noise_4_debugging") + + # Step 4 : 添加噪声并返回 + perturbed_g += (noise_1 + noise_2 + noise_3 + noise_4) + perturbed_g = tf.debugging.check_numerics(perturbed_g, "perturbed_g ERROR", name="perturbed_g_debugging") + + return perturbed_g + + +# solver +def symKL_objective(lam10, lam20, lam11, lam21, u, v, d, g_norm_square): + # 计算优化的目标函数 + div1 = lam21 + v + div2 = lam20 + u + div3 = lam11 + v + div4 = lam10 + u + if div1 == 0.: + div1 = ZERO_REPLACE + if div2 == 0.: + div2 = ZERO_REPLACE + if div3 == 0.: + div3 = ZERO_REPLACE + if div4 == 0.: + div4 = ZERO_REPLACE + objective = np.float32((d - np.float32(1)) * (lam20 + u) / (div1) \ + + (d - np.float32(1)) * (lam21 + v) / (div2) \ + + (lam10 + u + g_norm_square) / (div3) \ + + (lam11 + v + g_norm_square) / (div4)) + + # logging.info("symKL_objective, objective: {}, type: {}".format(objective, type(objective))) + return objective + + +def symKL_objective_zero_uv(lam10, lam11, g_norm_square): + # 计算优化的目标函数(u, v均为0) + if lam11 == 0.: + lam11 = ZERO_REPLACE + if lam10 == 0.: + lam10 = ZERO_REPLACE + objective = np.float32((lam10 + g_norm_square) / lam11 \ + + (lam11 + g_norm_square) / lam10) + # logging.info("symKL_objective_zero_uv, objective: {}, type: {}".format(objective, type(objective))) + return objective + + +def solve_isotropic_covariance(u, v, d, g_norm_square, p, P, + lam10_init=None, lam20_init=None, + lam11_init=None, lam21_init=None): + """ return the solution to the optimization problem + Args: + u ([type]): [the coordinate variance of the negative examples] + v ([type]): [the coordinate variance of the positive examples] + d ([type]): [the dimension of activation to protect] + g_norm_square ([type]): [squared 2-norm of g_0 - g_1, i.e. \|g^{(0)} - g^{(1)}\|_2^2] + P ([type]): [the power constraint value] + """ + if u == np.float32(0.0) and v == np.float32(0.0): + return solve_zero_uv(g_norm_square=g_norm_square, p=p, P=P) + + # logging.info("solve_isotropic_covariance, uv!=0") + ordering = [0, 1, 2] + random.shuffle(x=ordering) + + solutions = [] + div1 = np.float32(1.0) - p + if div1 == 0.: + div1 = ZERO_REPLACE + div2 = d + if div2 == 0.: + div2 = ZERO_REPLACE + div3 = p + if div3 == 0.: + div3 = ZERO_REPLACE + + # lambda21=0,对剩下的参数随机赋值(NUM_CANDIDATE决定候选的 lambda解 的数量) + if u <= v: + # logging.info("solve_isotropic_covariance, u<=v") + for i in range(NUM_CANDIDATE): + if i % 3 == ordering[0]: + if lam20_init: # if we pass an initialization + lam20 = lam20_init + else: + lam20 = np.float32(random.random() * P / div1 / div2) + lam10, lam11 = None, None + elif i % 3 == ordering[1]: + if lam11_init: + lam11 = lam11_init + else: + lam11 = np.float32(random.random() * P / div3) + lam10, lam20 = None, None + else: + if lam10_init: + lam10 = lam10_init + else: + lam10 = np.float32(random.random() * P / div1) + lam11, lam20 = None, None + # logging.info("solve_isotropic_covariance, u<=v_iter_{}, lam10: {}, lam20: {}, lam11: {}, type_lam10: {}, type_lam20: {}, type_lam11: {}".format(i, lam10, lam20, lam11, type(lam10), type(lam20), type(lam11))) + solutions.append( + solve_small_neg(u=u, v=v, d=d, g_norm_square=g_norm_square, p=p, P=P, lam10=lam10, lam11=lam11, + lam20=lam20)) + # lambda20=0,对剩下的参数随机赋值(NUM_CANDIDATE决定候选的 lambda解 的数量) + else: + # logging.info("solve_isotropic_covariance, u>v") + for i in range(NUM_CANDIDATE): + if i % 3 == ordering[0]: + if lam21_init: + lam21 = lam21_init + else: + lam21 = np.float32(random.random() * P / div3 / div2) + lam10, lam11 = None, None + elif i % 3 == ordering[1]: + if lam11_init: + lam11 = lam11_init + else: + lam11 = np.float32(random.random() * P / div3) + lam10, lam21 = None, None + else: + if lam10_init: + lam10 = lam10_init + else: + lam10 = np.float32(random.random() * P / div1) + lam11, lam21 = None, None + # logging.info("solve_isotropic_covariance, u>v_iter_{}, lam10: {}, lam21: {}, lam11: {}, type_lam10: {}, type_lam21: {}, type_lam11: {}".format(i, lam10, lam21, lam11, type(lam10), type(lam21), type(lam11))) + solutions.append( + solve_small_pos(u=u, v=v, d=d, g_norm_square=g_norm_square, p=p, P=P, lam10=lam10, lam11=lam11, + lam21=lam21)) + + # logging.info("solve_isotropic_covariance, solutions: {}, len: {}".format(solutions, len(solutions))) + lam10, lam20, lam11, lam21, objective = min(solutions, key=lambda x: x[-1]) + # logging.info("solve_isotropic_covariance, lam10: {}, lam20: {}, lam21: {}, lam11: {}, type_lam10: {}, type_lam21: {}, type_lam11: {}, type_lam20: {}".format(lam10, lam20, lam21, lam11, type(lam10), type(lam21), type(lam11), type(lam20))) + + return (lam10, lam20, lam11, lam21, objective) + + +def solve_zero_uv(g_norm_square, p, P): + # 特殊情况:当u, v=0 + C = P + div1 = C + p * g_norm_square + if div1 == 0.: + div1 = ZERO_REPLACE + E = np.float32(math.sqrt((C + (np.float32(1.0) - p) * g_norm_square) / div1)) + div2 = p + if div2 == 0.: + div2 = ZERO_REPLACE + div3 = E + (np.float32(1.0) - p) / div2 + if div3 == 0.: + div3 = ZERO_REPLACE + tau = np.float32(max((P / div2) / div3, np.float32(0.0))) + # logging.info("solve_zero_uv, C: {}, E: {}, tau: {}, type_C: {}, type_E: {}, type_tau: {}".format(C, E, tau, type(C), type(E), type(tau))) + div4 = np.float32(1.0) - p + if div4 == 0.: + div4 = ZERO_REPLACE + if 0 <= tau and tau <= P / div4: + lam10 = tau + lam11 = np.float32(max(P / div2 - (np.float32(1.0) - p) * tau / div2, np.float32(0.0))) + # logging.info("solve_zero_uv, branch_1, lam10: {}, lam11: {}, type_lam10: {}, type_lam11:{}".format(lam10, lam11, type(lam10), type(lam11))) + else: + lam10_case1, lam11_case1 = np.float32(0.0), max(P / div2, np.float32(0.0)) + lam10_case2, lam11_case2 = np.float32(max(P / div4, np.float32(0.0))), np.float32(0.0) + objective1 = symKL_objective_zero_uv(lam10=lam10_case1, lam11=lam11_case1, + g_norm_square=g_norm_square) + objective2 = symKL_objective_zero_uv(lam10=lam10_case2, lam11=lam11_case2, + g_norm_square=g_norm_square) + if objective1 < objective2: + lam10, lam11 = lam10_case1, lam11_case1 + else: + lam10, lam11 = lam10_case2, lam11_case2 + + # logging.info("solve_zero_uv, branch_2, lam10: {}, lam11: {}, type_lam10: {}, type_lam11:{}".format(lam10, lam11, type(lam10), type(lam11))) + + objective = symKL_objective_zero_uv(lam10=lam10, lam11=lam11, g_norm_square=g_norm_square) + # logging.info("solve_zero_uv, objective {}, type: {}".format(objective, type(objective))) + + # here we subtract d = 1 because the distribution is essentially one-dimensional + return (lam10, np.float32(0.0), lam11, np.float32(0.0), np.float32(np.float32(0.5) * objective - np.float32(1.0))) + + +def prime1(x, d, v, lam11, u, g_norm_square, D): + div11 = v + if div11 == 0.: + div11 = ZERO_REPLACE + div12 = lam11 + v + if div12 == 0.: + div12 = ZERO_REPLACE + div13 = x + u + if div13 == 0.: + div13 = ZERO_REPLACE + div14 = (D - (d - np.float32(1.0)) * x + u) + if div14 == 0.: + div14 = ZERO_REPLACE + return (d - np.float32(1.0)) / div11 - (d - np.float32(1.0)) / div12 - ( + d - np.float32(1.0)) / div13 * (v / div13) + (lam11 + v + g_norm_square) / div14 * ( + (d - np.float32(1.0)) / div14) + + +def prime2(x, d, v, p, lam10, u, g_norm_square, D): + div21 = v + if div21 == 0.: + div21 = ZERO_REPLACE + div22 = lam10 + u + if div22 == 0.: + div22 = ZERO_REPLACE + div23 = p + if div23 == 0.: + div23 = ZERO_REPLACE + div24 = x + u + if div24 == 0.: + div24 = ZERO_REPLACE + div25 = (D / div23 - (np.float32(1.0) - p) * (d - np.float32(1.0)) * x / div23 + v) + if div25 == 0.: + div25 = ZERO_REPLACE + div26 = (D / div23 - (1 - p) * (d - 1) * x / div23 + v) + if div26 == 0.: + div26 = ZERO_REPLACE + return (d - np.float32(1.0)) / div21 - (np.float32(1.0) - p) * (d - np.float32(1.0)) / div22 / div23 - ( + d - np.float32(1.0)) / div24 * (v / div24) + ( + lam10 + u + g_norm_square) / div25 * (1 - p) * (d - 1) / div23 / div26 + +def solve_small_neg(u, v, d, g_norm_square, p, P, lam10=None, lam20=None, lam11=None): + """[When u < v] + """ + # 优化过程:三个参数,轮流固定其中一个,另两个形成一个线性优化问题,求解另两个参数最优解 + # 结束条件:最后一轮的目标函数和倒数第四轮的目标函数的差值在一定范围内 + # some intialization to start the alternating optimization + LAM21 = np.float32(0.0) + i = 0 + objective_value_list = [] + + if lam20: + ordering = [0, 1, 2] + elif lam11: + ordering = [1, 0, 2] + else: + ordering = [1, 2, 0] + + while True: + if i % 3 == ordering[0]: # fix lam20 + D = np.float32(P - (np.float32(1.0) - p) * (d - np.float32(1.0)) * lam20) + C = np.float32(D + p * v + (np.float32(1.0) - p) * u) + + div1 = C + p * g_norm_square + if div1 == 0.: + div1 = ZERO_REPLACE + E = np.float32(math.sqrt((C + (np.float32(1.0) - p) * g_norm_square) / div1)) + + div2 = p + if div2 == 0.: + div2 = ZERO_REPLACE + + div_x = (E + (np.float32(1.0) - p) / div2) + if div_x == 0.: + div_x = ZERO_REPLACE + tau = np.float32(max((D / div2 + v - E * u) / div_x, np.float32(0.0))) + div3 = np.float32(1.0) - p + if div3 == 0.: + div3 = ZERO_REPLACE + + if lam20 <= tau and tau <= np.float32(P / div3 - (d - np.float32(1.0)) * lam20): + lam10 = tau + lam11 = np.float32(max(D / div2 - (np.float32(1.0) - p) * tau / div2, np.float32(0.0))) + else: + lam10_case1, lam11_case1 = lam20, np.float32( + max(P / div2 - (np.float32(1.0) - p) * d * lam20 / div2, np.float32(0.0))) + lam10_case2, lam11_case2 = np.float32( + max(P / div3 - (d - np.float32(1.0)) * lam20, np.float32(0.0))), np.float32(0.0) + objective1 = symKL_objective(lam10=lam10_case1, lam20=lam20, lam11=lam11_case1, lam21=LAM21, + u=u, v=v, d=d, g_norm_square=g_norm_square) + objective2 = symKL_objective(lam10=lam10_case2, lam20=lam20, lam11=lam11_case2, lam21=LAM21, + u=u, v=v, d=d, g_norm_square=g_norm_square) + if objective1 < objective2: + lam10, lam11 = lam10_case1, lam11_case1 + else: + lam10, lam11 = lam10_case2, lam11_case2 + + elif i % 3 == ordering[1]: # fix lam11 + div1 = np.float32(1.0) - p + if div1 == 0.: + div1 = ZERO_REPLACE + D = np.float32(max((P - p * lam11) / div1, np.float32(0.0))) + f = lambda x: symKL_objective(lam10=D - (d - np.float32(1.0)) * x, lam20=x, lam11=lam11, lam21=LAM21, + u=u, v=v, d=d, g_norm_square=g_norm_square) + + f_prime = lambda x: prime1(x=x, d=d, v=v, lam11=lam11, u=u, g_norm_square=g_norm_square, D=D) + + div2 = d + if div2 == 0.: + div2 = ZERO_REPLACE + lam20 = convex_min_1d(xl=np.float32(0.0), xr=D / div2, f=f, f_prime=f_prime) + lam10 = np.float32(max(D - (d - np.float32(1.0)) * lam20, np.float32(0.0))) + + else: # fix lam10 + D = np.float32( + max(P - (np.float32(1.0) - p) * lam10, np.float32(0.0))) # avoid negative due to numerical error + + div1 = p + if div1 == 0.: + div1 = ZERO_REPLACE + f = lambda x: symKL_objective(lam10=lam10, lam20=x, + lam11=D / div1 - (np.float32(1.0) - p) * (d - np.float32(1.0)) * x / div1, + lam21=LAM21, + u=u, v=v, d=d, g_norm_square=g_norm_square) + + f_prime = lambda x: prime2(x=x, d=d, v=v, p=p, lam10=lam10, u=u, g_norm_square=g_norm_square, D=D) + + div2 = (np.float32(1.0) - p) * (d - np.float32(1.0)) + if div2 == 0.: + div2 = ZERO_REPLACE + lam20 = convex_min_1d(xl=np.float32(0.0), + xr=min(D / div2, lam10), f=f, + f_prime=f_prime) + lam11 = np.float32(max(D / div1 - (np.float32(1.0) - p) * (d - np.float32(1.0)) * lam20 / div1, np.float32(0.0))) + + # if lam10 <0 or lam20 < 0 or lam11 <0 or LAM21 <0: # check to make sure no negative values + # assert False, i + + objective_value_list.append(symKL_objective(lam10=lam10, lam20=lam20, lam11=lam11, lam21=LAM21, + u=u, v=v, d=d, g_norm_square=g_norm_square)) + # logging.info("solve_small_neg, iter: {}, objective_value_list[-1]: {}".format(i, objective_value_list[-1])) + if (i >= 3 and objective_value_list[-4] - objective_value_list[-1] < OBJECTIVE_EPSILON) or i >= 100: + # logging.info("solve_small_neg, iter: {}, terminated".format(i)) + return (lam10, lam20, lam11, LAM21, np.float32(0.5) * objective_value_list[-1] - d) + + i += 1 + + +def prime3(x, d, u, lam11, v, p, g_norm_square, D): + div31 = u + if div31 == 0.: + div31 = ZERO_REPLACE + div32 = lam11 + v + if div32 == 0.: + div32 = ZERO_REPLACE + div33 = (np.float32(1.0) - p) + if div33 == 0.: + div33 = ZERO_REPLACE + div34 = x + v + if div34 == 0.: + div34 = ZERO_REPLACE + div35 = (D - p * (d - np.float32(1.0)) * x) / div33 + u + if div35 == 0.: + div35 = ZERO_REPLACE + return (d - np.float32(1.0)) / div31 - p * (d - np.float32(1.0)) / div32 / div33 - (d - 1) / div34 * (u / div34) \ + + (lam11 + v + g_norm_square) / div35 * p * (d - np.float32(1.0)) / div33 / div35 + + +def prime4(x, d, u, lam10, v, g_norm_square, D): + div41 = u + if div41 == 0.: + div41 = ZERO_REPLACE + div42 = lam10 + u + if div42 == 0.: + div42 = ZERO_REPLACE + div43 = x + v + if div43 == 0.: + div43 = ZERO_REPLACE + div44 = (D - (d - np.float32(1.0)) * x + v) + if div44 == 0.: + div44 = ZERO_REPLACE + return (d - np.float32(1.0)) / div41 - (d - np.float32(1.0)) / div42 - ( + d - np.float32(1.0)) / div43 * (u / div43) + (lam10 + u + g_norm_square) / div44 * (d - np.float32(1.0)) / div44 + + +def solve_small_pos(u, v, d, g_norm_square, p, P, lam10=None, lam11=None, lam21=None): + """[When u > v] lam20 = 0.0 and will not change throughout the optimization + """ + # 优化过程:三个参数,轮流固定其中一个,另两个形成一个线性优化问题,求解另两个参数最优解 + # some intialization to start the alternating optimization + LAM20 = np.float32(0.0) + i = 0 + objective_value_list = [] + if lam21: + ordering = [0, 1, 2] + elif lam11: + ordering = [1, 0, 2] + else: + ordering = [1, 2, 0] + while True: + if i % 3 == ordering[0]: # fix lam21 + D = np.float32(P - p * (d - np.float32(1.0)) * lam21) + C = np.float32(D + p * v + (np.float32(1.0) - p) * u) + + div1 = (C + p * g_norm_square) + if div1 == 0.: + div1 = ZERO_REPLACE + E = np.float32(math.sqrt((C + (np.float32(1.0) - p) * g_norm_square) / div1)) + div2 = p + if div2 == 0.: + div2 = ZERO_REPLACE + div3 = (E + (np.float32(1.0) - p) / div2) + if div3 == 0.: + div3 = ZERO_REPLACE + tau = np.float32(max((D / div2 + v - E * u) / div3, np.float32(0.0))) + div4 = (np.float32(1.0) - p) + if div4 == 0.: + div4 = ZERO_REPLACE + if np.float32(0.0) <= tau and tau <= (P - p * d * lam21) / div4: + lam10 = tau + lam11 = np.float32(max(D / div2 - (np.float32(1.0) - p) * tau / div2, np.float32(0.0))) + else: + lam10_case1, lam11_case1 = np.float32(0), np.float32( + max(P / div2 - (d - np.float32(1.0)) * lam21, np.float32(0.0))) + lam10_case2, lam11_case2 = np.float32( + max((P - p * d * lam21) / div4, np.float32(0.0))), lam21 + objective1 = symKL_objective(lam10=lam10_case1, lam20=LAM20, lam11=lam11_case1, lam21=lam21, + u=u, v=v, d=d, g_norm_square=g_norm_square) + objective2 = symKL_objective(lam10=lam10_case2, lam20=LAM20, lam11=lam11_case2, lam21=lam21, + u=u, v=v, d=d, g_norm_square=g_norm_square) + if objective1 < objective2: + lam10, lam11 = lam10_case1, lam11_case1 + else: + lam10, lam11 = lam10_case2, lam11_case2 + # logging.info("solve_small_pos, branch: 0, lam10: {}, lam11: {}".format(lam10, lam11)) + elif i % 3 == ordering[1]: # fix lam11 + D = np.float32(max(P - p * lam11, np.float32(0.0))) + div1 = np.float32(1.0) - p + if div1 == 0.: + div1 = ZERO_REPLACE + f = lambda x: symKL_objective(lam10=(D - p * (d - 1) * x) / div1, lam20=LAM20, lam11=lam11, + lam21=x, + u=u, v=v, d=d, g_norm_square=g_norm_square) + + f_prime = lambda x: prime3(x=x, d=d, u=v, lam11=lam11, v=v, p=p, g_norm_square=g_norm_square, D=D) + + div2 = p + if div2 == 0.: + div2 = ZERO_REPLACE + div3 = d - np.float32(1.0) + if div3 == 0.: + div3 = ZERO_REPLACE + lam21 = convex_min_1d(xl=np.float32(0.0), xr=min(D / div2 / div3, lam11), f=f, + f_prime=f_prime) + lam10 = np.float32(max((D - p * (d - 1) * lam21) / div1, np.float32(0.0))) + # logging.info("solve_small_pos, branch: 1, lam10: {}, lam21: {}".format(lam10, lam21)) + + else: # fix lam10 + div1 = p + if div1 == 0.: + div1 = ZERO_REPLACE + D = np.float32(max((P - (1 - p) * lam10) / div1, np.float32(0.0))) + f = lambda x: symKL_objective(lam10=lam10, lam20=LAM20, lam11=D - (d - np.float32(1.0)) * x, lam21=x, + u=u, v=v, d=d, g_norm_square=g_norm_square) + + f_prime = lambda x: prime4(x=x, d=d, u=u, lam10=lam10, v=v, g_norm_square=g_norm_square, D=D) + + div2 = d + if div2 == 0.: + div2 = ZERO_REPLACE + lam21 = convex_min_1d(xl=np.float32(0.0), xr=D / div2, f=f, f_prime=f_prime) + lam11 = np.float32(max(D - (d - np.float32(1.0)) * lam21, np.float32(0.0))) + + objective_value_list.append(symKL_objective(lam10=lam10, lam20=LAM20, lam11=lam11, lam21=lam21, + u=u, v=v, d=d, g_norm_square=g_norm_square)) + + if (i >= 3 and objective_value_list[-4] - objective_value_list[-1] < OBJECTIVE_EPSILON) or i >= 100: + # logging.info("solve_small_pos, iter: {}, terminated".format(i)) + return (lam10, LAM20, lam11, lam21, np.float32(np.float32(0.5) * objective_value_list[-1] - d)) + + i += 1 + + +def convex_min_1d(xl, xr, f, f_prime): + # 求解二值优化问题:1-d line-search minimization + xm = np.float32((xl + xr) / np.float32(2.0)) + if abs(xl - xr) <= CONVEX_EPSILON or abs(xl - xm) <= CONVEX_EPSILON or abs(xm - xr) <= CONVEX_EPSILON: + return np.float32(min((f(x), x) for x in [xl, xm, xr])[1]) + if f_prime(xl) <= 0 and f_prime(xr) <= 0: + return np.float32(xr) + elif f_prime(xl) >= 0 and f_prime(xr) >= 0: + return np.float32(xl) + if f_prime(xm) > 0: + return convex_min_1d(xl=xl, xr=xm, f=f, f_prime=f_prime) + else: + return convex_min_1d(xl=xm, xr=xr, f=f, f_prime=f_prime) + + +def small_neg_problem_string(u, v, d, g_norm_square, p, P): + return 'minimize ({2}-1)*(z + {0})/{1} + ({2}-1)*{1}/(z+{0})+(x+{0}+{3})/(y+{1}) + (y+{1}+{3})/(x+{0}) subject to x>=0, y>=0, z>=0, z<=x, {4}*y+(1-{4})*x+(1-{4})*({2}-1)*z={5}'.format( + u, v, d, g_norm_square, p, P) + + +def small_pos_problem_string(u, v, d, g_norm_square, p, P): + return 'minimize ({2}-1)*{0}/(z+{1}) + ({2}-1)*(z + {1})/{0} + (x+{0}+{3})/(y+{1}) + (y+{1}+{3})/(x+{0}) subject to x>=0, y>=0, z>=0, z<=y, {4}*y+(1-{4})*x+{4}*({2}-1)*z={5}'.format( + u, v, d, g_norm_square, p, P) + + +def zero_uv_problem_string(g_norm_square, p, P): + return 'minimize (x+{0})/y + (y+{0})/x subject to x>=0, y>=0, {1}*y+(1-{1})*x={2}'.format(g_norm_square, p, P) diff --git a/fedlearner/privacy/splitnn/norm_attack.py b/fedlearner/privacy/splitnn/norm_attack.py new file mode 100644 index 000000000..2739704aa --- /dev/null +++ b/fedlearner/privacy/splitnn/norm_attack.py @@ -0,0 +1,17 @@ +import tensorflow.compat.v1 as tf + +# Norm Attack见论文:https://arxiv.org/pdf/2102.08504.pdf + +def get_norm_pred(loss, var_list, gate_gradients): + # 获取gradient + g = tf.gradients(loss, var_list, gate_gradients=gate_gradients)[0] + # 计算gradient二范数,label=0和label=1的gradient二范数会存在差异 + norm_pred = tf.math.sigmoid(tf.norm(g, ord=2, axis=1)) + return norm_pred + +def norm_attack_auc(loss, var_list, gate_gradients, y): + norm_pred = get_norm_pred(loss, var_list, gate_gradients) + norm_pred = tf.reshape(norm_pred, y.shape) + # 计算norm attack auc + _, norm_auc = tf.metrics.auc(y, norm_pred) + return norm_auc diff --git a/fedlearner/proxy/channel.py b/fedlearner/proxy/channel.py index 0eadce1a4..165dfa205 100644 --- a/fedlearner/proxy/channel.py +++ b/fedlearner/proxy/channel.py @@ -28,7 +28,6 @@ EGRESS_HOST = os.environ.get('EGRESS_HOST', None) EGRESS_DOMAIN = os.environ.get('EGRESS_DOMAIN', None) - class ChannelType(Enum): UNKNOWN = 0 INTERNAL = 1 @@ -148,9 +147,10 @@ def make_secure_channel(address, mode=ChannelType.INTERNAL, options=None, compression=None): - use_tls, creds = common.use_tls() - assert use_tls, "In-consistant TLS enabling" - tls_creds = grpc.ssl_channel_credentials(creds[0], creds[1], creds[2]) + assert common.use_tls(), "In-consistant TLS enabling" + + tls_creds = grpc.sgxratls_channel_credentials("dynamic_config.json") + if check_address_valid(address): return grpc.secure_channel(address, tls_creds, options, compression) diff --git a/fedlearner/trainer/bridge.py b/fedlearner/trainer/bridge.py index a30d7ccb6..6f9c7dff8 100644 --- a/fedlearner/trainer/bridge.py +++ b/fedlearner/trainer/bridge.py @@ -23,11 +23,12 @@ import tensorflow.compat.v1 as tf from google.protobuf import any_pb2 as any_pb -from fedlearner.common import fl_logging +from fedlearner.common import fl_logging, common from fedlearner.channel import Channel from fedlearner.common import common_pb2 as common_pb from fedlearner.common import trainer_worker_service_pb2 as tws2_pb from fedlearner.common import trainer_worker_service_pb2_grpc as tws2_grpc +from fedlearner.common.metric_collector import metric_collector from fedlearner.trainer._global_context import global_context as _gctx _BRIDGE_SUPERVISE_ENABLED = strtobool( @@ -91,6 +92,7 @@ def __init__(self, self._channel = Channel( self._listen_address, self._remote_address, token=self._token, + max_workers=common.get_tf_config()["grpc_server_channel_threads"], stats_client=_gctx.stats_client) self._channel.subscribe(self._channel_callback) @@ -396,9 +398,9 @@ def commit(self): duration = (time.time() - self._iter_started_at) * 1000 self._current_iter_id = None - with _gctx.stats_client.pipeline() as pipe: - pipe.gauge("trainer.bridge.iterator_step", iter_id) - pipe.timing("trainer.bridge.iterator_timing", duration) + name_prefix = 'model.grpc.bridge' + metric_collector.emit_store(f'{name_prefix}.iterator_step', iter_id) + metric_collector.emit_store(f'{name_prefix}.iterator_timing', duration) def register_data_block_handler(self, func): assert self._data_block_handler_fn is None, \ @@ -479,10 +481,9 @@ def _receive(self, name): data = self._received_data[iter_id][name] duration = time.time() - start_time - _gctx.stats_client.timing( - "trainer.bridge.receive_timing", duration * 1000, - {"bridge_receive_name": name} - ) + metric_collector.emit_store(f'model.grpc.bridge.receive_timing', + duration * 1000, + {'bridge_receive_name': name}) fl_logging.debug("[Bridge] Data: received iter_id: %d, name: %s " "after %f sec", iter_id, name, duration) @@ -499,3 +500,63 @@ def func(): return tf.convert_to_tensor(self.receive(name), dtype=dtype) return tf.py_function(func=func, inp=[], Tout=dtype, name='recv_'+name) + + +class FakeBridge(object): + def __init__(self): + self._condition = threading.Condition() + self._current_iter_id = None + self._next_iter_id = 0 + self._iter_started_at = 0 + self._termiated_at = None + + @property + def terminated_at(self): + return self._termiated_at + + def connect(self): + fl_logging.debug("[Fake Bridge] connected") + + def start(self): + with self._condition: + fl_logging.debug("[Fake Bridge] started") + self._current_iter_id = self._next_iter_id + self._next_iter_id += 1 + self._iter_started_at = time.time() + + def commit(self): + with self._condition: + fl_logging.debug("[Fake Bridge] send commit iter_id: %d", + self._current_iter_id) + iter_id = self._current_iter_id + duration = (time.time() - self._iter_started_at) * 1000 + self._current_iter_id = None + + with _gctx.stats_client.pipeline() as pipe: + pipe.gauge("trainer.fake_bridge.iterator_step", iter_id) + pipe.timing("trainer.fake_bridge.iterator_timing", duration) + + def terminate(self): + fl_logging.debug("[Fake Bridge] terminated") + with self._condition: + self._termiated_at = int(time.time()) + + def load_data_block(self, count, block_id): + fl_logging.debug("[Fake Bridge] load DataBlock with id %s", block_id) + return True + + def send_op(self, name, x): + def func(x): + raise RuntimeError("Unexcepted call send op") + + out = tf.py_function(func=func, inp=[x], Tout=[], name='send_' + name) + return out + + def receive_op(self, name, dtype): + def func(): + raise RuntimeError("Unexcepted call receive op") + + return tf.py_function(func=func, inp=[], Tout=[dtype])[0] + + def register_data_block_handler(self, handler): + pass diff --git a/fedlearner/trainer/cluster_server.py b/fedlearner/trainer/cluster_server.py index ea496f8f2..d1fec26f9 100644 --- a/fedlearner/trainer/cluster_server.py +++ b/fedlearner/trainer/cluster_server.py @@ -13,27 +13,29 @@ # limitations under the License. # coding: utf-8 - +from typing import Optional import tensorflow.compat.v1 as tf -from fedlearner.common import fl_logging +from fedlearner.common import fl_logging, common -class ClusterServer(): +class ClusterServer: def __init__(self, cluster_spec, job_name, task_index=0, - extra_reserve_jobs=None): + extra_reserve_jobs=None, + server_port: Optional[int] = None): self._job_name = job_name self._task_index = task_index self._extra_reserve_jobs = set(extra_reserve_jobs) \ if extra_reserve_jobs is not None else set(["ps"]) + self._server_port = server_port self._create_tf_server(cluster_spec) def _create_tf_server(self, cluster_spec): self._tf_config = tf.ConfigProto() - self._tf_config.inter_op_parallelism_threads = 64 - self._tf_config.intra_op_parallelism_threads = 64 + self._tf_config.inter_op_parallelism_threads = 8 + self._tf_config.intra_op_parallelism_threads = 8 self._tf_config.experimental \ .share_session_state_in_clusterspec_propagation = True self._tf_config.rpc_options.compression_algorithm = "gzip" @@ -41,29 +43,31 @@ def _create_tf_server(self, cluster_spec): self._tf_config.rpc_options.disable_session_connection_sharing = True try: - address = cluster_spec.task_address( + task_address = cluster_spec.task_address( self._job_name, self._task_index) + address = task_address + if self._server_port: + address = f'0.0.0.0:{self._server_port}' self._tf_server = \ tf.distribute.Server({"server": { self._task_index: address} }, protocol="grpc", config=self._tf_config) - self._tf_target = "grpc://" + address + self._tf_target = "grpc://" + task_address except ValueError: self._tf_server = \ tf.distribute.Server({"server": - {self._task_index: "localhost:0"} - }, + {self._task_index: "localhost:0"} + }, protocol="grpc", config=self._tf_config) self._tf_target = self._tf_server.target + task_address = self._tf_target[len("grpc://"):] # modify cluster_spec cluster_dict = dict() - cluster_dict[self._job_name] = { - self._task_index: self._tf_target[len("grpc://"):] - } + cluster_dict[self._job_name] = {self._task_index: task_address} for job_name in cluster_spec.jobs: if job_name == self._job_name: continue diff --git a/fedlearner/trainer/data/data_block_loader.py b/fedlearner/trainer/data/data_block_loader.py index 51e65849f..d511247ef 100644 --- a/fedlearner/trainer/data/data_block_loader.py +++ b/fedlearner/trainer/data/data_block_loader.py @@ -33,6 +33,11 @@ def __init__(self, batch_size, role, bridge, trainer_master): self._bridge.register_data_block_handler(self._data_block_handler) def _data_block_handler(self, msg): + if self._count > msg.count: + fl_logging.warn('DataBlock: ignore repeated datablock "%s" at %d', + msg.block_id, msg.count) + return True + fl_logging.info('DataBlock: recv "%s" at %d', msg.block_id, msg.count) assert self._count == msg.count if not msg.block_id: @@ -61,7 +66,7 @@ def get_next_block(self): block = self._block_queue.get() return block - def make_dataset(self): + def make_dataset(self, compression_type=None): def gen(): while True: block = self.get_next_block() @@ -70,7 +75,8 @@ def gen(): yield block.data_path dataset = tf.data.Dataset.from_generator(gen, tf.string) - dataset = tf.data.TFRecordDataset(dataset) + dataset = tf.data.TFRecordDataset(dataset, + compression_type=compression_type) dataset = dataset.batch(self._batch_size, drop_remainder=True) dataset = dataset.prefetch(1) return dataset diff --git a/fedlearner/trainer/data_visitor.py b/fedlearner/trainer/data_visitor.py index a7b23a625..5f7dc6ab0 100644 --- a/fedlearner/trainer/data_visitor.py +++ b/fedlearner/trainer/data_visitor.py @@ -15,16 +15,23 @@ # coding: utf-8 # pylint: disable=broad-except +from fnmatch import fnmatch import os import zlib import json import threading import collections import random +import sys +from datetime import timedelta, datetime +from typing import Optional import tensorflow.compat.v1 as tf from fedlearner.common import fl_logging +from fedlearner.common import trainer_master_service_pb2 as tm_pb +from fedlearner.common.common import convert_time_string_to_datetime from fedlearner.data_join.data_block_visitor import DataBlockVisitor +from fedlearner.trainer.utils import match_date kvstore_type = os.environ.get('KVSTORE_TYPE', 'etcd') @@ -33,34 +40,114 @@ class _RawDataBlock( collections.namedtuple('RowDataBlock', - ['id', 'data_path'])): + ['id', 'data_path', 'start_time', 'end_time', + 'type'])): pass class DataBlock( collections.namedtuple('DataBlock', - ['id', 'epoch', 'data_path'])): + ['id', 'epoch', 'data_path', 'type'])): pass +class ShuffleType(object): + ALL = 'all' + DAY = 'day' + + +class RawDataBlockDealer(object): + def __init__(self, data_blocks): + self._data_blocks = data_blocks + + @property + def data_blocks(self): + return self._data_blocks + + def time_translate(self, forward, day, hour=0,): + delta = timedelta(days=day, hours=hour) + date_fmt = '%Y%m%d' + for db in self._data_blocks: + start_time = str(db.start_time)[:8] + end_time = str(db.end_time)[:8] + if forward: + new_start_time = datetime.strptime(start_time, date_fmt) + delta + new_end_time = datetime.strptime(end_time, date_fmt) + delta + else: + new_start_time = datetime.strptime(start_time, date_fmt) - delta + new_end_time = datetime.strptime(end_time, date_fmt) - delta + db.start_time = new_start_time.strftime(date_fmt) + start_time[8:] + db.end_time = new_end_time.strftime(date_fmt) + end_time[8:] + return self + + def merge_data_blocks(self, data_blocks): + self._data_blocks.extend(data_blocks) + return self + + def shuffle(self): + random.shuffle(self._data_blocks) + return self + + def shuffle_in_day(self): + def _shuffle(_start_index, _end_index): + # using Fisher–Yates shuffle Algorithm + for i in range(_end_index, _start_index, -1): + j = random.randint(_start_index, i) + self._data_blocks[i], self._data_blocks[j] = \ + self._data_blocks[j], self._data_blocks[i] + + start_index = 0 + end_index = 1 + num_data_blocks = len(self._data_blocks) + if not self._data_blocks or not self._data_blocks[0].end_time: + return self + start_day = str(self._data_blocks[0].end_time)[:8] + while end_index < num_data_blocks: + new_day = str(self._data_blocks[end_index].end_time)[:8] + if new_day != start_day: + _shuffle(start_index, end_index-1) + start_index = end_index + start_day = new_day + end_index += 1 + _shuffle(start_index, end_index - 1) + return self + + class _DataVisitor(object): - def __init__(self, datablocks, epoch_num=1, shuffle=False): - self._datablocks = list(datablocks) + def __init__(self, datablocks, local_datablocks=None, epoch_num=1, + shuffle_type: Optional[ShuffleType] = None): + self._datablocks = { + tm_pb.JOINED: list(datablocks), + } self._datablock_dict = {} for datablock in datablocks: - fl_logging.info("load datablock, id: %s, data_path: %s", - datablock.id, datablock.data_path) self._datablock_dict[datablock.id] = datablock + if local_datablocks: + self._datablocks[tm_pb.LOCAL] = list(local_datablocks) + for datablock in local_datablocks: + self._datablock_dict[datablock.id] = datablock self._epoch_num = epoch_num if epoch_num > 0 else 1 - self._shuffle = shuffle + self._shuffle_type = shuffle_type self._lock = threading.Lock() - self._datablock_index = 0 + self._datablock_index = { + tm_pb.JOINED: 0, + tm_pb.LOCAL: 0 + } + self._current_epoch = 1 self._allocated = {} # epoch -> set(datablock.id) - if self._shuffle: - random.shuffle(self._datablocks) + self._shuffle_data_blocks() + for datablock in self._datablocks[tm_pb.JOINED]: + fl_logging.info("load data block, id: %s, data_path: %s, type %s", + datablock.id, datablock.data_path, datablock.type) + if local_datablocks: + for datablock in self._datablocks[tm_pb.LOCAL]: + fl_logging.info("load data block, id: %s, data_path: %s, " + "type %s", + datablock.id, datablock.data_path, + datablock.type) @property def epoch_num(self): @@ -68,13 +155,38 @@ def epoch_num(self): @property def datablock_size(self): - return len(self._datablocks) * self._epoch_num + return len(self._datablocks[tm_pb.JOINED]) * self._epoch_num + + @property + def local_datablock_size(self): + if tm_pb.LOCAL in self._datablocks: + return len(self._datablocks[tm_pb.LOCAL]) * self._epoch_num + return 0 + + def _shuffle_data_blocks(self): + for datablocks in self._datablocks.values(): + dealer = RawDataBlockDealer(datablocks) + if self._shuffle_type == ShuffleType.ALL: + dealer.shuffle() + elif self._shuffle_type == ShuffleType.DAY: + dealer.shuffle_in_day() + elif self._shuffle_type: + fl_logging.fatal("Not supported shuffle type %s", + self._shuffle_type) + sys.exit(-1) def summary(self): with self._lock: + local_allocated_blocks = 0 + if tm_pb.LOCAL in self._datablocks: + local_allocated_blocks = (self._current_epoch - 1) * \ + len(self._datablocks[tm_pb.LOCAL]) \ + + self._datablock_index[tm_pb.LOCAL] return (self._current_epoch, - (self._current_epoch-1) * len(self._datablocks) \ - + self._datablock_index) + (self._current_epoch-1) * + len(self._datablocks[tm_pb.JOINED]) \ + + self._datablock_index[tm_pb.JOINED], + local_allocated_blocks) def dump(self): with self._lock: @@ -113,7 +225,8 @@ def get_datablock_by_id(self, block_id, epoch=1): if block_id not in self._datablock_dict: return None datablock = self._datablock_dict[block_id] - return DataBlock(datablock.id, epoch, datablock.data_path) + return DataBlock(datablock.id, epoch, datablock.data_path, + datablock.type) def _try_parse_v2(self, buff): try: @@ -143,26 +256,35 @@ def _allocate(self, epoch, datablock): self._allocated[epoch] = set() self._allocated[epoch].add(datablock.id) - def _next(self, peek=False): + def _next(self, peek=False, data_type=tm_pb.JOINED): while True: - while self._datablock_index < len(self._datablocks): - datablock = self._datablocks[self._datablock_index] + while self._datablock_index[data_type] < \ + len(self._datablocks[data_type]): + datablock = self._datablocks[data_type][ + self._datablock_index[data_type]] if self._check_allocated(self._current_epoch, datablock): if not peek: - self._datablock_index += 1 + self._datablock_index[data_type] += 1 self._allocate(self._current_epoch, datablock) return DataBlock(datablock.id, self._current_epoch, - datablock.data_path) - self._datablock_index += 1 + datablock.data_path, + datablock.type) + self._datablock_index[data_type] += 1 if self._current_epoch == self._epoch_num: raise StopIteration() self._current_epoch += 1 - self._datablock_index = 0 - if self._shuffle: - random.shuffle(self._datablocks) + self._datablock_index = { + tm_pb.JOINED: 0, + tm_pb.LOCAL: 0 + } + self._shuffle_data_blocks() + + def next_with_type(self, data_block_type): + with self._lock: + return self._next(data_type=data_block_type) def __next__(self): with self._lock: @@ -176,44 +298,102 @@ def __init__(self, data_source, start_date=None, end_date=None, + local_data_source=None, + local_start_date=None, + local_end_date=None, epoch_num=1, - shuffle=False): - fl_logging.info("create DataVisitor by data_source: %s", data_source) - self._data_block_visitor = DataBlockVisitor( + shuffle_type=None): + fl_logging.info("Load data_source: %s", data_source) + data_block_visitor = DataBlockVisitor( data_source, kvstore_type, kvstore_use_mock) - datablocks = [] - for datablock in self._data_block_visitor.LoadDataBlockRepByTimeFrame( + data_blocks = [] + for datablock in data_block_visitor.LoadDataBlockRepByTimeFrame( start_date, end_date).values(): - datablocks.append(datablock) - datablocks.sort(key=lambda x: x.start_time) + data_blocks.append( + _RawDataBlock(datablock.block_id, datablock.data_block_fpath, + datablock.start_time, datablock.end_time, + tm_pb.JOINED)) + local_data_blocks = [] + if local_data_source: + fl_logging.info("Load local data_source: %s", local_data_source) + data_block_visitor = DataBlockVisitor( + local_data_source, kvstore_type, kvstore_use_mock) + for datablock in data_block_visitor.LoadDataBlockRepByTimeFrame( + local_start_date, local_end_date).values(): + local_data_blocks.append( + _RawDataBlock(datablock.block_id, + datablock.data_block_fpath, + datablock.start_time, + datablock.end_time, + tm_pb.LOCAL)) + data_blocks.sort(key=lambda x: x.end_time) + local_data_blocks.sort(key=lambda x: x.end_time) super(DataSourceVisitor, self).__init__( - [_RawDataBlock(d.block_id, d.data_block_fpath) for d in datablocks], - epoch_num, - shuffle) + data_blocks, local_data_blocks, epoch_num, shuffle_type) class DataPathVisitor(_DataVisitor): def __init__(self, - data_path, - ext=".tfrecord", - epoch_num=1, - shuffle=False): + data_path: str, + local_data_path: str, + wildcard: str, + epoch_num: int = 1, + shuffle_type=None, + start_date=None, + end_date=None): fl_logging.info("create DataVisitor by data_path: %s", data_path) if not tf.io.gfile.exists(data_path): raise ValueError("data_path not found: %s"%data_path) + if start_date: + start_date = convert_time_string_to_datetime(str(start_date)) + if end_date: + end_date = convert_time_string_to_datetime(str(end_date)) datablocks = [] for dirname, _, filenames in tf.io.gfile.walk(data_path): for filename in filenames: - _, fileext = os.path.splitext(filename) - if ext and fileext != ext: + if not fnmatch(os.path.join(dirname, filename), wildcard): continue subdirname = os.path.relpath(dirname, data_path) + try: + cur_date = datetime.strptime(subdirname, '%Y%m%d') + if not match_date(cur_date, start_date, end_date): + continue + except Exception: + fl_logging.info('subdirname is not the format of time') block_id = os.path.join(subdirname, filename) - datablock = _RawDataBlock(block_id, - os.path.join(dirname, filename)) + datablock = _RawDataBlock( + id=block_id, data_path=os.path.join(dirname, filename), + start_time=None, end_time=None, type=tm_pb.JOINED) datablocks.append(datablock) - datablocks.sort() + datablocks.sort(key=lambda x: x.id) + + fl_logging.info("create DataVisitor by local_data_path: %s", + local_data_path) + local_datablocks = [] + if local_data_path and tf.io.gfile.exists(local_data_path): + for dirname, _, filenames in tf.io.gfile.walk(local_data_path): + for filename in filenames: + if not fnmatch(os.path.join(dirname, filename), wildcard): + continue + subdirname = os.path.relpath(dirname, local_data_path) + block_id = os.path.join(subdirname, filename) + datablock = _RawDataBlock( + id=block_id, data_path=os.path.join(dirname, filename), + start_time=None, end_time=None, type=tm_pb.LOCAL) + local_datablocks.append(datablock) + local_datablocks.sort(key=lambda x: x.id) + + super(DataPathVisitor, self).__init__(datablocks, local_datablocks, + epoch_num, shuffle_type) + + def _check_allocated(self, epoch: int, datablock: _RawDataBlock): + if epoch not in self._allocated: + return True + return datablock.data_path not in self._allocated[epoch] - super(DataPathVisitor, self).__init__(datablocks, epoch_num, shuffle) + def _allocate(self, epoch: int, datablock: _RawDataBlock): + if epoch not in self._allocated: + self._allocated[epoch] = set() + self._allocated[epoch].add(datablock.data_path) diff --git a/fedlearner/trainer/estimator.py b/fedlearner/trainer/estimator.py index 1ed9d901e..584f522b7 100644 --- a/fedlearner/trainer/estimator.py +++ b/fedlearner/trainer/estimator.py @@ -22,9 +22,7 @@ from tensorflow_estimator.python.estimator import model_fn as model_fn_lib from fedlearner.common import fl_logging -from fedlearner.trainer.run_hooks import TraceStatsHook -from fedlearner.trainer._global_context import global_context as _gctx - +from fedlearner.privacy.splitnn.marvell import KL_gradient_perturb class FLModel(object): def __init__(self, role, bridge, example_ids, exporting=False): @@ -95,7 +93,10 @@ def minimize(self, aggregation_method=None, colocate_gradients_with_ops=False, name=None, - grad_loss=None): + grad_loss=None, + marvell_protection=False, + marvell_threshold=0.25, + labels=None): recv_grads = [i for i in self._recvs if i[2]] if var_list is None: @@ -115,6 +116,9 @@ def minimize(self, send_grads = grads_and_vars[:len(recv_grads)] for (n, _, _), (grad, _) in zip(recv_grads, send_grads): if grad is not None: + # Marvell:给即将发送的gradient添加噪声 + if marvell_protection and labels is not None: + grad = KL_gradient_perturb(grad, labels, marvell_threshold) self.send(n + '_grad', grad) if grads_and_vars[len(recv_grads):]: @@ -193,9 +197,6 @@ def train(self, input_fn): features, labels, tf.estimator.ModeKeys.TRAIN) hooks = [] - # stats - hooks.append(TraceStatsHook( - every_secs=30, stats_client=_gctx.stats_client)) # user define chief hook if spec.training_chief_hooks and self._is_chief: hooks.extend(spec.training_chief_hooks) @@ -262,6 +263,9 @@ def evaluate(self, input_fn): final_ops_hook = tf.train.FinalOpsHook(eval_dict) all_hooks.append(final_ops_hook) + if self._input_hooks: + all_hooks.extend(self._input_hooks) + session_creator = tf.train.WorkerSessionCreator( master=self._cluster_server.target, config=self._cluster_server.cluster_config) @@ -278,7 +282,6 @@ def evaluate(self, input_fn): fl_logging.debug("after session run. time: %f sec", use_time) self._bridge.terminate() - # Print result fl_logging.info('Metrics for evaluate: %s', _dict_to_str(final_ops_hook.final_ops_values)) diff --git a/fedlearner/trainer/feature.py b/fedlearner/trainer/feature.py index 5272f83a5..1e22bed65 100644 --- a/fedlearner/trainer/feature.py +++ b/fedlearner/trainer/feature.py @@ -147,12 +147,16 @@ def add_slice(self, dim): return sslice -class FeatureColumnV1(object): - def __init__(self, feature_slot): - self.name = 'slot_%d' % feature_slot.slot_id +class _FeatureColumn(object): + def __init__(self, fc_name, feature_slot): + self._name = fc_name self._feature_slot = feature_slot self._placeholder_slices = {} + @property + def name(self): + return self._name + @property def feature_slot(self): return self._feature_slot @@ -165,9 +169,20 @@ def get_vector(self, sslice): if sslice not in self._placeholder_slices: self._placeholder_slices[sslice] = tf.placeholder( - self._feature_slot._dtype, [None, sslice.len]) + self._feature_slot._dtype, [None, sslice.len] + ) return self._placeholder_slices[sslice] def add_vector(self, dim): return self.get_vector(self._feature_slot.add_slice(dim)) + + +class FeatureColumnV1(_FeatureColumn): + def __init__(self, feature_slot): + fc_name = 'slot_%d' % feature_slot.slot_id + super(FeatureColumnV1, self).__init__(fc_name, feature_slot) + + +class FeatureColumnV2(_FeatureColumn): + pass diff --git a/fedlearner/trainer/parameter_server.py b/fedlearner/trainer/parameter_server.py index f8be092df..1b70d42dd 100644 --- a/fedlearner/trainer/parameter_server.py +++ b/fedlearner/trainer/parameter_server.py @@ -19,7 +19,8 @@ import argparse import tensorflow.compat.v1 as tf -from fedlearner.common import stats + +from fedlearner.common.metric_collector import metric_collector from fedlearner.trainer.cluster_server import ClusterServer from fedlearner.trainer._global_context import global_context as _gctx @@ -32,8 +33,15 @@ args = parser.parse_args() _gctx.task = "ps" - stats.enable_cpu_stats(_gctx.stats_client) - stats.enable_mem_stats(_gctx.stats_client) + global_tags = { + 'task': _gctx.task, + 'task_index': str(_gctx.task_index), + 'node_name': os.environ.get('HOSTNAME', 'default_node_name'), + 'pod_name': os.environ.get('POD_NAME', 'default_pod_name'), + } + metric_collector.add_global_tags(global_tags) + name_prefix = 'model.common.nn_vertical' + metric_collector.emit_counter(f'{name_prefix}.start_count', 1) cluster_spec = tf.train.ClusterSpec({'ps': {0: args.address}}) cluster_server = ClusterServer(cluster_spec, "ps") diff --git a/fedlearner/trainer/run_hooks.py b/fedlearner/trainer/run_hooks.py index 31cecff2b..df674c6e0 100644 --- a/fedlearner/trainer/run_hooks.py +++ b/fedlearner/trainer/run_hooks.py @@ -14,7 +14,9 @@ import re import tensorflow.compat.v1 as tf -from tensorflow.python.training import training_util #pylint: disable=no-name-in-module +from tensorflow.python.training import training_util # pylint: disable=no-name-in-module +from fedlearner.common import metrics +from fedlearner.common.metric_collector import metric_collector from fedlearner.trainer._global_context import global_context as _gctx class GlobalStepMetricTensorHook(tf.train.SessionRunHook): @@ -85,13 +87,24 @@ def after_run(self, run_context, run_values): def _stats_metric(self, global_step, results): with self._stats_client.pipeline() as pipe: - pipe.gauge("trainer.metric_global_step", global_step) + name_prefix = 'model.train.nn_vertical' + metric_collector.emit_store( + f'{name_prefix}.global_step', global_step) for key in self._metric_names: value = results[key] pipe.gauge("trainer.metric_value", value.sum(), tags={"metric": key}) + # for compatibility, also write to metrics(es) + metrics.emit_store(name=key, value=value) + + metric_collector.emit_store( + f'{name_prefix}.{key}', value.sum()) + # for compatibility, also emit one with metric name in tags + metric_collector.emit_store(f'{name_prefix}.metric_value', + value.sum(), tags={'metric': key}) + class StepMetricsHook(GlobalStepMetricTensorHook): """ @@ -114,6 +127,7 @@ def __init__(self, loss_tensor, auc_tensor, every_n_iter=5, every_steps=every_n_iter) +# NOTE(whisylan): maybe lead to memory leak class TraceStatsHook(tf.train.SessionRunHook): def __init__(self, timing_topn=20, @@ -182,15 +196,24 @@ def _emit_stats(self, step_stats): events.append(ev) with self._stats_client.pipeline() as pipe: + # TODO(lixiaoguang.01) old version, to be deleted # emit op pipe.gauge("trainer.trace.op_count", len(events)) events.sort(key=lambda ev: ev["duration"], reverse=True) + # new version + name_prefix = 'model.trace.nn_vertical' + metric_collector.emit_store(f'{name_prefix}.op_count', len(events)) for ev in events[0:self._timing_topn]: if ev["duration"] < self._timing_min_ms: break pipe.timing("trainer.trace.op_timing", ev["duration"], tags={"op_name": ev["op_name"], "op": ev["op"]}) + metric_collector.emit_store( + f'{name_prefix}.op_timing', + ev["duration"], + {"op_name": ev["op_name"], "op": ev["op"]} + ) # emit memory events.sort(key=lambda ev: ev["output_bytes"], reverse=True) @@ -200,6 +223,11 @@ def _emit_stats(self, step_stats): pipe.gauge("trainer.trace.op_output_bytes", ev["output_bytes"], tags={"op_name": ev["op_name"], "op": ev["op"]}) + metric_collector.emit_store( + f'{name_prefix}.op_output_bytes', + ev["output_bytes"], + {"op_name": ev["op_name"], "op": ev["op"]} + ) def _parse_op_label(self, label): """ diff --git a/fedlearner/trainer/sparse_estimator.py b/fedlearner/trainer/sparse_estimator.py index c07faf396..f1451f96d 100644 --- a/fedlearner/trainer/sparse_estimator.py +++ b/fedlearner/trainer/sparse_estimator.py @@ -31,8 +31,7 @@ class SparseFLModel(estimator.FLModel): def __init__(self, role, bridge, example_ids, exporting=False, config_run=True, bias_tensor=None, vec_tensor=None, - bias_embedding=None, vec_embedding=None, - feature_columns=None): + bias_embedding=None, vec_embedding=None): super(SparseFLModel, self).__init__(role, bridge, example_ids, exporting) @@ -46,12 +45,11 @@ def __init__(self, role, bridge, example_ids, exporting=False, self._vec_tensor = vec_tensor self._bias_embedding = bias_embedding self._vec_embedding = vec_embedding - self._feature_columns = feature_columns self._frozen = False self._slot_ids = [] self._feature_slots = {} - self._feature_column_v1s = {} + self._feature_columns = {} self._use_fid_v2 = False self._num_embedding_groups = 3 @@ -75,9 +73,24 @@ def add_feature_column(self, *args, **kwargs): assert slot_id in self._feature_slots and \ self._feature_slots[slot_id] is fc.feature_slot, \ "FeatureSlot with id %d must be added to Model first"%slot_id - assert slot_id not in self._feature_column_v1s, \ - "Only one FeatureColumnV1 can be created for each slot" - self._feature_column_v1s[slot_id] = fc + assert slot_id not in self._feature_columns, \ + "Only one FeatureColumn can be created for each slot" + self._feature_columns[slot_id] = fc + return fc + + def add_feature_column_v1(self, *args, **kwargs): + self.add_feature_column(*args, **kwargs) + + def add_feature_column_v2(self, *args, **kwargs): + assert not self._frozen, "Cannot modify model after finalization" + fc = feature.FeatureColumnV2(*args, **kwargs) + slot_id = fc.feature_slot.slot_id + assert slot_id in self._feature_slots and \ + self._feature_slots[slot_id] is fc.feature_slot, \ + "FeatureSlot with id %d must be added to Model first"%slot_id + assert slot_id not in self._feature_columns, \ + "Only one FeatureColumn can be created for each slot" + self._feature_columns[slot_id] = fc return fc def set_use_fid_v2(self, use_fid_v2): @@ -123,9 +136,9 @@ def _get_vec_slot_configs(self): slot_list = [] fs_map = {} for slot_id in self._slot_ids: - if slot_id not in self._feature_column_v1s: + if slot_id not in self._feature_columns: continue - fc = self._feature_column_v1s[slot_id] + fc = self._feature_columns[slot_id] fs = fc.feature_slot if fc.feature_slot.dim > 1: key = (id(fs._vec_initializer), id(fs._vec_optimizer)) @@ -146,9 +159,6 @@ def _get_vec_slot_configs(self): vec_config['use_fid_v2'] = self._use_fid_v2 return vec_config - def get_feature_columns(self): - return self._feature_column_v1s - def freeze_slots(self, features): assert not self._frozen, "Already finalized" if self._config_run: @@ -172,7 +182,7 @@ def freeze_slots(self, features): placeholders = [] dims = [] for slot_id, _, _, _ in vec_config['slot_list']: - fc = self._feature_column_v1s[slot_id] + fc = self._feature_columns[slot_id] for sslice in fc.feature_slot.feature_slices: dims.append(sslice.len) placeholders.append(fc.get_vector(sslice)) @@ -256,7 +266,6 @@ def _set_model_configs(self, mode): #features, labels, mode): except ConfigRunError as e: self._bias_slot_configs = M._get_bias_slot_configs() self._vec_slot_configs = M._get_vec_slot_configs() - self._feature_columns = M.get_feature_columns() self._slot_configs = [self._bias_slot_configs, self._vec_slot_configs] return self._slot_configs @@ -305,8 +314,7 @@ def _get_model_spec(self, features, labels, mode): bias_tensor=bias_tensor, bias_embedding=bias_embedding, vec_tensor=vec_tensor, - vec_embedding=vec_embedding, - feature_columns=self._feature_columns) + vec_embedding=vec_embedding) spec = self._model_fn(model, features, labels, mode) assert model._frozen, "Please finalize model in model_fn" diff --git a/fedlearner/trainer/trainer_master.py b/fedlearner/trainer/trainer_master.py index 9291277f9..a72286ad8 100644 --- a/fedlearner/trainer/trainer_master.py +++ b/fedlearner/trainer/trainer_master.py @@ -18,6 +18,7 @@ import os import signal import time +from typing import Optional from concurrent import futures import threading import grpc @@ -27,11 +28,12 @@ from fedlearner.common import trainer_master_service_pb2 as tm_pb from fedlearner.common import trainer_master_service_pb2_grpc as tm_grpc from fedlearner.common import common_pb2 as common_pb +from fedlearner.common.metric_collector import metric_collector +from fedlearner.trainer.bridge import FakeBridge from fedlearner.trainer.estimator import FLEstimator from fedlearner.trainer.sparse_estimator import SparseFLEstimator from fedlearner.trainer.cluster_server import ClusterServer -from fedlearner.trainer._global_context import global_context as _gctx - +from fedlearner.common.hdfs_util import upload_to_mt_hdfs class ExportModelHook(): def after_save(self, sess, model, export_dir, inputs, outputs): @@ -87,13 +89,13 @@ def _trigger(self, global_step): self._last_triggered_step = global_step -#class _CheckpointSaverHook(tf.train.CheckpointSaverHook): -# def _save(self, session, step): -# if self._timer.last_triggered_step() is None: -# # skip save checkpoint -# fl_logging.info("skip save checkpoint") -# return False -# return super(_CheckpointSaverHook, self)._save(session, step) +class _CheckpointSaverHook(tf.train.CheckpointSaverHook): + def _save(self, session, step): + if self._timer.last_triggered_step() is None: + # skip save checkpoint + fl_logging.info("skip save checkpoint at first time") + return False + return super(_CheckpointSaverHook, self)._save(session, step) class _DataVisitorCheckpointHook(tf.train.SessionRunHook): @@ -145,29 +147,13 @@ def before_save(self, session, global_step_value): #fl_logging.info("data checkpoint saved result: %s", res) -class _FakeBridge(): - def send_op(self, name, x): - def func(x): - raise RuntimeError("Unexcepted call send op") - - out = tf.py_function(func=func, inp=[x], Tout=[], name='send_' + name) - return out - def receive_op(self, name, dtype): - def func(): - raise RuntimeError("Unexcepted call receive op") - - return tf.py_function(func=func, inp=[], Tout=[dtype])[0] - def register_data_block_handler(self, handler): - pass - - class _FakeTrainerMasterClient(): pass class _TrainerMaster(tm_grpc.TrainerMasterServiceServicer): def __init__(self, - cluster_server, + cluster_server: ClusterServer, role, mode, model_fn, @@ -182,7 +168,9 @@ def __init__(self, summary_save_secs=None, export_path=None, sparse_estimator=False, - export_model_hook=None): + export_model_hook=None, + export_model: Optional[bool] = None, + using_mt_hadoop: Optional[bool] = None): self._cluster_server = cluster_server self._role = role self._mode = mode @@ -199,6 +187,7 @@ def __init__(self, self._export_path = export_path self._sparse_estimator = sparse_estimator self._export_model_hook = export_model_hook + self._should_export_model = export_model self._lock = threading.RLock() self._status = tm_pb.MasterStatus.CREATED @@ -212,6 +201,8 @@ def __init__(self, self._worker0_terminated_at = 0 self._worker0_cluster_def = None + self.using_mt_hadoop = using_mt_hadoop + def _check_status(self, callback_fn): with self._lock: return callback_fn(self._status) @@ -282,7 +273,7 @@ def _create_estimator(self): if self._sparse_estimator else FLEstimator return estimator_factory( cluster_server=self._cluster_server, - bridge=_FakeBridge(), + bridge=FakeBridge(), trainer_master=_FakeTrainerMasterClient(), role=self._role, model_fn=self._model_fn) @@ -293,9 +284,11 @@ def _run(self): fl_logging.info("start session_run") self._session_run(estimator) fl_logging.info("session_run done") - fl_logging.info("start export_model") - self._export_model(estimator) - fl_logging.info("export_model done") + if self._should_export_model or \ + (self._mode == 'train' and self._should_export_model is None): + fl_logging.info("start export_model") + self._export_model(estimator) + fl_logging.info("export_model done") self._transfer_status(tm_pb.MasterStatus.WORKER_COMPLETED, tm_pb.MasterStatus.COMPLETED) @@ -322,7 +315,8 @@ def _session_run(self, estimator): hooks = self._session_hooks # saver hook - if mode_key == tf.estimator.ModeKeys.TRAIN \ + if (mode_key == tf.estimator.ModeKeys.TRAIN or + self._should_export_model) \ and self._checkpoint_path \ and (self._save_checkpoint_secs \ or self._save_checkpoint_steps): @@ -346,6 +340,7 @@ def _session_run(self, estimator): output_dir=self._summary_path, save_secs=self._summary_save_secs, save_steps=self._summary_save_steps, + scaffold=session_creator._scaffold, ) ) noop = tf.no_op() @@ -365,7 +360,6 @@ def _session_run(self, estimator): break time.sleep(0.2) - def _export_model(self, estimator): if self._export_path: export_path = os.path.join( @@ -385,6 +379,9 @@ def _export_model(self, estimator): tf.saved_model.simple_save(sess, export_path, receiver.receiver_tensors, spec.predictions, None) + if self.using_mt_hadoop: + upload_to_mt_hdfs(export_path) + upload_to_mt_hdfs(self._checkpoint_path) if self._export_model_hook: self._export_model_hook.after_save( sess, model, export_path, @@ -495,7 +492,9 @@ def __init__(self, summary_save_secs=None, export_path=None, sparse_estimator=False, - export_model_hook=None): + export_model_hook=None, + export_model: Optional[bool] = None, + using_mt_hadoop: Optional[bool] = None): super(LeaderTrainerMaster, self).__init__( cluster_server, "leader", @@ -512,16 +511,20 @@ def __init__(self, summary_save_secs, export_path, sparse_estimator, - export_model_hook) + export_model_hook, + export_model=export_model, + using_mt_hadoop=using_mt_hadoop + ) self._data_visitor = data_visitor self._last_global_step = -1 # datavisitor checkpoint hook - hook = _DataVisitorCheckpointHook(self._data_visitor) - self._add_checkpoint_listener( - hook.create_checkpoint_saver_listener()) - self._add_session_hook(hook) + if mode == 'train': + hook = _DataVisitorCheckpointHook(self._data_visitor) + self._add_checkpoint_listener( + hook.create_checkpoint_saver_listener()) + self._add_session_hook(hook) # trigger hook self._last_trigger_time = 0 @@ -530,38 +533,59 @@ def __init__(self, trigger_fn=self._trigger_fn) ) + # worker type: data source type + self._worker_data_source_map = { + tm_pb.WorkerType.REMOTE_WORKER: tm_pb.DataSourceType.JOINED, + tm_pb.WorkerType.LOCAL_WORKER: tm_pb.DataSourceType.LOCAL + } + def _trigger_fn(self, global_step): now = time.time() if self._last_global_step >= 0: speed = (global_step-self._last_global_step) \ / (now-self._last_trigger_time) - allocated_epoch, allocated_datablock = self._data_visitor.summary() - total_epoch, total_datablock = \ + allocated_epoch, allocated_datablock, allocated_local_datablock \ + = self._data_visitor.summary() + total_epoch, total_datablock, total_local_datablock = \ self._data_visitor.epoch_num, \ - self._data_visitor.datablock_size + self._data_visitor.datablock_size, \ + self._data_visitor.local_datablock_size fl_logging.info("global_step: %d, speed: %0.2f step/sec, " "epoch: %d/%d, datablock allocated: %d/%d, " + "local datablock allocated: %d/%d, " "worker: %d/%d(running/completed)", global_step, speed, allocated_epoch, total_epoch, allocated_datablock, total_datablock, + allocated_local_datablock, total_local_datablock, len(self._running_workers), len(self._completed_workers)) - with _gctx.stats_client.pipeline() as pipe: - pipe.gauge("trainer.global_step", global_step) - pipe.gauge("trainer.datablock_total", total_datablock) - pipe.gauge("trainer.datablock_allocated", allocated_datablock) - pipe.gauge("trainer.speed", speed) + name_prefix = f'model.{self._mode}.nn_vertical' + metric_collector.emit_store( + f'{name_prefix}.global_step', global_step) + metric_collector.emit_store( + f'{name_prefix}.datablock_total', total_datablock) + metric_collector.emit_store( + f'{name_prefix}.datablock_allocated', allocated_datablock) + metric_collector.emit_store( + f'{name_prefix}.local_datablock_total', + total_local_datablock + ) + metric_collector.emit_store( + f'{name_prefix}.local_datablock_allocated', + allocated_local_datablock + ) + metric_collector.emit_store(f'{name_prefix}.speed', speed) self._last_trigger_time = now self._last_global_step = global_step def _request_data_block(self, request): try: - data_block = next(self._data_visitor) + data_block = self._data_visitor.next_with_type( + self._worker_data_source_map[request.worker_type]) except StopIteration: data_block = None - response = tm_pb.DataBlockResponse() if data_block: fl_logging.info("allocated worker_%d with block: %s", request.worker_rank, @@ -599,7 +623,10 @@ def __init__(self, summary_save_secs=None, export_path=None, sparse_estimator=False, - export_model_hook=None): + export_model_hook=None, + export_model: Optional[bool] = None, + using_mt_hadoop: Optional[bool] = None + ): super(FollowerTrainerMaster, self).__init__( cluster_server, @@ -617,7 +644,10 @@ def __init__(self, summary_save_secs, export_path, sparse_estimator, - export_model_hook) + export_model_hook, + export_model=export_model, + using_mt_hadoop=using_mt_hadoop + ) self._data_visitor = data_visitor self._last_global_step = -1 @@ -635,17 +665,24 @@ def _trigger_fn(self, global_step): speed = (global_step-self._last_global_step) \ / (now-self._last_trigger_time) total_datablock = self._data_visitor.datablock_size + total_local_datablock = self._data_visitor.local_datablock_size fl_logging.info("global_step: %d, speed: %0.2f step/sec, " "datablock size: %d, " + "local datablock size: %d, " "worker: %d/%d(running/completed)", global_step, speed, total_datablock, + total_local_datablock, len(self._running_workers), len(self._completed_workers)) - with _gctx.stats_client.pipeline() as pipe: - pipe.gauge("trainer.global_step", global_step) - pipe.gauge("trainer.datablock_total", total_datablock) - pipe.gauge("trainer.speed", speed) + name_prefix = f'model.{self._mode}.nn_vertical' + metric_collector.emit_store( + f'{name_prefix}.global_step', global_step) + metric_collector.emit_store( + f'{name_prefix}.datablock_total', total_datablock) + metric_collector.emit_store( + f'{name_prefix}.local_datablock_total', total_local_datablock) + metric_collector.emit_store(f'{name_prefix}.speed', speed) self._last_trigger_time = now self._last_global_step = global_step diff --git a/fedlearner/trainer/trainer_master_client.py b/fedlearner/trainer/trainer_master_client.py index 732987dfc..81f921cce 100644 --- a/fedlearner/trainer/trainer_master_client.py +++ b/fedlearner/trainer/trainer_master_client.py @@ -26,16 +26,26 @@ class _TrainerMasterClient(object): - def __init__(self, client, worker_rank): + def __init__(self, client, worker_rank, + worker_type=tm_pb.WorkerType.REMOTE_WORKER): self._worker_rank = worker_rank self._client = client + self._worker_type = worker_type def request_data_block(self, block_id): request = tm_pb.DataBlockRequest( worker_rank=self._worker_rank, - block_id=block_id) + block_id=block_id, + worker_type=self._worker_type) response = _grpc_with_retry( lambda: self._client.RequestDataBlock(request)) + while response.status.code == \ + common_pb.StatusCode.STATUS_WAIT_FOR_DATA_BLOCK: + fl_logging.info("Sleep 5s to wait for data block of type %s", + self._worker_type) + time.sleep(5) + response = _grpc_with_retry( + lambda: self._client.RequestDataBlock(request)) if response.status.code == common_pb.StatusCode.STATUS_SUCCESS: fl_logging.debug("succeeded to get datablock, id:%s, data_path: %s", response.block_id, response.data_path) @@ -98,7 +108,7 @@ def wait_master_complete(self): class TrainerMasterClient(_TrainerMasterClient): - def __init__(self, address, worker_rank): + def __init__(self, address, worker_rank, worker_type): channel = make_insecure_channel( address, mode=ChannelType.INTERNAL, @@ -109,7 +119,8 @@ def __init__(self, address, worker_rank): ) ) client = tm_grpc.TrainerMasterServiceStub(channel) - super(TrainerMasterClient, self).__init__(client, worker_rank) + super(TrainerMasterClient, self).__init__(client, worker_rank, + worker_type) class LocalTrainerMasterClient(_TrainerMasterClient): diff --git a/fedlearner/trainer/trainer_worker.py b/fedlearner/trainer/trainer_worker.py index 4262f514f..caa5bf292 100644 --- a/fedlearner/trainer/trainer_worker.py +++ b/fedlearner/trainer/trainer_worker.py @@ -18,23 +18,29 @@ import threading import tensorflow.compat.v1 as tf -from fedlearner.common import fl_logging, stats -from fedlearner.trainer.bridge import Bridge +from fedlearner.common import fl_logging +from fedlearner.common.argparse_util import str_as_bool +from fedlearner.common import trainer_master_service_pb2 as tm_pb +from fedlearner.trainer.bridge import Bridge, FakeBridge +from fedlearner.common.metric_collector import metric_collector from fedlearner.trainer.estimator import FLEstimator from fedlearner.trainer.sparse_estimator import SparseFLEstimator from fedlearner.trainer.trainer_master_client \ import LocalTrainerMasterClient, TrainerMasterClient from fedlearner.trainer.trainer_master \ import LeaderTrainerMaster, FollowerTrainerMaster, ExportModelHook -from fedlearner.trainer.data_visitor import DataPathVisitor, DataSourceVisitor +from fedlearner.trainer.data_visitor import DataPathVisitor, \ + DataSourceVisitor, ShuffleType from fedlearner.trainer.cluster_server import ClusterServer from fedlearner.trainer._global_context import global_context as _gctx +from fedlearner.common.hdfs_util import get_local_temp_path, exists, mt_hadoop_download from fedlearner.trainer.run_hooks import StepLossAucMetricsHook, StepMetricsHook #pylint: disable=unused-import LEADER = "leader" FOLLOER = "follower" + def create_argument_parser(): parser = argparse.ArgumentParser(description='FedLearner Trainer.') parser.add_argument('--master', @@ -60,6 +66,10 @@ def create_argument_parser(): type=str, help='Address of peer\'s bridge, ' \ 'in [IP]:[PORT] format') + parser.add_argument('--server-port', + type=int, + default=None, + help='server port of tensorflow server, e.g. 50052') parser.add_argument('--cluster-spec', type=str, help='ClusterSpec description for master/ps/worker, '\ @@ -77,34 +87,60 @@ def create_argument_parser(): parser.add_argument('--data-source', type=str, help='path to data source for training') + parser.add_argument('--local-data-source', + type=str, + help='path to local data source for training') parser.add_argument('--data-path', type=str, help='path to data block files for training.' 'Ignore if data-source is set') + parser.add_argument('--local-data-path', + type=str, + help='path to local data block files for training.' + 'Ignore if local-data-source is set') + parser.add_argument('--data-path-wildcard', + type=str, + default='part-*', + help='file wildcard under data path for training.' + '* for any files') parser.add_argument('--start-date', type=int, help='training data start time') parser.add_argument('--end-date', type=int, help='training data end time') + parser.add_argument('--local-start-date', + type=int, + help='local training data start time') + parser.add_argument('--local-end-date', + type=int, + help='local training data end time') parser.add_argument('--epoch-num', type=int, default=1, help='number of epoch for training, not '\ 'support in online training') parser.add_argument('--shuffle', - type=bool, + type=str_as_bool, + default=False, const=True, nargs='?', help='shuffle the data block or not') + parser.add_argument('--shuffle-in-day', + type=bool, + help='shuffle the data block within a day or not') parser.add_argument('--export-path', type=str, help='Path to save exported models.') parser.add_argument('--checkpoint-path', type=str, - help='Path to save and load model checkpoints.') + help='path to save and load model checkpoints.') + parser.add_argument('--load-checkpoint-path', + type=str, + help='path to load model checkpoints.') parser.add_argument('--load-checkpoint-filename', type=str, help='filename to load model checkpoints, ' \ - 'Relative path to checkpoint-path') + 'relative path to load-checkpoint-path ' \ + 'or checkpoint-path') parser.add_argument('--load-checkpoint-filename-with-path', type=str, help='filename with path to load model checkpoints') @@ -125,18 +161,55 @@ def create_argument_parser(): type=int, help='Number of secs to save summary files.') parser.add_argument('--sparse-estimator', - type=bool, + type=str_as_bool, + default=False, const=True, nargs='?', help='Whether using sparse estimator.') parser.add_argument('--mode', type=str, default='train', help='Train or eval.') + parser.add_argument('--export-model', + type=str_as_bool, + default=None, nargs='?', + help='export model to export_path') parser.add_argument('--loglevel', type=str, default=None, help="Specify verbosity level. It can be one of " "'debug', 'info', 'warning', 'error', 'critical'") - + parser.add_argument('--extra-params', + type=str, + default=None, + help="extra params string for training") + parser.add_argument('--using_mt_hadoop', + type=str, + default=None, + help="use Meituan hadoop to get or upload data") + # 添加与label protection相关的参数 + parser.add_argument('--using_embedding_protection', + type=str_as_bool, + default='False', + help='Whether use embedding protection.') + parser.add_argument('--discorloss_weight', + type=str, + default='0.01', + help='Distance correlation weight.') + parser.add_argument('--using_marvell_protection', + type=str_as_bool, + default='False', + help='Whether use marvell protection.') + parser.add_argument('--sumkl_threshold', + type=str, + default='0.25', + help='Marvell sumKL threshold.') + parser.add_argument('--using_emb_attack', + type=str_as_bool, + default='False', + help='Whether use embedding attack.') + parser.add_argument('--using_norm_attack', + type=str_as_bool, + default='False', + help='Whether use norm attack.') return parser def _run_master(role, @@ -156,7 +229,35 @@ def _run_master(role, cluster_server = None if cluster_spec: - cluster_server = ClusterServer(cluster_spec, "master") + cluster_server = ClusterServer(cluster_spec, "master", + server_port=args.server_port) + + # use Meituan hadoop + # first:convert Meituan HDFS path to local storage path, if local exit psi result file, user local file + # second:if local not exit psi result file,from Meituan HDFS download to local + if args.using_mt_hadoop: + data_path = args.data_path + if data_path: + local_data_path = get_local_temp_path(data_path) + if not exists(local_data_path): + data_path = mt_hadoop_download(data_path) + else: + data_path = local_data_path + args.data_path = data_path + + checkpoint_path = args.checkpoint_path + if checkpoint_path: + args.checkpoint_path = get_local_temp_path(checkpoint_path) + + load_checkpoint_path = args.load_checkpoint_path + if load_checkpoint_path: + args.load_checkpoint_path = get_local_temp_path(load_checkpoint_path) + if not exists(args.load_checkpoint_path): + mt_hadoop_download(load_checkpoint_path) + + export_path = args.export_path + if export_path: + args.export_path = get_local_temp_path(export_path) checkpoint_filename_with_path = _get_checkpoint_filename_with_path(args) data_visitor = _create_data_visitor(args) @@ -179,34 +280,45 @@ def _run_master(role, summary_save_secs=args.summary_save_secs, export_path=args.export_path, sparse_estimator=args.sparse_estimator, - export_model_hook=export_model_hook) + export_model_hook=export_model_hook, + export_model=args.export_model, + using_mt_hadoop=args.using_mt_hadoop) master.run_forever(args.master_addr) def _run_worker(role, args, input_fn, model_fn): - if not args.local_addr: - raise ValueError("local-addr is required") - if not args.peer_addr: - raise ValueError("peer-addr is required") if not args.master_addr: raise ValueError("master-addr is required") mode = args.mode.lower() + worker_type = tm_pb.WorkerType.REMOTE_WORKER + if hasattr(args, "local_worker") and args.local_worker: + worker_type = tm_pb.WorkerType.LOCAL_WORKER + bridge = FakeBridge() + else: + if not args.local_addr: + raise ValueError("local-addr is required") + if not args.peer_addr: + raise ValueError("peer-addr is required") + bridge = Bridge(role, + int(args.local_addr.split(':')[1]), + args.peer_addr, + args.application_id, + args.worker_rank) + + fl_logging.info("Start worker rank %d with type %s", args.worker_rank, + worker_type) + cluster_spec = _create_cluster_spec(args, require_ps=True) cluster_server = ClusterServer(cluster_spec, "worker", - task_index=args.worker_rank) - + task_index=args.worker_rank, + server_port=args.server_port) trainer_master = TrainerMasterClient(args.master_addr, - args.worker_rank) + args.worker_rank, + worker_type) if not trainer_master.worker_register(cluster_spec.as_cluster_def()): return - bridge = Bridge(role, - int(args.local_addr.split(':')[1]), - args.peer_addr, - args.application_id, - args.worker_rank) - estimator_factory = SparseFLEstimator \ if args.sparse_estimator else FLEstimator estimator = estimator_factory(cluster_server, @@ -230,10 +342,6 @@ def _run_local(role, model_fn, serving_input_receiver_fn, export_model_hook=None): - if not args.local_addr: - raise ValueError("local-addr is required") - if not args.peer_addr: - raise ValueError("peer-addr is required") mode = args.mode.lower() cluster_spec = _create_cluster_spec(args) @@ -260,20 +368,29 @@ def _run_local(role, summary_save_secs=args.summary_save_secs, export_path=args.export_path, sparse_estimator=args.sparse_estimator, - export_model_hook=export_model_hook) + export_model_hook=export_model_hook, + export_model=args.export_model) master_thread = threading.Thread(target=local_master.run_forever) master_thread.setDaemon(True) master_thread.start() # run worker + if hasattr(args, "local_worker") and args.local_worker: + bridge = FakeBridge() + else: + if not args.local_addr: + raise ValueError("local-addr is required") + if not args.peer_addr: + raise ValueError("peer-addr is required") + bridge = Bridge(role, + int(args.local_addr.split(':')[1]), + args.peer_addr, + args.application_id, + 0) + trainer_master = LocalTrainerMasterClient(local_master, 0) if not trainer_master.worker_register(): return - bridge = Bridge(role, - int(args.local_addr.split(':')[1]), - args.peer_addr, - args.application_id, - 0) estimator_factory = \ SparseFLEstimator if args.sparse_estimator else FLEstimator @@ -293,18 +410,21 @@ def _run_local(role, def _get_checkpoint_filename_with_path(args): checkpoint_filename_with_path = None + if args.load_checkpoint_filename_with_path: checkpoint_filename_with_path = args.load_checkpoint_filename_with_path elif args.load_checkpoint_filename: - if not args.checkpoint_path: - raise ValueError("checkpoint_path is required " - "when provide checkpoint_filename") + load_checkpoint_path = args.load_checkpoint_path or args.checkpoint_path + if not load_checkpoint_path: + raise ValueError("load_checkpoint_path or checkpoint_path is " + "required when provide load_checkpoint_filename") checkpoint_filename_with_path = \ - os.path.join(args.checkpoint_path, args.checkpoint_filename) - elif args.checkpoint_path: + os.path.join(load_checkpoint_path, args.load_checkpoint_filename) + elif args.load_checkpoint_path or args.checkpoint_path: + load_checkpoint_path = args.load_checkpoint_path or args.checkpoint_path checkpoint_filename_with_path = \ - tf.train.latest_checkpoint(args.checkpoint_path) + tf.train.latest_checkpoint(load_checkpoint_path) if not checkpoint_filename_with_path: return None @@ -341,19 +461,37 @@ def _create_data_visitor(args): visitor = None start_date = int(args.start_date) if args.start_date else None end_date = int(args.end_date) if args.end_date else None + local_start_date = int(args.local_start_date) if args.local_start_date \ + else None + local_end_date = int(args.local_end_date) if args.local_end_date \ + else None + + shuffle_type = None + if args.shuffle: + shuffle_type = ShuffleType.ALL + elif args.shuffle_in_day: + shuffle_type = ShuffleType.DAY if args.data_source: visitor = DataSourceVisitor(args.data_source, start_date=start_date, end_date=end_date, + local_data_source=args.local_data_source, + local_start_date=local_start_date, + local_end_date=local_end_date, epoch_num=args.epoch_num, - shuffle=args.shuffle) - elif args.data_path: + shuffle_type=shuffle_type) + elif args.data_path and args.data_path_wildcard: visitor = DataPathVisitor(args.data_path, + args.local_data_path, + wildcard=args.data_path_wildcard, epoch_num=args.epoch_num, - shuffle=args.shuffle) + shuffle_type=shuffle_type, + start_date=start_date, + end_date=end_date) if not visitor: raise ValueError("cannot found any data to train, " - "please specify --data-source or --data-path") + "please specify [--data-source] or " + "[--data-path and --data-path-wildcard]") return visitor def train(role, @@ -392,8 +530,16 @@ def train(role, else: raise ValueError("duplication specify --master and --worker") - stats.enable_cpu_stats(_gctx.stats_client) - stats.enable_mem_stats(_gctx.stats_client) + global_tags = { + 'task': _gctx.task, + 'task_index': str(_gctx.task_index), + 'role': role.lower(), + 'node_name': os.environ.get('HOSTNAME', 'default_node_name'), + 'pod_name': os.environ.get('POD_NAME', 'default_pod_name'), + } + metric_collector.add_global_tags(global_tags) + name_prefix = f'model.{mode}.nn_vertical' + metric_collector.emit_counter(f'{name_prefix}.start_count', 1) if _gctx.task == "local": _run_local(role, args, input_fn, model_fn, diff --git a/fedlearner/trainer/utils.py b/fedlearner/trainer/utils.py index fca224c29..e47b858f4 100644 --- a/fedlearner/trainer/utils.py +++ b/fedlearner/trainer/utils.py @@ -19,6 +19,9 @@ from __future__ import division from __future__ import print_function +from datetime import datetime +from typing import Optional + import sys import numpy as np @@ -122,3 +125,12 @@ def _compute_slot_config(unsorted_slot_config, groups=None, use_fid_v2=False): 'slot_weight_offset': slot_weight_offset, 'output_size': offset } + + +def match_date(cur_date: datetime, start_date: Optional[datetime], + end_date: Optional[datetime]) -> bool: + if start_date and cur_date < start_date: + return False + if end_date and cur_date > end_date: + return False + return True diff --git a/protocols/fedlearner/common/common.proto b/protocols/fedlearner/common/common.proto index 5a11d0cd6..6f6e7b1b4 100644 --- a/protocols/fedlearner/common/common.proto +++ b/protocols/fedlearner/common/common.proto @@ -27,6 +27,7 @@ enum StatusCode { STATUS_MESSAGE_MISSING = 6; STATUS_INVALID_DATA_BLOCK = 7; STATUS_WAIT_FOR_SYNCING_CHECKPOINT = 8; + STATUS_WAIT_FOR_DATA_BLOCK = 9; } message Status { diff --git a/protocols/fedlearner/common/data_portal_service.proto b/protocols/fedlearner/common/data_portal_service.proto index 4c7236c71..3492a207e 100644 --- a/protocols/fedlearner/common/data_portal_service.proto +++ b/protocols/fedlearner/common/data_portal_service.proto @@ -109,6 +109,8 @@ message DataPotraMasterlOptions { bool check_success_tag = 3; bool single_subfolder = 4; int64 files_per_job_limit = 5; + string start_date = 6; + string end_date = 7; } message DataPortalWorkerOptions { diff --git a/protocols/fedlearner/common/trainer_master_service.proto b/protocols/fedlearner/common/trainer_master_service.proto index 77cc88da9..737bec660 100644 --- a/protocols/fedlearner/common/trainer_master_service.proto +++ b/protocols/fedlearner/common/trainer_master_service.proto @@ -27,9 +27,20 @@ enum MasterStatus { COMPLETED = 4; } +enum DataSourceType { + JOINED = 0; + LOCAL = 1; +} + +enum WorkerType { + REMOTE_WORKER = 0; + LOCAL_WORKER = 1; +} + message DataBlockRequest { uint32 worker_rank = 1; string block_id = 2; + WorkerType worker_type = 3; }; message DataBlockResponse { diff --git a/requirements.txt b/requirements.txt index f96fb4bd3..5576303ef 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ -tensorflow==2.4.2 -tensorflow_io==0.17.1 setuptools==41.0.0 +cityhash pylint==2.4.4 jinja2 grpcio-tools etcd3 +influxdb peewee apsw configparser @@ -12,6 +12,7 @@ prettytable kubernetes scipy gmpy2 +cityhash scikit-learn pycryptodomex rsa @@ -21,8 +22,25 @@ guppy3 psutil sqlalchemy==1.2.19 mysqlclient +leveldb prison==0.1.3 matplotlib -leveldb -pytz -cityhash +flatten_dict +pyspark==3.0.2 +pandas==1.1.5 +opentelemetry-api==1.10.0 +opentelemetry-sdk==1.10.0 +opentelemetry-exporter-otlp==1.10.0 + +# for meituan hadoop +requests==2.25.1 +pytz==2021.1 +krb5==0.3.0 +gssapi==1.7.3 +requests-kerberos==0.14.0 +hdfs==2.7.0 +docopt==0.6.2 +pyspnego==0.5.4 +cryptography==40.0.2 +decorator==5.1.1 +fsspec==2022.1.0 diff --git a/setup.py b/setup.py index 113024365..fc7f33313 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup, find_packages import time -with open("README.md", "r") as fh: +with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read() with open('requirements.txt') as f: @@ -11,8 +11,7 @@ def get_version(): base = "1.5" - day = time.strftime('%Y%m%d', time.localtime()) - return '%s-dev%s'%(base, day) + return '%s-dev' % base setup( name='fedlearner', diff --git a/sgx/README.md b/sgx/README.md index 372be46da..58880eb65 100644 --- a/sgx/README.md +++ b/sgx/README.md @@ -1,35 +1,258 @@ -# MNIST - -This directory contains steps and artifacts to run a MNIST sample workload on -Graphene. - -# Build docker image and start container - -``` -cp build_docker_image.sh ../ && cd .. -./build_docker_image.sh ${tag} - -cd sgx -./start_container.sh ${tag} -``` - -# Run in container - -## Solo Mode -``` -cd /graphene/Examples/mnist -test-sgx.sh data -test-sgx.sh leader -``` - -open another terminal and execute -``` -test-sgx follower -``` - -## Distributed Mode - - -# Feature Not Included - -* tensorflow-io, imported by fedlearner but not installed, mocked by `sgx/tenorflow_io.py` +# Vertical Federated Learning + +## Background + +With the increasing concerns on data security and user privacy in machine learning, federated learning becomes a promising solution to privacy and security challenges. Federated Learning can be classified into Vertical Federated Learning, Horizontal Federated Learning, Federated Transfer Learning (FTL) according to how sensitive data are distributed among participating parties. + +Federated Learning usually adopts three major technologies in protecting privacy: Differential Privacy (DP), Homomorphic Encryption (HE) and Muti-Party Computation (MPC). The privacy protection technologies that are adopted in deep neural networks are DP and MPC and TEE (Trusted Executing Environment). +This solution presents an innovative way to presents an secure enhanced Vertical Federated Learning by integrating Intel SGX technology. + +Vertical Federated Learning assumes that the data are partitioned by different features (including labels). A typical scenario of Vertical Federated Learning is including two parts: online reference and offline training. When an online media platform A displays ads of an e-commerce company B to its users and charges B for each conversion (e.g., user clicking the ad and buying the product). + +![vertical FL](./imgs/vfl.png) + +During offline training, active party and passive party , both parties use the example_id recorded online to align the data and label, and then read the data in the order of alignment. The model is divided into two parts. The passive party inputs the data into the first half, obtains the intermediate result (embedding) and then sends it to active party. Active party calculates the second half of the model, then use the label they record to calculate the loss and gradient, and then pass the gradient back to the passive party. Finally, the active party and passive party update their models. + +## Introduction + +In this solution, it focuses on online training part and the main involved modules are as below: + +- AI Framework – [Fedlearner](https://github.com/bytedance/fedlearner/tree/fix_dev_sgx), a Bytedance end-to-end open-source framework, based on TensorFlow, for machine learning, providing interfaces that facilitate federated learning tasks. + +- Security Isolation LibOS – [Gramine](https://github.com/gramineproject/gramine), an open-source project for Intel SGX, run applications in an isolated environment with no modification in Intel SGX. +- Containerization using Docker - The framework of this solution is built in Docker and can be automating deployment, management of containerized with Kubernetes. +- Runtime Security - AI framework Fedlearner will run into Intel SGX Enclave, which offers hardware-based memory encryption that isolates specific application code and data in memory. + +- Model Protection - Protecting the confidentiality and integrity of the model by encryption when training takes place on an untrusted platform. + +- Data Protection - Establishing a secure communication link ([RA-TLS enhanced gRPC](https://cczoo.readthedocs.io/en/latest/Solutions/grpc-ra-tls/index.html)) from parameter server to worker and worker to worker. + +- Platform Integrity - Providing Remote Attestation mechanism when workers begins to communicate with each other during the handshake. Please refer to [RA-TLS enhanced gRPC](https://cczoo.readthedocs.io/en/latest/Solutions/grpc-ra-tls/index.html) for more details. + + + +![Vertical FL with SGX](./imgs/vfl_with_sgx.png) + +Usually, there are two roles during model training - parameter server and workers. Each worker computes the gradient of the loss on its portion of the data, and then a parameter server sums each worker’s gradient to yield the full mini-batch gradient. After using this gradient to update the model parameters, the parameter server must send back the updated weights to the worker. Workers from active party and passive party will transfer labels and gradients via gRPC. + +**Runtime security with Intel SGX** + +Intel SGX allows user-level code to allocate private regions of memory, called Enclaves, which are designed to be protected from processes running at higher privilege levels. It also helps protect against SW attacks even if OS/drivers/BIOS/VMM/SMM are compromised and helps increase protections for secrets even when attacker has full control of platform. In this solution, parameter server and worker are both running SGX Enclave smoothly with the help of LibOS Gramine. + +**Attestation and Authentication** + +In this solution, when two workers build the connection via gRPC, before the communication channel establish successfully, the workers will verify each other with two parts: remote attestation and identity authentication. + +In remote attestation, generally the attesting SGX enclave collects attestation evidence in the form of an SGX Quote using the Quoting Enclave. This form of attestation is used to gain the remote partner's trust by sending the attestation evidence to a remote party (not on the same physical machine). + +When workers begin the communication via gRPC, the SGX Quote will be integrated in TLS and verified in the other worker side by the preinstalled Intel SGX DCAP package in the container. + +Besides the verification of the Enclave, it also checks the identity information (`mr_enclave`,`mr_signer`,`isv_prod_id`,`isv_svn`) of the Enclave which excludes the possibility of authenticating them via a user identity. + +Once the verification and identity check pass, the communication channel between workers will be built successfully. More details please refer to [RA-TLS enhanced gRPC](https://cczoo.readthedocs.io/en/latest/Solutions/grpc-ra-tls/index.html). + +**Data at-rest security** + +We encrypt models with cryptographic (wrap) key by using Protected-File mode in LibOS Gramine to guarantee the integrity of the model file by metadata checking method. Any changes of the model will have a different hash code, which will be denied by Gramine . + + + +## Prerequisites + +- Ubuntu 18.04. This solution should work on other Linux distributions as well, but for simplicity we provide the steps for Ubuntu 18.04 only. + +- Docker Engine. Docker Engine is an open source containerization technology for building and containerizing your applications. In this solution, Gramine, Fedlearner, gRPC will be built in Docker images. Please follow [this guide](https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script) to install Docker engine. + +- SGX capable platform. Intel SGX Driver and SDK/PSW. You need a machine that supports Intel SGX and FLC/DCAP. Please follow [this guide](https://download.01.org/intel-sgx/latest/linux-latest/docs/) to install the Intel SGX driver and SDK/PSW. One way to verify SGX enabling status in your machine is to run [QuoteGeneration](https://github.com/intel/SGXDataCenterAttestationPrimitives/blob/master/QuoteGeneration) and [QuoteVerification](https://github.com/intel/SGXDataCenterAttestationPrimitives/blob/master/QuoteVerification) successfully. + +Here, we will demonstrate how to run leader and follower from two containers. + + + +## Executing Fedlearner in SGX + +### 1. Download source code + +``` +git clone -b fix_dev_sgx https://github.com/bytedance/fedlearner.git +cd fedlearner +git submodule init +git submodule update +``` + +### 2. Build Docker image + +``` +img_tag=Your_defined_tag +./sgx/build_dev_docker_image.sh ${img_tag} +``` + +*Note:* `build_dev_docker_image.sh` provides parameter `proxy_server` to help you set your network proxy. It can be removed from this script if it is not needed. + +You will get the built image: + +``` +REPOSITORY TAG IMAGE ID CREATED SIZE +fedlearner-sgx-dev latest 8c3c7a05f973 45 hours ago 15.2GB +``` + +### 3. Start Container + +In terminal 1, start container to run leader: + +``` +docker run -it \ + --name=fedlearner_leader \ + --restart=unless-stopped \ + -p 50051:50051 \ + --device=/dev/sgx_enclave:/dev/sgx/enclave \ + --device=/dev/sgx_provision:/dev/sgx/provision \ + fedlearner-sgx-dev:latest \ + bash +``` + +In terminal 2, start container to run follower: + +``` +docker run -it \ + --name=fedlearner_follwer \ + --restart=unless-stopped \ + -p 50052:50052 \ + --device=/dev/sgx_enclave:/dev/sgx/enclave \ + --device=/dev/sgx_provision:/dev/sgx/provision \ + fedlearner-sgx-dev:latest \ + bash +``` + +#### 3.1 Configure PCCS + +- If you are using public cloud instance, please replace the pccs url in `/etc/sgx_default_qcnl.conf` with the new pccs url provided by the cloud. + + ``` + Old: PCCS_URL=https://pccs.service.com:8081/sgx/certification/v3/ + New: PCCS_URL=https://public_cloud_pccs_url + ``` + +- If you are using your own machine, please make sure, the PCCS service is running successfully in your host with command `systemctl status pccs`. And add your host IP address in `/etc/hosts` under container. For example: + + ``` + cat /etc/hosts + XXX.XXX.XXX.XXX pccs.service.com #XXX.XXX.XXX.XXX is the host IP + ``` + +#### 3.2 Start aesm service + +Execute below script in both leader and follower container: + +``` +/root/start_aesm_service.sh +``` + +#### 4. Prepare data + +Generate data in both leader and follower container: + +``` +cd /gramine/CI-Examples/wide_n_deep +./test-ps-sgx.sh data +``` + +#### 5. Compile applications + +Compile applications in both leader and follower container: + +``` +cd /gramine/CI-Examples/wide_n_deep +./test-ps-sgx.sh make +``` + +Please find `mr_enclave`,`mr_signer` from the print log as below: + +``` ++ make ++ grep 'mr_enclave\|mr_signer\|isv_prod_id\|isv_svn' + isv_prod_id: 0 + isv_svn: 0 + mr_enclave: bda462c6483a15f18c92bbfd0acbb61b9702344202fcc6ceed194af00a00fc02 + mr_signer: dbf7a340bbed6c18345c6d202723364765d261fdb04e960deb4ca894d4274839 + isv_prod_id: 0 + isv_svn: 0 +``` + +Then, update the leader's `dynamic_config.json` under current folder with follower's `mr_enclave`,`mr_signer`. Also, update follower's `dynamic_config.json` with leader's `mr_enclave`,`mr_signer`. + +``` +dynamic_config.json: +{ +...... + "sgx_mrs": [ + { + "mr_enclave": "", + "mr_signer": "", + "isv_prod_id": "0", + "isv_svn": "0" + } + ], +...... +} + +``` + +#### 6. Config leader and follower's IP + +In leader's `test-ps-sgx.sh`, for `--peer-addr` , please replace `localhost` with `follower_contianer_ip` + +``` +elif [ "$ROLE" == "leader" ]; then + make_custom_env + rm -rf model/leader + ...... + taskset -c 4-7 stdbuf -o0 gramine-sgx python -u leader.py \ + --local-addr=localhost:50051 \ + --peer-addr=follower_contianer_ip:50052 +``` + +In follower's `test-ps-sgx.sh`, for `--peer-addr` , please replace `localhost` with `leader_contianer_ip` + +``` +elif [ "$ROLE" == "follower" ]; then + make_custom_env + rm -rf model/follower + ...... + taskset -c 12-15 stdbuf -o0 gramine-sgx python -u follower.py \ + --local-addr=localhost:50052 \ + --peer-addr=leader_container_ip:50051 +``` + +*Note:* Get the container ip under your host: + +``` +docker inspect --format '{{ .NetworkSettings.IPAddress }}' contianer_id +``` + +#### 7.Run the distributing training + +Under leader container: + +``` +cd /gramine/CI-Examples/wide_n_deep +./test-ps-sgx.sh leader +``` + +Under follower container: + +``` +cd /gramine/CI-Examples/wide_n_deep +./test-ps-sgx.sh follower +``` + +Finally, the model file will be placed at + +``` +./model/leader/id/save_model.pd +``` + +``` +./model/follower/id/save_model.pd +``` + diff --git a/sgx/build_docker_image.sh b/sgx/build_dev_docker_image.sh similarity index 52% rename from sgx/build_docker_image.sh rename to sgx/build_dev_docker_image.sh index 0bf7ab8db..f5f630466 100755 --- a/sgx/build_docker_image.sh +++ b/sgx/build_dev_docker_image.sh @@ -2,19 +2,24 @@ set -e if [ ! -n "$1" ] ; then - tag=latest + image_tag=latest else - tag=$1 + image_tag=$1 fi +cd `dirname "$0"`/.. + # You can remove build-arg http_proxy and https_proxy if your network doesn't need it -#no_proxy="localhost,127.0.0.0/1" -proxy_server="http://child-prc.intel.com:913" +no_proxy="localhost,127.0.0.1" +proxy_server="http://test-proxy:port" DOCKER_BUILDKIT=0 docker build \ - -f fedlearner-sgx-dev.dockerfile . \ - -t fedlearner-sgx-dev:${tag} \ + -f fedlearner-sgx-dev.dockerfile \ + -t fedlearner-sgx-dev:${image_tag} \ --network=host \ --build-arg http_proxy=${proxy_server} \ --build-arg https_proxy=${proxy_server} \ - --build-arg no_proxy=${no_proxy} + --build-arg no_proxy=${no_proxy} \ + . + +cd - diff --git a/sgx/build_release_docker_image.sh b/sgx/build_release_docker_image.sh new file mode 100755 index 000000000..300db9bc9 --- /dev/null +++ b/sgx/build_release_docker_image.sh @@ -0,0 +1,32 @@ +#!/bin/bash +set -e + +if [ ! -n "$1" ] ; then + image_tag=latest +else + image_tag=$1 +fi + +if [ ! -n "$2" ] ; then + base_image=fedlearner-sgx-dev:latest +else + base_image=$2 +fi + +cd `dirname "$0"`/.. + +# You can remove build-arg http_proxy and https_proxy if your network doesn't need it +no_proxy="localhost,127.0.0.1" +proxy_server="http://test-proxy:port" + +DOCKER_BUILDKIT=0 docker build \ + -f fedlearner-sgx-release.dockerfile \ + -t fedlearner-sgx-release:${image_tag} \ + --network=host \ + --build-arg base_image=${base_image} \ + --build-arg http_proxy=${proxy_server} \ + --build-arg https_proxy=${proxy_server} \ + --build-arg no_proxy=${no_proxy} \ + . + +cd - diff --git a/sgx/configs/etc/apt/sources.list b/sgx/configs/etc/apt/sources.list deleted file mode 100644 index 4f1da838c..000000000 --- a/sgx/configs/etc/apt/sources.list +++ /dev/null @@ -1,14 +0,0 @@ -deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse - -deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse - -deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse - -deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse - -deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse diff --git a/sgx/fedlearner/build_install.sh b/sgx/fedlearner/build_install.sh deleted file mode 100755 index beb5ff13b..000000000 --- a/sgx/fedlearner/build_install.sh +++ /dev/null @@ -1,16 +0,0 @@ -set -e - -cd ${FEDLEARNER_PATH} - -make protobuf -make op - -rm -rf dist -python3 setup.py bdist_wheel - -pip3 uninstall -y fedlearner -pip3 install ./dist/*.whl -mkdir -p /usr/local/lib/python3.6/dist-packages/cc -cp ./cc/embedding.so /usr/local/lib/python3.6/dist-packages/cc - -cd - diff --git a/sgx/fedlearner/setup.py b/sgx/fedlearner/setup.py deleted file mode 100644 index 53686fece..000000000 --- a/sgx/fedlearner/setup.py +++ /dev/null @@ -1,33 +0,0 @@ -import os -import os -import platform -from setuptools import setup, find_packages -import time - -with open("README.md", "r", encoding="utf-8") as fh: - long_description = fh.read() - -with open('requirements.txt') as f: - required = f.read().splitlines() - -def get_version(): - base = "1.5" - day = time.strftime('%Y%m%d', time.localtime()) - return '%s-dev%s'%(base, day) - -setup( - name='fedlearner', - version=get_version(), - packages=find_packages(), - include_package_data=True, - author='Fedlearner Contributors', - long_description=long_description, - long_description_content_type="text/markdown", - install_requires=required, - classifiers=[ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: Apache Software License", - "Operating System :: MacOS", - "Operating System :: POSIX :: Linux" - ], -) \ No newline at end of file diff --git a/sgx/gramine/CI-Examples/.gitignore b/sgx/gramine/CI-Examples/.gitignore new file mode 100644 index 000000000..44da5dd64 --- /dev/null +++ b/sgx/gramine/CI-Examples/.gitignore @@ -0,0 +1 @@ +grpc-* diff --git a/sgx/gramine/CI-Examples/generate-token/Makefile b/sgx/gramine/CI-Examples/generate-token/Makefile new file mode 100644 index 000000000..e10d9635e --- /dev/null +++ b/sgx/gramine/CI-Examples/generate-token/Makefile @@ -0,0 +1,48 @@ +################################# CONSTANTS ################################### + +GRAMINEDIR ?= ../.. +SGX_SIGNER_KEY ?= $(GRAMINEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem + +ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) + +ifeq ($(DEBUG),1) +GRAPHENE_LOG_LEVEL = debug +else +GRAPHENE_LOG_LEVEL = error +endif + +.PHONY: all +all: python.manifest +ifeq ($(SGX),1) +all: python.manifest python.manifest.sgx python.sig python.token +endif + +################################ fedlearner MANIFEST ############################### + +python.manifest: python.manifest.template + gramine-manifest \ + -Dentrypoint=$(realpath $(shell sh -c "command -v python3")) \ + -Darch_libdir=$(ARCH_LIBDIR) \ + -Dlog_level=$(GRAPHENE_LOG_LEVEL) \ + $< >$@ + +python.manifest.sgx: python.manifest + gramine-sgx-sign \ + --key $(SGX_SIGNER_KEY) \ + --manifest $< \ + --output $@ + +python.sig: python.manifest.sgx + +python.token: python.sig + gramine-sgx-get-token --output $@ --sig $< + +################################## CLEANUP #################################### + +.PHONY: clean +clean: + $(RM) *.token *.sig *.manifest.sgx *.manifest + $(RM) -r scripts/__pycache__ + +.PHONY: distclean +distclean: clean diff --git a/sgx/gramine/CI-Examples/generate-token/generate.sh b/sgx/gramine/CI-Examples/generate-token/generate.sh new file mode 100755 index 000000000..529666ec8 --- /dev/null +++ b/sgx/gramine/CI-Examples/generate-token/generate.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -x + +shopt -s expand_aliases +alias make_logfilter="grep -v 'measured'" +alias runtime_logfilter="grep -v 'FUTEX|measured|memory entry|cleaning up|async event|shim_exit'" + +rm -rf *.log +make clean && make | make_logfilter diff --git a/sgx/gramine/CI-Examples/generate-token/python.manifest.template b/sgx/gramine/CI-Examples/generate-token/python.manifest.template new file mode 100644 index 000000000..346b51366 --- /dev/null +++ b/sgx/gramine/CI-Examples/generate-token/python.manifest.template @@ -0,0 +1,616 @@ +libos.entrypoint = "{{ entrypoint }}" +libos.check_invalid_pointers = false + +loader.preload = "file:{{ gramine.libos }}" +loader.log_level = "none" +loader.entrypoint = "file:{{ gramine.libos }}" + +loader.pal_internal_mem_size = "200M" + +loader.insecure__use_cmdline_argv = true +loader.insecure__use_host_env = true +loader.insecure_disable_aslr = true +sgx.allow_file_creation = true +sgx.static_address = 1 + +loader.env.LD_LIBRARY_PATH = "/opt/meituan/hadoop/lib/native:/opt/tiger/jdk/openjdk-1.8.0_265/jre/lib/amd64/server:/opt/meituan/hadoop/lib/native:/opt/meituan/hadoop/lib/native/nfs:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server:/usr/local/lib/x86_64-linux-gnu:/opt/tiger/yarn_deploy/hadoop_current/lib/native:/opt/tiger/jdk/openjdk-1.8.0_265/jre/lib/amd64/server:/opt/tiger/jdk/openjdk-1.8.0_265/jre/lib/amd64/jli/:/opt/tiger/jdk/openjdk-1.8.0_265/jre/lib/amd64:{{ python.stdlib }}/lib:/lib:{{ arch_libdir }}:/usr/local/lib:/usr/local/{{ arch_libdir }}:/usr/lib:/usr/{{ arch_libdir }}" +loader.env.SECRET_PROVISION_CONSTRUCTOR = "1" +loader.env.SECRET_PROVISION_SET_PF_KEY = "1" + +sys.enable_sigterm_injection = true +sys.enable_extra_runtime_domain_names_conf = true +sgx.ioctl_structs.ifconf = [ {name = "ifc_len",size = 4, direction = "inout" }, {size = 4}, { ptr=[ {size= "ifc_len", direction = "in"} ] } ] +sgx.ioctl_structs.ifreq = [ { name ="ifreq", size=40, direction ="inout"} ] +sgx.allowed_ioctls = [ + { request_code = 0x8912, struct = "ifconf"}, + { request_code = 0x8927, struct = "ifreq"}, +] + +fs.mounts = [ + { path = "/lib", uri = "file:{{ gramine.runtimedir() }}" }, + { path = "{{ arch_libdir }}", uri = "file:{{ arch_libdir }}" }, + { path = "/usr", uri = "file:/usr" }, + { path = "{{ python.stdlib }}", uri = "file:{{ python.stdlib }}" }, + { path = "{{ python.distlib }}", uri = "file:{{ python.distlib }}" }, + { path = "/opt", uri = "file:/opt" }, + { path = "/gramine/leader", uri = "file:/gramine/leader"}, + { path = "/gramine/follower", uri = "file:/gramine/follower"}, + { path = "/etc", uri = "file:/etc" }, + { path = "/tmp", uri = "file:/tmp" }, + { path = "/bin", uri = "file:/bin" }, + { path = "/data", uri = "file:/data" }, + { path = "/proc/net", uri = "file:/proc/net" }, + { path = "/proc/stat", uri = "file:/proc/stat" }, + { path = "/proc/self/cmdline", uri = "file:/proc/self/cmdline" }, + { path = "/root/.keras/keras.json", uri = "file:/root/.keras/keras.json" } +] + +# Note that Gramine also creates an internal +# thread for handling inter-process communication (IPC), and potentially another +# thread for asynchronous events. Therefore, the actual number of threads that +# the application can create is (sgx.thread_num - 2). + +sgx.debug = false +sgx.remote_attestation = "dcap" +sgx.preheat_enclave = false +sgx.nonpie_binary = true +sgx.enable_stats = false +sgx.enclave_size = "8G" +sgx.thread_num = 256 +sgx.rpc_thread_num = 0 +sgx.protected_files_key = "ffeeddccbbaa99887766554433221100" + +sgx.trusted_files = [ + "file:{{ entrypoint }}", + "file:{{ gramine.runtimedir() }}/", + "file:{{ arch_libdir }}/", + "file:/usr/{{ arch_libdir }}/", + "file:/etc/ssl/certs/ca-certificates.crt", + "file:/etc/default/apport", + "file:/etc/mime.types", + "file:/gramine/leader/", + "file:/gramine/follower/", + "file:/usr/local/lib/cmake/", + "file:/usr/local/lib/libabsl_bad_any_cast_impl.a", + "file:/usr/local/lib/libabsl_bad_optional_access.a", + "file:/usr/local/lib/libabsl_bad_variant_access.a", + "file:/usr/local/lib/libabsl_base.a", + "file:/usr/local/lib/libabsl_city.a", + "file:/usr/local/lib/libabsl_civil_time.a", + "file:/usr/local/lib/libabsl_cord.a", + "file:/usr/local/lib/libabsl_debugging_internal.a", + "file:/usr/local/lib/libabsl_demangle_internal.a", + "file:/usr/local/lib/libabsl_examine_stack.a", + "file:/usr/local/lib/libabsl_exponential_biased.a", + "file:/usr/local/lib/libabsl_failure_signal_handler.a", + "file:/usr/local/lib/libabsl_flags.a", + "file:/usr/local/lib/libabsl_flags_commandlineflag.a", + "file:/usr/local/lib/libabsl_flags_commandlineflag_internal.a", + "file:/usr/local/lib/libabsl_flags_config.a", + "file:/usr/local/lib/libabsl_flags_internal.a", + "file:/usr/local/lib/libabsl_flags_marshalling.a", + "file:/usr/local/lib/libabsl_flags_parse.a", + "file:/usr/local/lib/libabsl_flags_private_handle_accessor.a", + "file:/usr/local/lib/libabsl_flags_program_name.a", + "file:/usr/local/lib/libabsl_flags_reflection.a", + "file:/usr/local/lib/libabsl_flags_usage.a", + "file:/usr/local/lib/libabsl_flags_usage_internal.a", + "file:/usr/local/lib/libabsl_graphcycles_internal.a", + "file:/usr/local/lib/libabsl_hash.a", + "file:/usr/local/lib/libabsl_hashtablez_sampler.a", + "file:/usr/local/lib/libabsl_int128.a", + "file:/usr/local/lib/libabsl_leak_check.a", + "file:/usr/local/lib/libabsl_leak_check_disable.a", + "file:/usr/local/lib/libabsl_log_severity.a", + "file:/usr/local/lib/libabsl_malloc_internal.a", + "file:/usr/local/lib/libabsl_periodic_sampler.a", + "file:/usr/local/lib/libabsl_random_distributions.a", + "file:/usr/local/lib/libabsl_random_internal_distribution_test_util.a", + "file:/usr/local/lib/libabsl_random_internal_platform.a", + "file:/usr/local/lib/libabsl_random_internal_pool_urbg.a", + "file:/usr/local/lib/libabsl_random_internal_randen.a", + "file:/usr/local/lib/libabsl_random_internal_randen_hwaes.a", + "file:/usr/local/lib/libabsl_random_internal_randen_hwaes_impl.a", + "file:/usr/local/lib/libabsl_random_internal_randen_slow.a", + "file:/usr/local/lib/libabsl_random_internal_seed_material.a", + "file:/usr/local/lib/libabsl_random_seed_gen_exception.a", + "file:/usr/local/lib/libabsl_random_seed_sequences.a", + "file:/usr/local/lib/libabsl_raw_hash_set.a", + "file:/usr/local/lib/libabsl_raw_logging_internal.a", + "file:/usr/local/lib/libabsl_scoped_set_env.a", + "file:/usr/local/lib/libabsl_spinlock_wait.a", + "file:/usr/local/lib/libabsl_stacktrace.a", + "file:/usr/local/lib/libabsl_status.a", + "file:/usr/local/lib/libabsl_statusor.a", + "file:/usr/local/lib/libabsl_str_format_internal.a", + "file:/usr/local/lib/libabsl_strerror.a", + "file:/usr/local/lib/libabsl_strings.a", + "file:/usr/local/lib/libabsl_strings_internal.a", + "file:/usr/local/lib/libabsl_symbolize.a", + "file:/usr/local/lib/libabsl_synchronization.a", + "file:/usr/local/lib/libabsl_throw_delegate.a", + "file:/usr/local/lib/libabsl_time.a", + "file:/usr/local/lib/libabsl_time_zone.a", + "file:/usr/local/lib/libabsl_wyhash.a", + "file:/usr/local/lib/libaddress_sorting.a", + "file:/usr/local/lib/libcares.a", + "file:/usr/local/lib/libcjson.a", + "file:/usr/local/lib/libcjson_utils.a", + "file:/usr/local/lib/libcrypto.a", + "file:/usr/local/lib/libgpr.a", + "file:/usr/local/lib/libgrpc++.a", + "file:/usr/local/lib/libgrpc++_alts.a", + "file:/usr/local/lib/libgrpc++_error_details.a", + "file:/usr/local/lib/libgrpc++_reflection.a", + "file:/usr/local/lib/libgrpc++_unsecure.a", + "file:/usr/local/lib/libgrpc.a", + "file:/usr/local/lib/libgrpc_plugin_support.a", + "file:/usr/local/lib/libgrpc_unsecure.a", + "file:/usr/local/lib/libgrpcpp_channelz.a", + "file:/usr/local/lib/libmbedcrypto_gramine.a", + "file:/usr/local/lib/libmbedtls_gramine.a", + "file:/usr/local/lib/libmbedx509_gramine.a", + "file:/usr/local/lib/libprotobuf-lite.a", + "file:/usr/local/lib/libprotobuf.a", + "file:/usr/local/lib/libprotoc.a", + "file:/usr/local/lib/libre2.a", + "file:/usr/local/lib/libssl.a", + "file:/usr/local/lib/libupb.a", + "file:/usr/local/lib/libz.a", + "file:/usr/local/lib/libz.so", + "file:/usr/local/lib/libz.so.1", + "file:/usr/local/lib/libz.so.1.2.11", + "file:/usr/local/lib/pkgconfig/", + "file:/usr/local/lib/x86_64-linux-gnu/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/__internal__/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/__operators__/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/audio/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/autodiff/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/autograph/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/bitwise/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/compat/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/config/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/data/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/debugging/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/distribute/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/dtypes/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/errors/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/experimental/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/feature_column/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/graph_util/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/image/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/io/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/linalg/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/lite/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/lookup/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/math/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/mixed_precision/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/mlir/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/nest/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/nn/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/profiler/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/quantization/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/queue/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/ragged/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/random/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/raw_ops/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/saved_model/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/sets/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/signal/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/sparse/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/strings/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/summary/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/sysconfig/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/test/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/tpu/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/train/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/types/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/version/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/xla/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/jit/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/mlir/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/tf2tensorrt/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/tf2tensorrt/ops/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/tf2tensorrt/utils/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/tf2xla/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/tf2xla/python/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/xla/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/debug/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/example/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/framework/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/grappler/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/lib/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/profiler/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/protobuf/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/util/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/kernels/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/kernels/boosted_trees/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/include/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/keras/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/tools/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/lite/experimental/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/lite/toco/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/lite/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/xla_aot_runtime_src/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/autograph/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/client/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/compat/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/compiler/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/benchmarks/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/experimental/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/experimental/kernel_tests/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/experimental/ops/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/experimental/service/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/experimental/service/server_lib.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/kernel_tests/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/ops/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/util/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/debug/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/dlpack/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/estimator/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/feature_column/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/grappler/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/kernel_tests/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/layers/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/lib/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/module/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/platform/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/model_analyzer.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/option_builder.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/profiler.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/profiler_client.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/profiler_v2.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/tfprof_logger.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/trace.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/traceme.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/internal/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/internal/flops_registry.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/pywrap_mlir.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/pywrap_tensorflow.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/pywrap_tensorflow_internal.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/pywrap_tfe.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/saved_model/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/summary/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/tf2.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/tools/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/tpu/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/training/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/types/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/user_ops/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/util/", + "file:/usr/local/lib/python3.6/dist-packages/pyspark/", + "file:/usr/local/lib/python3.6/dist-packages/Cython/", + "file:/usr/local/lib/python3.6/dist-packages/numpy/", + "file:/usr/local/lib/python3.6/dist-packages/grpc/", + "file:/usr/local/lib/python3.6/dist-packages/google/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow_estimator/", + "file:/usr/local/lib/python3.6/dist-packages/sklearn/", + "file:/usr/local/lib/python3.6/dist-packages/fedlearner/", + "file:/usr/local/lib/python3.6/dist-packages/pandas/", + "file:/usr/local/lib/python3.6/dist-packages/Cryptodome/", + "file:/usr/local/lib/python3.6/dist-packages/PIL/", + "file:/usr/local/lib/python3.6/dist-packages/Pillow.libs/", + "file:/usr/local/lib/python3.6/dist-packages/_cffi_backend.cpython-36m-x86_64-linux-gnu.so", + "file:/usr/local/lib/python3.6/dist-packages/_yaml/", + "file:/usr/local/lib/python3.6/dist-packages/absl/", + "file:/usr/local/lib/python3.6/dist-packages/aiocontextvars.py", + "file:/usr/local/lib/python3.6/dist-packages/apsw/", + "file:/usr/local/lib/python3.6/dist-packages/astroid/", + "file:/usr/local/lib/python3.6/dist-packages/astunparse/", + "file:/usr/local/lib/python3.6/dist-packages/backoff/", + "file:/usr/local/lib/python3.6/dist-packages/backports/", + "file:/usr/local/lib/python3.6/dist-packages/cachetools/", + "file:/usr/local/lib/python3.6/dist-packages/cc/", + "file:/usr/local/lib/python3.6/dist-packages/certifi/", + "file:/usr/local/lib/python3.6/dist-packages/cffi/", + "file:/usr/local/lib/python3.6/dist-packages/chardet/", + "file:/usr/local/lib/python3.6/dist-packages/cityhash.cpython-36m-x86_64-linux-gnu.so", + "file:/usr/local/lib/python3.6/dist-packages/cityhashcrc.cpython-36m-x86_64-linux-gnu.so", + "file:/usr/local/lib/python3.6/dist-packages/configparser.py", + "file:/usr/local/lib/python3.6/dist-packages/contextvars/", + "file:/usr/local/lib/python3.6/dist-packages/coverage/", + "file:/usr/local/lib/python3.6/dist-packages/cryptography/", + "file:/usr/local/lib/python3.6/dist-packages/cycler.py", + "file:/usr/local/lib/python3.6/dist-packages/cython.py", + "file:/usr/local/lib/python3.6/dist-packages/dataclasses.py", + "file:/usr/local/lib/python3.6/dist-packages/dateutil/", + "file:/usr/local/lib/python3.6/dist-packages/decorator.py", + "file:/usr/local/lib/python3.6/dist-packages/deprecated/", + "file:/usr/local/lib/python3.6/dist-packages/docopt.py", + "file:/usr/local/lib/python3.6/dist-packages/easy_install.py", + "file:/usr/local/lib/python3.6/dist-packages/elasticsearch/", + "file:/usr/local/lib/python3.6/dist-packages/elasticsearch6/", + "file:/usr/local/lib/python3.6/dist-packages/elftools/", + "file:/usr/local/lib/python3.6/dist-packages/etcd3/", + "file:/usr/local/lib/python3.6/dist-packages/farmhash.cpython-36m-x86_64-linux-gnu.so", + "file:/usr/local/lib/python3.6/dist-packages/flatbuffers/", + "file:/usr/local/lib/python3.6/dist-packages/flatten_dict/", + "file:/usr/local/lib/python3.6/dist-packages/fsspec/", + "file:/usr/local/lib/python3.6/dist-packages/gast/", + "file:/usr/local/lib/python3.6/dist-packages/gmpy2/", + "file:/usr/local/lib/python3.6/dist-packages/gmpy2.libs/", + "file:/usr/local/lib/python3.6/dist-packages/google_auth_oauthlib/", + "file:/usr/local/lib/python3.6/dist-packages/googleapis_common_protos-1.56.3-py3.10-nspkg.pth", + "file:/usr/local/lib/python3.6/dist-packages/graminelibos/", + "file:/usr/local/lib/python3.6/dist-packages/grpc_tools/", + "file:/usr/local/lib/python3.6/dist-packages/guppy/", + "file:/usr/local/lib/python3.6/dist-packages/h5py/", + "file:/usr/local/lib/python3.6/dist-packages/hdfs/", + "file:/usr/local/lib/python3.6/dist-packages/immutables/", + "file:/usr/local/lib/python3.6/dist-packages/importlib_metadata/", + "file:/usr/local/lib/python3.6/dist-packages/influxdb/", + "file:/usr/local/lib/python3.6/dist-packages/isort/", + "file:/usr/local/lib/python3.6/dist-packages/joblib/", + "file:/usr/local/lib/python3.6/dist-packages/keras_preprocessing/", + "file:/usr/local/lib/python3.6/dist-packages/kiwisolver.cpython-36m-x86_64-linux-gnu.so", + "file:/usr/local/lib/python3.6/dist-packages/kubernetes/", + "file:/usr/local/lib/python3.6/dist-packages/lazy_object_proxy/", + "file:/usr/local/lib/python3.6/dist-packages/markdown/", + "file:/usr/local/lib/python3.6/dist-packages/matplotlib/", + "file:/usr/local/lib/python3.6/dist-packages/matplotlib-3.3.4-py3.6-nspkg.pth", + "file:/usr/local/lib/python3.6/dist-packages/mccabe.py", + "file:/usr/local/lib/python3.6/dist-packages/mesonbuild/", + "file:/usr/local/lib/python3.6/dist-packages/mpl_toolkits/", + "file:/usr/local/lib/python3.6/dist-packages/msgpack/", + "file:/usr/local/lib/python3.6/dist-packages/numpy/", + "file:/usr/local/lib/python3.6/dist-packages/numpy.libs/", + "file:/usr/local/lib/python3.6/dist-packages/oauthlib/", + "file:/usr/local/lib/python3.6/dist-packages/opentelemetry/", + "file:/usr/local/lib/python3.6/dist-packages/opt_einsum/", + "file:/usr/local/lib/python3.6/dist-packages/pasta/", + "file:/usr/local/lib/python3.6/dist-packages/peewee.py", + "file:/usr/local/lib/python3.6/dist-packages/pip/", + "file:/usr/local/lib/python3.6/dist-packages/pkg_resources/", + "file:/usr/local/lib/python3.6/dist-packages/playhouse/", + "file:/usr/local/lib/python3.6/dist-packages/prettytable/", + "file:/usr/local/lib/python3.6/dist-packages/prison/", + "file:/usr/local/lib/python3.6/dist-packages/protobuf-3.19.6-py3.6-nspkg.pth", + "file:/usr/local/lib/python3.6/dist-packages/psutil/", + "file:/usr/local/lib/python3.6/dist-packages/pwiz.py", + "file:/usr/local/lib/python3.6/dist-packages/py4j/", + "file:/usr/local/lib/python3.6/dist-packages/pyasn1/", + "file:/usr/local/lib/python3.6/dist-packages/pyasn1_modules/", + "file:/usr/local/lib/python3.6/dist-packages/pycparser/", + "file:/usr/local/lib/python3.6/dist-packages/pylab.py", + "file:/usr/local/lib/python3.6/dist-packages/pylint/", + "file:/usr/local/lib/python3.6/dist-packages/pyparsing/", + "file:/usr/local/lib/python3.6/dist-packages/pytz/", + "file:/usr/local/lib/python3.6/dist-packages/pyximport/", + "file:/usr/local/lib/python3.6/dist-packages/requests/", + "file:/usr/local/lib/python3.6/dist-packages/requests_kerberos/", + "file:/usr/local/lib/python3.6/dist-packages/requests_oauthlib/", + "file:/usr/local/lib/python3.6/dist-packages/rsa/", + "file:/usr/local/lib/python3.6/dist-packages/scikit_learn.libs/", + "file:/usr/local/lib/python3.6/dist-packages/scipy/", + "file:/usr/local/lib/python3.6/dist-packages/scipy.libs/", + "file:/usr/local/lib/python3.6/dist-packages/setuptools/", + "file:/usr/local/lib/python3.6/dist-packages/six.py", + "file:/usr/local/lib/python3.6/dist-packages/spnego/", + "file:/usr/local/lib/python3.6/dist-packages/src/", + "file:/usr/local/lib/python3.6/dist-packages/tenacity/", + "file:/usr/local/lib/python3.6/dist-packages/tensorboard/", + "file:/usr/local/lib/python3.6/dist-packages/tensorboard_data_server/", + "file:/usr/local/lib/python3.6/dist-packages/tensorboard_plugin_wit/", + "file:/usr/local/lib/python3.6/dist-packages/termcolor.py", + "file:/usr/local/lib/python3.6/dist-packages/test/", + "file:/usr/local/lib/python3.6/dist-packages/tests/", + "file:/usr/local/lib/python3.6/dist-packages/threadpoolctl.py", + "file:/usr/local/lib/python3.6/dist-packages/toml/", + "file:/usr/local/lib/python3.6/dist-packages/typed_ast/", + "file:/usr/local/lib/python3.6/dist-packages/typing_extensions.py", + "file:/usr/local/lib/python3.6/dist-packages/urllib3/", + "file:/usr/local/lib/python3.6/dist-packages/wcwidth/", + "file:/usr/local/lib/python3.6/dist-packages/websocket/", + "file:/usr/local/lib/python3.6/dist-packages/werkzeug/", + "file:/usr/local/lib/python3.6/dist-packages/wheel/", + "file:/usr/local/lib/python3.6/dist-packages/yaml/", + "file:/usr/local/lib/python3.6/dist-packages/zipp.py" +] + +sgx.allowed_files = [ + "file:tensorflow_io.py", + "file:/opt/tiger/", + "file:/opt/meituan/", + "file:/usr/lib/ssl/openssl.cnf", + "file:/usr/lib/gcc", + "file:/usr/local/lib/python3.6/dist-packages/MySQLdb/", + "file:/usr/local/lib/python3.6/dist-packages/gssapi/", + "file:/usr/local/lib/python3.6/dist-packages/krb5/", + "file:/usr/local/lib/python3.6/dist-packages/leveldb.cpython-36m-x86_64-linux-gnu.so", + "file:/usr/local/lib/python3.6/dist-packages/leveldb-0.201.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/mysqlclient-2.1.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/wrapt-1.12.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/sqlalchemy/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/__init__.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/lite/python/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/_api/v2/v2.py", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/libtensorflow_framework.so.2", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/tf2tensorrt/_pywrap_py_utils.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/compiler/tf2xla/ops/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/core/kernels/libtfkernel_sobol_op.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_dtypes.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_op_def_registry.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_op_def_util.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_python_memory_checker_helper.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_bfloat16.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_checkpoint_reader.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_debug_events_writer.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_device_lib.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_events_writer.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_file_io.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_kernel_registry.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_mlir.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_parallel_device.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_py_exception_registry.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_py_func.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_python_api_dispatcher.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_python_op_gen.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_quantize_training.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_record_io.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_stacktrace_handler.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_stat_summarizer.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_tensor_float_32_execution.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_tensorflow_internal.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_tf_cluster.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_tf_item.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_tf_optimizer.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_tf_session.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_tfe.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_tfprof.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_toco_api.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_transform_graph.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_util_port.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_pywrap_utils.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/_tf_stack.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/data/experimental/service/_pywrap_server_lib.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/internal/_pywrap_profiler.so", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow/python/profiler/internal/_pywrap_traceme.so", + "file:/usr/local/lib/python3.6/dist-packages/wrapt/", + "file:/usr/local/lib/python3.6/dist-packages/Cython-0.29.36.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/Deprecated-1.2.14.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/Keras_Preprocessing-1.1.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/Markdown-3.3.7.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/Pillow-8.4.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/PyYAML-6.0.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/Werkzeug-2.0.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/absl_py-0.15.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/aiocontextvars-0.2.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/apsw-3.43.0.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/astroid-2.3.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/astunparse-1.6.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/backoff-1.10.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/cachetools-4.2.4.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/certifi-2024.2.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/cffi-1.15.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/chardet-4.0.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/cityhash-0.4.7.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/configparser-5.2.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/contextvars-2.4.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/coverage-6.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/cryptography-40.0.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/cycler-0.11.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/dataclasses-0.8.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/decorator-5.1.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/docopt-0.6.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/elasticsearch-7.11.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/elasticsearch6-6.8.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/etcd3-0.12.0-py3.6.egg-info/", + "file:/usr/local/lib/python3.6/dist-packages/fedlearner-1.5.dev0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/flatbuffers-1.12.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/flatten_dict-0.4.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/fsspec-2022.1.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/gast-0.3.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/gmpy2-2.1.5.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/google_auth-2.22.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/google_auth_oauthlib-0.4.6.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/google_pasta-0.2.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/googleapis_common_protos-1.56.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/grpcio-1.38.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/grpcio_tools-1.48.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/gssapi-1.7.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/guppy3-3.1.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/h5py-2.10.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/hdfs-2.7.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/immutables-0.19.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/importlib_metadata-4.8.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/influxdb-5.3.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/isort-4.3.21.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/joblib-1.1.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/kiwisolver-1.3.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/krb5-0.3.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/kubernetes-29.0.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/lazy_object_proxy-1.4.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/matplotlib-3.3.4.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/mccabe-0.6.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/meson-0.61.5.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/msgpack-1.0.5.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/numpy-1.19.5.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/oauthlib-3.2.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/opentelemetry_api-1.10.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/opentelemetry_exporter_otlp-1.10.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/opentelemetry_exporter_otlp_proto_grpc-1.10.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/opentelemetry_exporter_otlp_proto_http-1.10.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/opentelemetry_proto-1.10.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/opentelemetry_sdk-1.10.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/opentelemetry_semantic_conventions-0.29b0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/opt_einsum-3.3.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pandas-1.1.5.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/peewee-3.17.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pip-21.3.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/prettytable-2.5.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/prison-0.1.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/protobuf-3.19.6.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/psutil-5.9.8.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/py4j-0.10.9.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pyasn1-0.5.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pyasn1_modules-0.3.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pycparser-2.21.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pycryptodomex-3.20.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pyelftools-0.31.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pylint-2.4.4.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pyparsing-3.1.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pyspark-3.0.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pyspnego-0.5.4.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/python_dateutil-2.9.0.post0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/pytz-2021.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/requests-2.25.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/requests_kerberos-0.14.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/requests_oauthlib-2.0.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/rsa-4.9.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/scikit_learn-0.24.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/scipy-1.5.4.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/setuptools-41.0.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/six-1.15.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/tenacity-8.2.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/tensorboard-2.10.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/tensorboard_data_server-0.6.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/tensorboard_plugin_wit-1.8.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow-2.4.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/tensorflow_estimator-2.4.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/termcolor-1.1.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/threadpoolctl-3.1.0.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/toml-0.10.2.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/typed_ast-1.4.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/typing_extensions-3.7.4.3.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/urllib3-1.26.18.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/wcwidth-0.2.13.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/websocket_client-1.3.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/wheel-0.37.1.dist-info/", + "file:/usr/local/lib/python3.6/dist-packages/zipp-3.6.0.dist-info/", + "file:{{ python.stdlib }}/", + "file:{{ python.distlib }}/", + "file:/etc/ethers", + "file:/etc/hosts", + "file:/etc/group", + "file:/etc/passwd", + "file:/etc/ld.so.conf", + "file:/etc/gai.conf", + "file:/etc/host.conf", + "file:/etc/resolv.conf", + "file:/etc/nsswitch.conf", + "file:/etc/sgx_default_qcnl.conf", + "file:/etc/ssl/certs/ca-certificates.crt", + "file:/etc/tce_dynamic/identity.token", + "file:/proc/stat", + "file:/proc/net/", + "file:/proc/self/cmdline", + "file:/tmp/", + "file:/root/.keras/keras.json", + "file:dynamic_config.json", + "file:/usr/bin/", + "file:/lib/", + "file:/bin/", + "file:/data/", +] diff --git a/sgx/gramine/CI-Examples/grpc/cpp/helloworld/Makefile b/sgx/gramine/CI-Examples/grpc/cpp/helloworld/Makefile new file mode 100644 index 000000000..1d96c258c --- /dev/null +++ b/sgx/gramine/CI-Examples/grpc/cpp/helloworld/Makefile @@ -0,0 +1,48 @@ +################################# CONSTANTS ################################### + +GRAMINEDIR ?= ../../../.. +SGX_SIGNER_KEY ?= $(GRAMINEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem + +include $(GRAMINEDIR)/Scripts/Makefile.configs + +ifeq ($(DEBUG),1) +GRAPHENE_LOG_LEVEL = debug +else +GRAPHENE_LOG_LEVEL = error +endif + +.PHONY: all +all: grpc.manifest +ifeq ($(SGX),1) +all: grpc.manifest.sgx grpc.sig grpc.token +endif + +################################ gRPC MANIFEST ############################### + +grpc.manifest: grpc.manifest.template + gramine-manifest \ + -Dentrypoint=$(GRAPHENE_ENTRYPOINT) \ + -Darch_libdir=$(ARCH_LIBDIR) \ + -Dlog_level=$(GRAPHENE_LOG_LEVEL) \ + $< >$@ + +grpc.manifest.sgx: grpc.manifest + gramine-sgx-sign \ + --key $(SGX_SIGNER_KEY) \ + --manifest $< \ + --output $@ + +grpc.sig: grpc.manifest.sgx + +grpc.token: grpc.sig + gramine-sgx-get-token --output $@ --sig $< + +################################## CLEANUP #################################### + +.PHONY: clean +clean: + $(RM) *.token *.sig *.manifest.sgx *.manifest + $(RM) -r scripts/__pycache__ + +.PHONY: distclean +distclean: clean diff --git a/sgx/graphene/Examples/grpc/cpp/helloworld/README.md b/sgx/gramine/CI-Examples/grpc/cpp/helloworld/README.md similarity index 72% rename from sgx/graphene/Examples/grpc/cpp/helloworld/README.md rename to sgx/gramine/CI-Examples/grpc/cpp/helloworld/README.md index 2f7591cb6..081062b40 100644 --- a/sgx/graphene/Examples/grpc/cpp/helloworld/README.md +++ b/sgx/gramine/CI-Examples/grpc/cpp/helloworld/README.md @@ -5,12 +5,12 @@ recent version of gRPC (as of this writing, version 3.18.0). This was tested on a machine with SGX v1 and Ubuntu 18.04. The Makefile and the template manifest contain extensive comments and are made -self-explanatory. Please review them to gain understanding of Graphene-SGX -and requirements for applications running under Graphene-SGX. +self-explanatory. Please review them to gain understanding of Gramine-SGX +and requirements for applications running under Gramine-SGX. ## gRPC RA-TLS server -The server is supposed to run in the SGX enclave with Graphene and RA-TLS dlopen-loaded. +The server is supposed to run in the SGX enclave with Gramine and RA-TLS dlopen-loaded. ## gRPC RA-TLS client @@ -26,10 +26,9 @@ with four additional command-line arguments (see the source code for details). kill %% -make run & +cd ../tmp/server +gramine-sgx grpc -# get mre and mrs -graphene-sgx-get-token --sig grpc-server.sig - -./grpc-client -mre=xxxxxxxxxxxxx -mrs=xxxxxxxxxxxxx -isv_prod_id=x -isv_svn=x +cd ../tmp/client +gramine-sgx grpc ``` diff --git a/sgx/gramine/CI-Examples/grpc/cpp/helloworld/build.sh b/sgx/gramine/CI-Examples/grpc/cpp/helloworld/build.sh new file mode 100755 index 000000000..ad9ac2959 --- /dev/null +++ b/sgx/gramine/CI-Examples/grpc/cpp/helloworld/build.sh @@ -0,0 +1,60 @@ +set -ex + +shopt -s expand_aliases +alias logfilter="grep \"mr_enclave\|mr_signer\|isv_prod_id\|isv_svn\"" + +GRPC_EXP_PATH=${GRPC_PATH}/examples +GRPC_EXP_CPP_PATH=${GRPC_EXP_PATH}/cpp +RUNTIME_TMP_PATH=/tmp/grpc_tmp_runtime +RUNTIME_PATH=`pwd -P`/runtime + +function get_env() { + gramine-sgx-get-token -s grpc.sig -o /dev/null | grep $1 | awk -F ":" '{print $2}' | xargs +} + +function prepare_runtime() { + make clean && GRAPHENE_ENTRYPOINT=$1 make | logfilter && cp -r `pwd -P` ${RUNTIME_TMP_PATH}/$1 +} + +function generate_json() { + cd ${RUNTIME_TMP_PATH}/$1 + jq ' .sgx_mrs[0].mr_enclave = ''"'`get_env mr_enclave`'" | .sgx_mrs[0].mr_signer = ''"'`get_env mr_signer`'" ' ${GRPC_EXP_PATH}/dynamic_config.json > ${RUNTIME_TMP_PATH}/$2/dynamic_config.json + cd - +} + +# build examples +${GRPC_EXP_CPP_PATH}/helloworld/build.sh +${GRPC_EXP_CPP_PATH}/keyvaluestore/build.sh + +# copy examples +cp ${GRPC_EXP_CPP_PATH}/helloworld/build/greeter_server . +cp ${GRPC_EXP_CPP_PATH}/helloworld/build/greeter_client . +cp ${GRPC_EXP_CPP_PATH}/helloworld/build/greeter_async_server . +cp ${GRPC_EXP_CPP_PATH}/helloworld/build/greeter_async_client . +cp ${GRPC_EXP_CPP_PATH}/keyvaluestore/build/server ./stream_server +cp ${GRPC_EXP_CPP_PATH}/keyvaluestore/build/client ./stream_client + +# create runtime tmp dir +rm -rf ${RUNTIME_PATH} || true +rm -rf ${RUNTIME_TMP_PATH} || true +mkdir -p ${RUNTIME_TMP_PATH} + +# prepare runtime with gramine +prepare_runtime greeter_server +prepare_runtime greeter_client +prepare_runtime greeter_async_server +prepare_runtime greeter_async_client +prepare_runtime stream_server +prepare_runtime stream_client + +# generate config json for sgx +generate_json greeter_server greeter_client +generate_json greeter_client greeter_server +generate_json greeter_async_server greeter_async_client +generate_json greeter_async_client greeter_async_server +generate_json stream_server stream_client +generate_json stream_client stream_server + +mv ${RUNTIME_TMP_PATH} ${RUNTIME_PATH} + +kill -9 `pgrep -f gramine` diff --git a/sgx/gramine/CI-Examples/grpc/cpp/helloworld/grpc.manifest.template b/sgx/gramine/CI-Examples/grpc/cpp/helloworld/grpc.manifest.template new file mode 100644 index 000000000..9ee6a213c --- /dev/null +++ b/sgx/gramine/CI-Examples/grpc/cpp/helloworld/grpc.manifest.template @@ -0,0 +1,74 @@ +libos.entrypoint = "{{ entrypoint }}" +libos.check_invalid_pointers = false + +loader.preload = "file:{{ gramine.libos }}" +loader.log_level = "{{ log_level }}" +# loader.log_file = "" + +loader.pal_internal_mem_size = "128M" + +loader.insecure__use_cmdline_argv = true +loader.insecure__use_host_env = false + +loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}" +loader.env.LC_ALL = "C" +loader.env.GRPC_VERBOSITY = "ERROR" + +sys.enable_sigterm_injection = true +sys.stack.size = "16M" + +fs.mount.lib.type = "chroot" +fs.mount.lib.path = "/lib" +fs.mount.lib.uri = "file:{{ gramine.runtimedir() }}" + +fs.mount.lib2.type = "chroot" +fs.mount.lib2.path = "{{ arch_libdir }}" +fs.mount.lib2.uri = "file:{{ arch_libdir }}" + +fs.mount.lib3.type = "chroot" +fs.mount.lib3.path = "/usr{{ arch_libdir }}" +fs.mount.lib3.uri = "file:/usr{{ arch_libdir }}" + +fs.mount.etc.type = "chroot" +fs.mount.etc.path = "/etc" +fs.mount.etc.uri = "file:/etc" + +# Note that Gramine also creates an internal +# thread for handling inter-process communication (IPC), and potentially another +# thread for asynchronous events. Therefore, the actual number of threads that +# the application can create is (sgx.thread_num - 2). + +sgx.debug = false +sgx.remote_attestation = true +sgx.nonpie_binary = true + +sgx.enclave_size = "2G" +sgx.thread_num = 16 + +# sgx.require_avx = true +# sgx.require_avx512 = true +# sgx.require_amx = true + +sgx.enable_stats = false + +sgx.trusted_files = [ + "file:{{ entrypoint }}", + "file:{{ gramine.runtimedir() }}/", + "file:{{ arch_libdir }}/", + "file:/usr{{ arch_libdir }}/", + "file:/etc/ssl/certs/ca-certificates.crt", +] + +sgx.allowed_files = [ + "file:/usr/lib/ssl/openssl.cnf", + "file:/etc/ld.so.conf", + "file:/etc/gai.conf", + "file:/etc/host.conf", + "file:/etc/resolv.conf", + "file:/etc/nsswitch.conf", + "file:/etc/sgx_default_qcnl.conf", + "file:/etc/hosts", + "file:/etc/group", + "file:/etc/passwd", + "file:dynamic_config.json", +] diff --git a/sgx/gramine/CI-Examples/grpc/python/helloworld/Makefile b/sgx/gramine/CI-Examples/grpc/python/helloworld/Makefile new file mode 100644 index 000000000..03577521d --- /dev/null +++ b/sgx/gramine/CI-Examples/grpc/python/helloworld/Makefile @@ -0,0 +1,48 @@ +################################# CONSTANTS ################################### + +GRAMINEDIR ?= ../../../.. +SGX_SIGNER_KEY ?= $(GRAMINEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem + +include $(GRAMINEDIR)/Scripts/Makefile.configs + +ifeq ($(DEBUG),1) +GRAPHENE_LOG_LEVEL = debug +else +GRAPHENE_LOG_LEVEL = error +endif + +.PHONY: all +all: python.manifest +ifeq ($(SGX),1) +all: python.manifest.sgx python.sig python.token +endif + +################################ gRPC MANIFEST ############################### + +python.manifest: python.manifest.template + gramine-manifest \ + -Dentrypoint=$(realpath $(shell sh -c "command -v python3")) \ + -Darch_libdir=$(ARCH_LIBDIR) \ + -Dlog_level=$(GRAPHENE_LOG_LEVEL) \ + $< >$@ + +python.manifest.sgx: python.manifest + gramine-sgx-sign \ + --key $(SGX_SIGNER_KEY) \ + --manifest $< \ + --output $@ + +python.sig: python.manifest.sgx + +python.token: python.sig + gramine-sgx-get-token --output $@ --sig $< + +################################## CLEANUP #################################### + +.PHONY: clean +clean: + $(RM) *.token *.sig *.manifest.sgx *.manifest + $(RM) -r scripts/__pycache__ + +.PHONY: distclean +distclean: clean diff --git a/sgx/gramine/CI-Examples/grpc/python/helloworld/README.md b/sgx/gramine/CI-Examples/grpc/python/helloworld/README.md new file mode 100644 index 000000000..c2240fcbd --- /dev/null +++ b/sgx/gramine/CI-Examples/grpc/python/helloworld/README.md @@ -0,0 +1,32 @@ +# gRPC + +This directory contains the Makefile and the template manifest for the most +recent version of gRPC (as of this writing, version 3.18.0). This was tested +on a machine with SGX v1 and Ubuntu 18.04. + +The Makefile and the template manifest contain extensive comments and are made +self-explanatory. Please review them to gain understanding of Gramine-SGX +and requirements for applications running under Gramine-SGX. + +## gRPC RA-TLS server + +The server is supposed to run in the SGX enclave with Gramine and RA-TLS dlopen-loaded. + +## gRPC RA-TLS client + +If client is run without additional command-line arguments, it uses default RA-TLS verification +callback that compares `mr_enclave`, `mr_signer`, `isv_prod_id` and `isv_svn` against the corresonding +`RA_TLS_*` environment variables. To run the client with its own verification callback, execute it +with four additional command-line arguments (see the source code for details). + +# Quick Start + +``` +./build.sh + +kill %% + +gramine-sgx python -u ./grpc-server.py + +gramine-sgx python -u ./grpc-client.py +``` diff --git a/sgx/gramine/CI-Examples/grpc/python/helloworld/build.sh b/sgx/gramine/CI-Examples/grpc/python/helloworld/build.sh new file mode 100755 index 000000000..93d4748f8 --- /dev/null +++ b/sgx/gramine/CI-Examples/grpc/python/helloworld/build.sh @@ -0,0 +1,29 @@ +set -e + +shopt -s expand_aliases +alias logfilter="grep \"mr_enclave\|mr_signer\|isv_prod_id\|isv_svn\"" + +# cp -r /home/host-home/0400h/fedlearner/sgx/grpc/v1.38.1/. ${GRPC_PATH} +# cp -r /home/host-home/0400h/fedlearner/sgx/gramine/CI-Examples/. ${GRAMINEDIR}/CI-Examples + +export EXP_PATH=${GRPC_PATH}/examples +export EXP_PY_PATH=${EXP_PATH}/python/helloworld + +function get_env() { + gramine-sgx-get-token -s python.sig -o /dev/null | grep $1 | awk -F ":" '{print $2}' | xargs +} + +# build example +${EXP_PY_PATH}/build.sh + +# copy examples +cp ${EXP_PY_PATH}/greeter_client.py ./grpc-client.py +cp ${EXP_PY_PATH}/greeter_server.py ./grpc-server.py +cp ${EXP_PY_PATH}/helloworld_pb2.py . +cp ${EXP_PY_PATH}/helloworld_pb2_grpc.py . + +# build and generate config json with gramine +make clean && make | logfilter +jq ' .sgx_mrs[0].mr_enclave = ''"'`get_env mr_enclave`'" | .sgx_mrs[0].mr_signer = ''"'`get_env mr_signer`'" ' ${EXP_PATH}/dynamic_config.json > ./dynamic_config.json + +kill -9 `pgrep -f gramine` diff --git a/sgx/gramine/CI-Examples/grpc/python/helloworld/python.manifest.template b/sgx/gramine/CI-Examples/grpc/python/helloworld/python.manifest.template new file mode 100644 index 000000000..3ad793af6 --- /dev/null +++ b/sgx/gramine/CI-Examples/grpc/python/helloworld/python.manifest.template @@ -0,0 +1,88 @@ +libos.entrypoint = "{{ entrypoint }}" +libos.check_invalid_pointers = false + +loader.preload = "file:{{ gramine.libos }}" +loader.log_level = "{{ log_level }}" +# loader.log_file = "" + +loader.pal_internal_mem_size = "128M" + +loader.insecure__use_cmdline_argv = true +loader.insecure__use_host_env = false + +loader.env.LD_LIBRARY_PATH = "{{ python.stdlib }}/lib:/lib:{{ arch_libdir }}:/usr/local/lib:/usr/local/{{ arch_libdir }}:/usr/lib:/usr/{{ arch_libdir }}" +loader.env.GRPC_VERBOSITY = "ERROR" + +sys.enable_sigterm_injection = true +sys.stack.size = "16M" + +fs.mount.lib.type = "chroot" +fs.mount.lib.path = "/lib" +fs.mount.lib.uri = "file:{{ gramine.runtimedir() }}" + +fs.mount.lib2.type = "chroot" +fs.mount.lib2.path = "{{ arch_libdir }}" +fs.mount.lib2.uri = "file:{{ arch_libdir }}" + +fs.mount.usr.type = "chroot" +fs.mount.usr.path = "/usr" +fs.mount.usr.uri = "file:/usr" + +fs.mount.pyhome.type = "chroot" +fs.mount.pyhome.path = "{{ python.stdlib }}" +fs.mount.pyhome.uri = "file:{{ python.stdlib }}" + +fs.mount.pydisthome.type = "chroot" +fs.mount.pydisthome.path = "{{ python.distlib }}" +fs.mount.pydisthome.uri = "file:{{ python.distlib }}" + +fs.mount.tmp.type = "chroot" +fs.mount.tmp.path = "/tmp" +fs.mount.tmp.uri = "file:/tmp" + +fs.mount.etc.type = "chroot" +fs.mount.etc.path = "/etc" +fs.mount.etc.uri = "file:/etc" + +# Note that Gramine also creates an internal +# thread for handling inter-process communication (IPC), and potentially another +# thread for asynchronous events. Therefore, the actual number of threads that +# the application can create is (sgx.thread_num - 2). + +sgx.debug = false +sgx.remote_attestation = true +sgx.nonpie_binary = true +sgx.enclave_size = "2G" +sgx.thread_num = 32 + +sgx.trusted_files = [ + "file:{{ entrypoint }}", + "file:{{ gramine.runtimedir() }}/", + "file:{{ arch_libdir }}/", + "file:/usr/{{ arch_libdir }}/", + "file:{{ python.stdlib }}/", + "file:{{ python.distlib }}/", + "file:/usr/local/lib/python3.6/dist-packages/", + "file:/etc/ssl/certs/ca-certificates.crt", + "file:/etc/default/apport", + "file:/etc/mime.types", + "file:grpc-server.py", + "file:grpc-client.py", + "file:helloworld_pb2.py", + "file:helloworld_pb2_grpc.py", +] + +sgx.allowed_files = [ + "file:/usr/lib/ssl/openssl.cnf", + "file:/etc/ld.so.conf", + "file:/etc/gai.conf", + "file:/etc/host.conf", + "file:/etc/resolv.conf", + "file:/etc/nsswitch.conf", + "file:/etc/sgx_default_qcnl.conf", + "file:/etc/hosts", + "file:/etc/group", + "file:/etc/passwd", + "file:/proc/", + "file:dynamic_config.json" +] diff --git a/sgx/gramine/CI-Examples/mnist/Makefile b/sgx/gramine/CI-Examples/mnist/Makefile new file mode 100644 index 000000000..78e6ba12c --- /dev/null +++ b/sgx/gramine/CI-Examples/mnist/Makefile @@ -0,0 +1,48 @@ +################################# CONSTANTS ################################### + +GRAMINEDIR ?= ../.. +SGX_SIGNER_KEY ?= $(GRAMINEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem + +include $(GRAMINEDIR)/Scripts/Makefile.configs + +ifeq ($(DEBUG),1) +GRAPHENE_LOG_LEVEL = debug +else +GRAPHENE_LOG_LEVEL = error +endif + +.PHONY: all +all: python.manifest +ifeq ($(SGX),1) +all: python.manifest.sgx python.sig python.token +endif + +################################ fedlearner MANIFEST ############################### + +python.manifest: python.manifest.template + gramine-manifest \ + -Dentrypoint=$(realpath $(shell sh -c "command -v python3")) \ + -Darch_libdir=$(ARCH_LIBDIR) \ + -Dlog_level=$(GRAPHENE_LOG_LEVEL) \ + $< >$@ + +python.manifest.sgx: python.manifest + gramine-sgx-sign \ + --key $(SGX_SIGNER_KEY) \ + --manifest $< \ + --output $@ + +python.sig: python.manifest.sgx + +python.token: python.sig + gramine-sgx-get-token --output $@ --sig $< + +################################## CLEANUP #################################### + +.PHONY: clean +clean: + $(RM) *.token *.sig *.manifest.sgx *.manifest + $(RM) -r scripts/__pycache__ + +.PHONY: distclean +distclean: clean diff --git a/sgx/gramine/CI-Examples/mnist/python.manifest.template b/sgx/gramine/CI-Examples/mnist/python.manifest.template new file mode 100644 index 000000000..894da37b7 --- /dev/null +++ b/sgx/gramine/CI-Examples/mnist/python.manifest.template @@ -0,0 +1,114 @@ +libos.entrypoint = "{{ entrypoint }}" +libos.check_invalid_pointers = false + +loader.preload = "file:{{ gramine.libos }}" +loader.log_level = "{{ log_level }}" +# loader.log_file = "" + +loader.pal_internal_mem_size = "200M" + +loader.insecure__use_cmdline_argv = true +loader.insecure__use_host_env = true + +loader.env.LD_LIBRARY_PATH = "{{ python.stdlib }}/lib:/lib:{{ arch_libdir }}:/usr/local/lib:/usr/local/{{ arch_libdir }}:/usr/lib:/usr/{{ arch_libdir }}" +loader.env.SECRET_PROVISION_CONSTRUCTOR = "1" +loader.env.SECRET_PROVISION_SET_PF_KEY = "1" + +sys.enable_sigterm_injection = true +sys.stack.size = "2M" + +fs.mount.lib.type = "chroot" +fs.mount.lib.path = "/lib" +fs.mount.lib.uri = "file:{{ gramine.runtimedir() }}" + +fs.mount.lib2.type = "chroot" +fs.mount.lib2.path = "{{ arch_libdir }}" +fs.mount.lib2.uri = "file:{{ arch_libdir }}" + +fs.mount.usr.type = "chroot" +fs.mount.usr.path = "/usr" +fs.mount.usr.uri = "file:/usr" + +fs.mount.pyhome.type = "chroot" +fs.mount.pyhome.path = "{{ python.stdlib }}" +fs.mount.pyhome.uri = "file:{{ python.stdlib }}" + +fs.mount.pydisthome.type = "chroot" +fs.mount.pydisthome.path = "{{ python.distlib }}" +fs.mount.pydisthome.uri = "file:{{ python.distlib }}" + +fs.mount.tmp.type = "chroot" +fs.mount.tmp.path = "/tmp" +fs.mount.tmp.uri = "file:/tmp" + +# Do not use "/proc" in tensorflow +# fs.mount.proc.type = "chroot" +# fs.mount.proc.path = "/proc" +# fs.mount.proc.uri = "file:/proc" + +fs.mount.etc.type = "chroot" +fs.mount.etc.path = "/etc" +fs.mount.etc.uri = "file:/etc" + +fs.mount.keras.type = "chroot" +fs.mount.keras.path = "/root/.keras/keras.json" +fs.mount.keras.uri = "file:/root/.keras/keras.json" + +# Note that Gramine also creates an internal +# thread for handling inter-process communication (IPC), and potentially another +# thread for asynchronous events. Therefore, the actual number of threads that +# the application can create is (sgx.thread_num - 2). + +sgx.debug = false +sgx.remote_attestation = true +sgx.nonpie_binary = true +sgx.enclave_size = "16G" +sgx.thread_num = 512 +sgx.rpc_thread_num = 0 +sgx.protected_files_key = "ffeeddccbbaa99887766554433221100" + +sgx.trusted_files = [ + "file:{{ entrypoint }}", + "file:{{ gramine.runtimedir() }}/", + "file:{{ arch_libdir }}/", + "file:/usr/{{ arch_libdir }}/", + "file:{{ python.stdlib }}/", + "file:{{ python.distlib }}/", + "file:/usr/local/lib/python3.6/dist-packages/", + "file:/etc/ssl/certs/ca-certificates.crt", + "file:/etc/default/apport", + "file:/etc/mime.types", + "file:make_data.py", + "file:leader.py", + "file:follower.py", + "file:tensorflow_io.py", +] + +sgx.allowed_files = [ + "file:/usr/lib/ssl/openssl.cnf", + "file:/usr/lib/gcc", + "file:/usr/bin/ld", + "file:/usr/bin/gcc", + "file:/usr/bin/objdump", + "file:/etc/ethers", + "file:/etc/hosts", + "file:/etc/group", + "file:/etc/passwd", + "file:/etc/ld.so.conf", + "file:/etc/gai.conf", + "file:/etc/host.conf", + "file:/etc/resolv.conf", + "file:/etc/nsswitch.conf", + "file:/etc/sgx_default_qcnl.conf", + "file:/etc/ssl/certs/ca-certificates.crt", + "file:/proc/stat", + "file:/tmp/", + "file:data/", + "file:model/", + "file:/root/.keras/keras.json", + "file:dynamic_config.json", +] + +#sgx.protected_files = [ +# "file:model", +#] diff --git a/sgx/gramine/CI-Examples/mnist/test-ps-sgx.sh b/sgx/gramine/CI-Examples/mnist/test-ps-sgx.sh new file mode 100755 index 000000000..e7c21dd4c --- /dev/null +++ b/sgx/gramine/CI-Examples/mnist/test-ps-sgx.sh @@ -0,0 +1,82 @@ +#!/bin/bash +set -ex + +shopt -s expand_aliases +alias make_logfilter="grep \"mr_enclave\|mr_signer\|isv_prod_id\|isv_svn\"" +alias runtime_logfilter="grep -v \"FUTEX\|measured\|memory entry\|cleaning up\|async event\|shim_exit\"" + +function get_env() { + gramine-sgx-get-token -s python.sig -o /dev/null | grep $1 | awk -F ":" '{print $2}' | xargs +} + +function make_custom_env() { + export DEBUG=0 + export CUDA_VISIBLE_DEVICES="" + export DNNL_VERBOSE=0 + export GRPC_VERBOSITY=ERROR + export GRPC_POLL_STRATEGY=epoll1 + export TF_CPP_MIN_LOG_LEVEL=1 + export TF_GRPC_SGX_RA_TLS_ENABLE=on + export FL_GRPC_SGX_RA_TLS_ENABLE=on + export TF_DISABLE_MKL=0 + export TF_ENABLE_MKL_NATIVE_FORMAT=1 + export parallel_num_threads=4 + export INTRA_OP_PARALLELISM_THREADS=$parallel_num_threads + export INTER_OP_PARALLELISM_THREADS=$parallel_num_threads + export GRPC_SERVER_CHANNEL_THREADS=2 + export KMP_SETTINGS=1 + export KMP_BLOCKTIME=0 + export MR_ENCLAVE=`get_env mr_enclave` + export MR_SIGNER=`get_env mr_signer` + export ISV_PROD_ID=`get_env isv_prod_id` + export ISV_SVN=`get_env isv_svn` + # network proxy + unset http_proxy https_proxy +} + +ROLE=$1 +if [ "$ROLE" == "data" ]; then + rm -rf data + cp ../tensorflow_io.py . + cp -r $FEDLEARNER_PATH/example/mnist/*.py . + python make_data.py +elif [ "$ROLE" == "make" ]; then + rm -rf *.log model + make clean && make | make_logfilter + jq ' .sgx_mrs[0].mr_enclave = ''"'`get_env mr_enclave`'" | .sgx_mrs[0].mr_signer = ''"'`get_env mr_signer`'" ' $GRPC_PATH/examples/dynamic_config.json > ./dynamic_config.json + kill -9 `pgrep -f gramine` +elif [ "$ROLE" == "leader" ]; then + make_custom_env + rm -rf model/leader + taskset -c 0-3 stdbuf -o0 gramine-sgx python -u -m fedlearner.trainer.parameter_server localhost:40051 2>&1 | runtime_logfilter | tee -a leader-gramine-ps.log & + taskset -c 4-7 stdbuf -o0 gramine-sgx python -u leader.py --local-addr=localhost:50051 \ + --peer-addr=localhost:50052 \ + --data-path=data/leader \ + --checkpoint-path=model/leader/checkpoint \ + --export-path=model/leader/saved_model \ + --save-checkpoint-steps=10 \ + --epoch-num=2 \ + --batch-size=32 \ + --cluster-spec='{"clusterSpec":{"PS":["localhost:40051"]}}' \ + --loglevel=debug 2>&1 | runtime_logfilter | tee -a leader-gramine.log & + if [ "$DEBUG" != "0" ]; then + wait && kill -9 `pgrep -f gramine` + fi +elif [ "$ROLE" == "follower" ]; then + make_custom_env + rm -rf model/follower + taskset -c 8-11 stdbuf -o0 gramine-sgx python -u -m fedlearner.trainer.parameter_server localhost:40061 2>&1 | runtime_logfilter | tee -a follower-gramine-ps.log & + taskset -c 12-15 stdbuf -o0 gramine-sgx python -u follower.py --local-addr=localhost:50052 \ + --peer-addr=localhost:50051 \ + --data-path=data/follower \ + --checkpoint-path=model/follower/checkpoint \ + --export-path=model/follower/saved_model \ + --save-checkpoint-steps=10 \ + --epoch-num=2 \ + --batch-size=32 \ + --cluster-spec='{"clusterSpec":{"PS":["localhost:40061"]}}' \ + --loglevel=debug 2>&1 | runtime_logfilter | tee -a follower-gramine.log & + if [ "$DEBUG" != "0" ]; then + wait && kill -9 `pgrep -f gramine` + fi +fi diff --git a/sgx/gramine/CI-Examples/mnist/test-ps.sh b/sgx/gramine/CI-Examples/mnist/test-ps.sh new file mode 100755 index 000000000..849769f3e --- /dev/null +++ b/sgx/gramine/CI-Examples/mnist/test-ps.sh @@ -0,0 +1,58 @@ +#!/bin/bash +set -ex + +function make_custom_env() { + export CUDA_VISIBLE_DEVICES="" + export DNNL_VERBOSE=0 + export GRPC_VERBOSITY=ERROR + export GRPC_POLL_STRATEGY=epoll1 + export TF_CPP_MIN_LOG_LEVEL=1 + export TF_GRPC_SGX_RA_TLS_ENABLE="" + export FL_GRPC_SGX_RA_TLS_ENABLE="" + export TF_DISABLE_MKL=0 + export TF_ENABLE_MKL_NATIVE_FORMAT=1 + export parallel_num_threads=4 + export INTRA_OP_PARALLELISM_THREADS=$parallel_num_threads + export INTER_OP_PARALLELISM_THREADS=$parallel_num_threads + export GRPC_SERVER_CHANNEL_THREADS=2 + export KMP_SETTINGS=1 + export KMP_BLOCKTIME=0 + # network proxy + unset http_proxy https_proxy +} + +ROLE=$1 +if [ "$ROLE" == "data" ]; then + rm -rf data model *.log + cp ../tensorflow_io.py . + cp -r ${FEDLEARNER_PATH}/example/mnist/*.py . + python make_data.py +elif [ "$ROLE" == "leader" ]; then + make_custom_env + rm -rf model/leader + taskset -c 0-3 python -u -m fedlearner.trainer.parameter_server localhost:40051 2>&1 | tee -a leader-ps.log & + taskset -c 4-7 python -u leader.py --local-addr=localhost:50051 \ + --peer-addr=localhost:50052 \ + --data-path=data/leader \ + --checkpoint-path=model/leader/checkpoint \ + --export-path=model/leader/saved_model \ + --save-checkpoint-steps=10 \ + --epoch-num=2 \ + --batch-size=32 \ + --cluster-spec='{"clusterSpec":{"PS":["localhost:40051"]}}' \ + --loglevel=debug 2>&1 | tee -a leader-native.log & +elif [ "$ROLE" == "follower" ]; then + make_custom_env + rm -rf model/follower + taskset -c 8-11 python -u -m fedlearner.trainer.parameter_server localhost:40061 2>&1 | tee -a follower-ps.log & + taskset -c 12-15 python -u follower.py --local-addr=localhost:50052 \ + --peer-addr=localhost:50051 \ + --data-path=data/follower \ + --checkpoint-path=model/follower/checkpoint \ + --export-path=model/follower/saved_model \ + --save-checkpoint-steps=10 \ + --epoch-num=2 \ + --batch-size=32 \ + --cluster-spec='{"clusterSpec":{"PS":["localhost:40061"]}}' \ + --loglevel=debug 2>&1 | tee -a follower-native.log & +fi diff --git a/sgx/gramine/CI-Examples/ra-tls-mbedtls/build.sh b/sgx/gramine/CI-Examples/ra-tls-mbedtls/build.sh new file mode 100755 index 000000000..eae1f5aa3 --- /dev/null +++ b/sgx/gramine/CI-Examples/ra-tls-mbedtls/build.sh @@ -0,0 +1,16 @@ +set -ex + +export MBEDTLS_PATH=${GRAMINEDIR}/CI-Examples/ra-tls-mbedtls + +cd ${MBEDTLS_PATH} + +make clean +make app dcap + +cp -r mbedtls/include ${INSTALL_PREFIX} + +whereis libmbedtls_gramine libmbedcrypto_gramine libmbedx509_gramine +whereis libsgx_util libsgx_dcap_quoteverify libdcap_quoteprov.so.* +whereis libra_tls_attest libra_tls_verify_dcap libra_tls_verify_epid + +cd - diff --git a/sgx/graphene/Examples/ra-tls-mbedtls/src/client.c b/sgx/gramine/CI-Examples/ra-tls-mbedtls/src/client.c similarity index 99% rename from sgx/graphene/Examples/ra-tls-mbedtls/src/client.c rename to sgx/gramine/CI-Examples/ra-tls-mbedtls/src/client.c index e48f44c77..fef650910 100644 --- a/sgx/graphene/Examples/ra-tls-mbedtls/src/client.c +++ b/sgx/gramine/CI-Examples/ra-tls-mbedtls/src/client.c @@ -202,7 +202,7 @@ int main(int argc, char** argv) { * RA-TLS verification with DCAP inside SGX enclave uses dummies instead of real * functions from libsgx_urts.so, thus we don't need to load this helper library. */ - ra_tls_verify_lib = dlopen("libra_tls_verify_dcap_graphene.so", RTLD_LAZY); + ra_tls_verify_lib = dlopen("libra_tls_verify_dcap_gramine.so", RTLD_LAZY); if (!ra_tls_verify_lib) { mbedtls_printf("%s\n", dlerror()); mbedtls_printf("User requested RA-TLS verification with DCAP inside SGX but cannot find lib\n"); diff --git a/sgx/gramine/CI-Examples/ra-tls-secret-prov/build.sh b/sgx/gramine/CI-Examples/ra-tls-secret-prov/build.sh new file mode 100755 index 000000000..1ae8c2871 --- /dev/null +++ b/sgx/gramine/CI-Examples/ra-tls-secret-prov/build.sh @@ -0,0 +1,9 @@ +set -e + +#make -C ${GRAMINEDIR}/Pal/src/host/Linux-SGX/tools/ra-tls dcap + +cd ${GRAMINEDIR}/CI-Examples/ra-tls-secret-prov + +make dcap pf_crypt + +cd - diff --git a/sgx/gramine/CI-Examples/ra-tls-secret-prov/copy_resource.sh b/sgx/gramine/CI-Examples/ra-tls-secret-prov/copy_resource.sh new file mode 100755 index 000000000..4bb604dcc --- /dev/null +++ b/sgx/gramine/CI-Examples/ra-tls-secret-prov/copy_resource.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e + +if [ ! -n "$1" ] ; then + target=. +else + target=$1 +fi + +${GRAMINEDIR}/Examples/ra-tls-secret-prov/build.sh + +cp -r ${GRAMINEDIR}/CI-Examples/ra-tls-secret-prov/libs/* ${target} +cp -r ${GRAMINEDIR}/CI-Examples/ra-tls-secret-prov/pf_crypt ${target} diff --git a/sgx/gramine/CI-Examples/tensorflow-ps/Makefile b/sgx/gramine/CI-Examples/tensorflow-ps/Makefile new file mode 100644 index 000000000..78e6ba12c --- /dev/null +++ b/sgx/gramine/CI-Examples/tensorflow-ps/Makefile @@ -0,0 +1,48 @@ +################################# CONSTANTS ################################### + +GRAMINEDIR ?= ../.. +SGX_SIGNER_KEY ?= $(GRAMINEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem + +include $(GRAMINEDIR)/Scripts/Makefile.configs + +ifeq ($(DEBUG),1) +GRAPHENE_LOG_LEVEL = debug +else +GRAPHENE_LOG_LEVEL = error +endif + +.PHONY: all +all: python.manifest +ifeq ($(SGX),1) +all: python.manifest.sgx python.sig python.token +endif + +################################ fedlearner MANIFEST ############################### + +python.manifest: python.manifest.template + gramine-manifest \ + -Dentrypoint=$(realpath $(shell sh -c "command -v python3")) \ + -Darch_libdir=$(ARCH_LIBDIR) \ + -Dlog_level=$(GRAPHENE_LOG_LEVEL) \ + $< >$@ + +python.manifest.sgx: python.manifest + gramine-sgx-sign \ + --key $(SGX_SIGNER_KEY) \ + --manifest $< \ + --output $@ + +python.sig: python.manifest.sgx + +python.token: python.sig + gramine-sgx-get-token --output $@ --sig $< + +################################## CLEANUP #################################### + +.PHONY: clean +clean: + $(RM) *.token *.sig *.manifest.sgx *.manifest + $(RM) -r scripts/__pycache__ + +.PHONY: distclean +distclean: clean diff --git a/sgx/gramine/CI-Examples/tensorflow-ps/python.manifest.template b/sgx/gramine/CI-Examples/tensorflow-ps/python.manifest.template new file mode 100644 index 000000000..07fb1a533 --- /dev/null +++ b/sgx/gramine/CI-Examples/tensorflow-ps/python.manifest.template @@ -0,0 +1,110 @@ +libos.entrypoint = "{{ entrypoint }}" +libos.check_invalid_pointers = false + +loader.preload = "file:{{ gramine.libos }}" +loader.log_level = "{{ log_level }}" +# loader.log_file = "" + +loader.pal_internal_mem_size = "200M" + +loader.insecure__use_cmdline_argv = true +loader.insecure__use_host_env = true + +loader.env.LD_LIBRARY_PATH = "{{ python.stdlib }}/lib:/lib:{{ arch_libdir }}:/usr/local/lib:/usr/local/{{ arch_libdir }}:/usr/lib:/usr/{{ arch_libdir }}" +loader.env.SECRET_PROVISION_CONSTRUCTOR = "1" +loader.env.SECRET_PROVISION_SET_PF_KEY = "1" + +sys.enable_sigterm_injection = true +sys.stack.size = "2M" + +fs.mount.lib.type = "chroot" +fs.mount.lib.path = "/lib" +fs.mount.lib.uri = "file:{{ gramine.runtimedir() }}" + +fs.mount.lib2.type = "chroot" +fs.mount.lib2.path = "{{ arch_libdir }}" +fs.mount.lib2.uri = "file:{{ arch_libdir }}" + +fs.mount.usr.type = "chroot" +fs.mount.usr.path = "/usr" +fs.mount.usr.uri = "file:/usr" + +fs.mount.pyhome.type = "chroot" +fs.mount.pyhome.path = "{{ python.stdlib }}" +fs.mount.pyhome.uri = "file:{{ python.stdlib }}" + +fs.mount.pydisthome.type = "chroot" +fs.mount.pydisthome.path = "{{ python.distlib }}" +fs.mount.pydisthome.uri = "file:{{ python.distlib }}" + +fs.mount.tmp.type = "chroot" +fs.mount.tmp.path = "/tmp" +fs.mount.tmp.uri = "file:/tmp" + +# Do not use "/proc" in tensorflow +# fs.mount.proc.type = "chroot" +# fs.mount.proc.path = "/proc" +# fs.mount.proc.uri = "file:/proc" + +fs.mount.etc.type = "chroot" +fs.mount.etc.path = "/etc" +fs.mount.etc.uri = "file:/etc" + +fs.mount.keras.type = "chroot" +fs.mount.keras.path = "/root/.keras/keras.json" +fs.mount.keras.uri = "file:/root/.keras/keras.json" + +# Note that Gramine also creates an internal +# thread for handling inter-process communication (IPC), and potentially another +# thread for asynchronous events. Therefore, the actual number of threads that +# the application can create is (sgx.thread_num - 2). + +sgx.debug = false +sgx.remote_attestation = true +sgx.nonpie_binary = true +sgx.enclave_size = "8G" +sgx.thread_num = 512 +sgx.rpc_thread_num = 0 +sgx.protected_files_key = "ffeeddccbbaa99887766554433221100" + +sgx.trusted_files = [ + "file:{{ entrypoint }}", + "file:{{ gramine.runtimedir() }}/", + "file:{{ arch_libdir }}/", + "file:/usr/{{ arch_libdir }}/", + "file:{{ python.stdlib }}/", + "file:{{ python.distlib }}/", + "file:/usr/local/lib/python3.6/dist-packages/", + "file:/etc/ssl/certs/ca-certificates.crt", + "file:/etc/default/apport", + "file:/etc/mime.types", + "file:train.py", +] + +sgx.allowed_files = [ + "file:/usr/lib/ssl/openssl.cnf", + "file:/usr/lib/gcc", + "file:/usr/bin/ld", + "file:/usr/bin/gcc", + "file:/usr/bin/objdump", + "file:/etc/ethers", + "file:/etc/hosts", + "file:/etc/group", + "file:/etc/passwd", + "file:/etc/ld.so.conf", + "file:/etc/gai.conf", + "file:/etc/host.conf", + "file:/etc/resolv.conf", + "file:/etc/nsswitch.conf", + "file:/etc/sgx_default_qcnl.conf", + "file:/etc/ssl/certs/ca-certificates.crt", + "file:/proc/stat", + "file:/tmp/", + "file:data/", + "file:model/", + "file:/root/.keras/keras.json", +] + +#sgx.protected_files = [ +# "file:model", +#] diff --git a/sgx/gramine/CI-Examples/tensorflow-ps/test-ps-sgx.sh b/sgx/gramine/CI-Examples/tensorflow-ps/test-ps-sgx.sh new file mode 100755 index 000000000..c42bd4e6a --- /dev/null +++ b/sgx/gramine/CI-Examples/tensorflow-ps/test-ps-sgx.sh @@ -0,0 +1,65 @@ +#!/bin/bash +set -x + +shopt -s expand_aliases +alias make_logfilter="grep \"mr_enclave\|mr_signer\|isv_prod_id\|isv_svn\"" +alias runtime_logfilter="grep -v \"FUTEX\|measured\|memory entry\|cleaning up\|async event\|shim_exit\"" + +function get_env() { + gramine-sgx-get-token -s python.sig -o /dev/null | grep $1 | awk -F ":" '{print $2}' | xargs +} + +function make_custom_env() { + export DEBUG=0 + export CUDA_VISIBLE_DEVICES="" + export DNNL_VERBOSE=0 + export GRPC_VERBOSITY=ERROR + export GRPC_POLL_STRATEGY=epoll1 + export TF_CPP_MIN_LOG_LEVEL=1 + export TF_GRPC_SGX_RA_TLS_ENABLE=on + export TF_DISABLE_MKL=0 + export TF_ENABLE_MKL_NATIVE_FORMAT=1 + export parallel_num_threads=4 + export INTRA_OP_PARALLELISM_THREADS=$parallel_num_threads + export INTER_OP_PARALLELISM_THREADS=$parallel_num_threads + export KMP_SETTINGS=1 + export KMP_BLOCKTIME=0 + export MR_ENCLAVE=`get_env mr_enclave` + export MR_SIGNER=`get_env mr_signer` + export ISV_PROD_ID=`get_env isv_prod_id` + export ISV_SVN=`get_env isv_svn` + # network proxy + unset http_proxy https_proxy +} + +ROLE=$1 +if [ "$ROLE" == "make" ]; then + rm -rf model *.log + make clean && make | make_logfilter + kill -9 `pgrep -f python` + kill -9 `pgrep -f gramine` +elif [ "$ROLE" == "ps0" ]; then + make_custom_env + taskset -c 0-3 stdbuf -o0 gramine-sgx python -u train.py --task_index=0 --job_name=ps --loglevel=debug 2>&1 | runtime_logfilter | tee -a ps0-gramine.log & + if [ "$DEBUG" != "0" ]; then + wait && kill -9 `pgrep -f gramine` + fi +elif [ "$ROLE" == "ps1" ]; then + make_custom_env + taskset -c 8-11 stdbuf -o0 gramine-sgx python -u train.py --task_index=1 --job_name=ps --loglevel=debug 2>&1 | runtime_logfilter | tee -a ps1-gramine.log & + if [ "$DEBUG" != "0" ]; then + wait && kill -9 `pgrep -f gramine` + fi +elif [ "$ROLE" == "worker0" ]; then + make_custom_env + taskset -c 4-7 stdbuf -o0 gramine-sgx python -u train.py --task_index=0 --job_name=worker --loglevel=debug 2>&1 | runtime_logfilter | tee -a worker0-gramine.log & + if [ "$DEBUG" != "0" ]; then + wait && kill -9 `pgrep -f gramine` + fi +elif [ "$ROLE" == "worker1" ]; then + make_custom_env + taskset -c 12-15 stdbuf -o0 gramine-sgx python -u train.py --task_index=1 --job_name=worker --loglevel=debug 2>&1 | runtime_logfilter | tee -a worker1-gramine.log & + if [ "$DEBUG" != "0" ]; then + wait && kill -9 `pgrep -f gramine` + fi +fi diff --git a/sgx/gramine/CI-Examples/tensorflow-ps/test-ps.sh b/sgx/gramine/CI-Examples/tensorflow-ps/test-ps.sh new file mode 100755 index 000000000..524575abc --- /dev/null +++ b/sgx/gramine/CI-Examples/tensorflow-ps/test-ps.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -x + +function make_custom_env() { + export CUDA_VISIBLE_DEVICES="" + export DNNL_VERBOSE=0 + export GRPC_VERBOSITY=ERROR + export GRPC_POLL_STRATEGY=epoll1 + export TF_CPP_MIN_LOG_LEVEL=1 + export TF_GRPC_SGX_RA_TLS_ENABLE="" + export TF_DISABLE_MKL=0 + export TF_ENABLE_MKL_NATIVE_FORMAT=1 + export parallel_num_threads=4 + export INTRA_OP_PARALLELISM_THREADS=$parallel_num_threads + export INTER_OP_PARALLELISM_THREADS=$parallel_num_threads + export KMP_SETTINGS=1 + export KMP_BLOCKTIME=0 + # network proxy + unset http_proxy https_proxy +} + +ROLE=$1 +if [ "$ROLE" == "ps0" ]; then + kill -9 `pgrep -f python` + make_custom_env + taskset -c 0-3 stdbuf -o0 python -u train.py --task_index=0 --job_name=ps --loglevel=debug 2>&1 | tee -a ps0-native.log & +elif [ "$ROLE" == "ps1" ]; then + make_custom_env + taskset -c 8-11 stdbuf -o0 python -u train.py --task_index=1 --job_name=ps --loglevel=debug 2>&1 | tee -a ps1-native.log & +elif [ "$ROLE" == "worker0" ]; then + make_custom_env + taskset -c 4-7 stdbuf -o0 python -u train.py --task_index=0 --job_name=worker --loglevel=debug 2>&1 | tee -a worker0-native.log & +elif [ "$ROLE" == "worker1" ]; then + make_custom_env + taskset -c 12-15 stdbuf -o0 python -u train.py --task_index=1 --job_name=worker --loglevel=debug 2>&1 | tee -a worker1-native.log & +fi diff --git a/sgx/gramine/CI-Examples/tensorflow-ps/train.py b/sgx/gramine/CI-Examples/tensorflow-ps/train.py new file mode 100644 index 000000000..930dcafc9 --- /dev/null +++ b/sgx/gramine/CI-Examples/tensorflow-ps/train.py @@ -0,0 +1,68 @@ +import os +import numpy as np +import tensorflow.compat.v1 as tf +tf.disable_v2_behavior() +tf.disable_eager_execution() + +tf.app.flags.DEFINE_string("job_name", "worker", "One of 'ps', 'worker'") +tf.app.flags.DEFINE_integer("task_index", 0, "Index of task within the job") +FLAGS = tf.app.flags.FLAGS + +# Configuration of cluster +ps_hosts = [ "localhost:60001", "localhost:60002"] +worker_hosts = [ "localhost:60003", "localhost:60004"] +cluster = tf.train.ClusterSpec({"ps": ps_hosts, "worker": worker_hosts}) + +def main(_): + server = tf.train.Server(cluster, + job_name=FLAGS.job_name, + task_index=FLAGS.task_index) + if FLAGS.job_name == "ps": + server.join() + elif FLAGS.job_name == "worker": + with tf.device(tf.train.replica_device_setter( + worker_device="/job:worker/task:%d" % FLAGS.task_index, + cluster=cluster)): + + x_data = tf.placeholder(tf.float32, [100]) + y_data = tf.placeholder(tf.float32, [100]) + + W = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) + b = tf.Variable(tf.zeros([1])) + y = W * x_data + b + loss = tf.reduce_mean(tf.square(y - y_data)) + + global_step = tf.train.get_or_create_global_step() + optimizer = tf.train.GradientDescentOptimizer(0.1) + train_op = optimizer.minimize(loss, global_step=global_step) + + tf.summary.scalar('cost', loss) + summary_op = tf.summary.merge_all() + tf.global_variables_initializer() + # The StopAtStepHook handles stopping after running given steps. + hooks = [ tf.train.StopAtStepHook(last_step=1000)] + # The MonitoredTrainingSession takes care of session initialization, + # restoring from a checkpoint, saving to a checkpoint, and closing when done + # or an error occurs. + config = tf.ConfigProto(intra_op_parallelism_threads=int(os.environ["INTRA_OP_PARALLELISM_THREADS"]), + inter_op_parallelism_threads=int(os.environ["INTER_OP_PARALLELISM_THREADS"])) + with tf.train.MonitoredTrainingSession(master=server.target, + is_chief=(FLAGS.task_index==0), # 我们制定task_index为0的任务为主任务,用于负责变量初始化、做checkpoint、保存summary和复原 + checkpoint_dir="model", + save_checkpoint_secs=None, + config=config, + hooks=hooks) as mon_sess: + while not mon_sess.should_stop(): + # Run a training step asynchronously. + # See `tf.train.SyncReplicasOptimizer` for additional details on how to + # perform *synchronous* training. + # mon_sess.run handles AbortedError in case of preempted PS. + train_x = np.random.rand(100).astype(np.float32) + train_y = train_x * 0.1 + 0.3 + _, step, loss_v, weight, biase = mon_sess.run([train_op, global_step, loss, W, b], feed_dict={x_data: train_x, y_data: train_y}) + if step % 100 == 0: + print("step: %d, weight: %f, biase: %f, loss: %f" %(step, weight, biase, loss_v)) + print("Training finished.") + +if __name__ == "__main__": + tf.app.run() diff --git a/sgx/fedlearner/tensorflow_io.py b/sgx/gramine/CI-Examples/tensorflow_io.py similarity index 100% rename from sgx/fedlearner/tensorflow_io.py rename to sgx/gramine/CI-Examples/tensorflow_io.py diff --git a/sgx/gramine/CI-Examples/wide_n_deep/Makefile b/sgx/gramine/CI-Examples/wide_n_deep/Makefile new file mode 100644 index 000000000..78e6ba12c --- /dev/null +++ b/sgx/gramine/CI-Examples/wide_n_deep/Makefile @@ -0,0 +1,48 @@ +################################# CONSTANTS ################################### + +GRAMINEDIR ?= ../.. +SGX_SIGNER_KEY ?= $(GRAMINEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem + +include $(GRAMINEDIR)/Scripts/Makefile.configs + +ifeq ($(DEBUG),1) +GRAPHENE_LOG_LEVEL = debug +else +GRAPHENE_LOG_LEVEL = error +endif + +.PHONY: all +all: python.manifest +ifeq ($(SGX),1) +all: python.manifest.sgx python.sig python.token +endif + +################################ fedlearner MANIFEST ############################### + +python.manifest: python.manifest.template + gramine-manifest \ + -Dentrypoint=$(realpath $(shell sh -c "command -v python3")) \ + -Darch_libdir=$(ARCH_LIBDIR) \ + -Dlog_level=$(GRAPHENE_LOG_LEVEL) \ + $< >$@ + +python.manifest.sgx: python.manifest + gramine-sgx-sign \ + --key $(SGX_SIGNER_KEY) \ + --manifest $< \ + --output $@ + +python.sig: python.manifest.sgx + +python.token: python.sig + gramine-sgx-get-token --output $@ --sig $< + +################################## CLEANUP #################################### + +.PHONY: clean +clean: + $(RM) *.token *.sig *.manifest.sgx *.manifest + $(RM) -r scripts/__pycache__ + +.PHONY: distclean +distclean: clean diff --git a/sgx/gramine/CI-Examples/wide_n_deep/python.manifest.template b/sgx/gramine/CI-Examples/wide_n_deep/python.manifest.template new file mode 100644 index 000000000..3ce35386e --- /dev/null +++ b/sgx/gramine/CI-Examples/wide_n_deep/python.manifest.template @@ -0,0 +1,116 @@ +libos.entrypoint = "{{ entrypoint }}" +libos.check_invalid_pointers = false + +loader.preload = "file:{{ gramine.libos }}" +loader.log_level = "{{ log_level }}" +# loader.log_file = "" + +loader.pal_internal_mem_size = "200M" + +loader.insecure__use_cmdline_argv = true +loader.insecure__use_host_env = true + +loader.env.LD_LIBRARY_PATH = "{{ python.stdlib }}/lib:/lib:{{ arch_libdir }}:/usr/local/lib:/usr/local/{{ arch_libdir }}:/usr/lib:/usr/{{ arch_libdir }}" +loader.env.SECRET_PROVISION_CONSTRUCTOR = "1" +loader.env.SECRET_PROVISION_SET_PF_KEY = "1" + +sys.enable_sigterm_injection = true +sys.stack.size = "2M" + +fs.mount.lib.type = "chroot" +fs.mount.lib.path = "/lib" +fs.mount.lib.uri = "file:{{ gramine.runtimedir() }}" + +fs.mount.lib2.type = "chroot" +fs.mount.lib2.path = "{{ arch_libdir }}" +fs.mount.lib2.uri = "file:{{ arch_libdir }}" + +fs.mount.usr.type = "chroot" +fs.mount.usr.path = "/usr" +fs.mount.usr.uri = "file:/usr" + +fs.mount.pyhome.type = "chroot" +fs.mount.pyhome.path = "{{ python.stdlib }}" +fs.mount.pyhome.uri = "file:{{ python.stdlib }}" + +fs.mount.pydisthome.type = "chroot" +fs.mount.pydisthome.path = "{{ python.distlib }}" +fs.mount.pydisthome.uri = "file:{{ python.distlib }}" + +fs.mount.tmp.type = "chroot" +fs.mount.tmp.path = "/tmp" +fs.mount.tmp.uri = "file:/tmp" + +# Do not use "/proc" in tensorflow +# fs.mount.proc.type = "chroot" +# fs.mount.proc.path = "/proc" +# fs.mount.proc.uri = "file:/proc" + +fs.mount.etc.type = "chroot" +fs.mount.etc.path = "/etc" +fs.mount.etc.uri = "file:/etc" + +fs.mount.keras.type = "chroot" +fs.mount.keras.path = "/root/.keras/keras.json" +fs.mount.keras.uri = "file:/root/.keras/keras.json" + +# Note that Gramine also creates an internal +# thread for handling inter-process communication (IPC), and potentially another +# thread for asynchronous events. Therefore, the actual number of threads that +# the application can create is (sgx.thread_num - 2). + +sgx.debug = false +sgx.remote_attestation = true +sgx.preheat_enclave = false +sgx.nonpie_binary = true +sgx.enable_stats = false +sgx.enclave_size = "16G" +sgx.thread_num = 512 +sgx.rpc_thread_num = 0 +sgx.protected_files_key = "ffeeddccbbaa99887766554433221100" + +sgx.trusted_files = [ + "file:{{ entrypoint }}", + "file:{{ gramine.runtimedir() }}/", + "file:{{ arch_libdir }}/", + "file:/usr/{{ arch_libdir }}/", + "file:/etc/ssl/certs/ca-certificates.crt", + "file:/etc/default/apport", + "file:/etc/mime.types", + "file:make_data.py", + "file:leader.py", + "file:follower.py", + "file:tensorflow_io.py", +] + +sgx.allowed_files = [ + "file:{{ python.stdlib }}/", + "file:{{ python.distlib }}/", + "file:/usr/local/lib/python3.6/dist-packages/", + "file:/usr/lib/ssl/openssl.cnf", + "file:/usr/lib/gcc", + "file:/usr/bin/ld", + "file:/usr/bin/gcc", + "file:/usr/bin/objdump", + "file:/etc/ethers", + "file:/etc/hosts", + "file:/etc/group", + "file:/etc/passwd", + "file:/etc/ld.so.conf", + "file:/etc/gai.conf", + "file:/etc/host.conf", + "file:/etc/resolv.conf", + "file:/etc/nsswitch.conf", + "file:/etc/sgx_default_qcnl.conf", + "file:/etc/ssl/certs/ca-certificates.crt", + "file:/proc/stat", + "file:/tmp/", + "file:data/", + "file:model/", + "file:/root/.keras/keras.json", + "file:dynamic_config.json", +] + +#sgx.protected_files = [ +# "file:model", +#] diff --git a/sgx/gramine/CI-Examples/wide_n_deep/test-ps-sgx.sh b/sgx/gramine/CI-Examples/wide_n_deep/test-ps-sgx.sh new file mode 100755 index 000000000..afe80a43a --- /dev/null +++ b/sgx/gramine/CI-Examples/wide_n_deep/test-ps-sgx.sh @@ -0,0 +1,87 @@ +#!/bin/bash +set -x + +shopt -s expand_aliases +alias make_logfilter="grep \"mr_enclave\|mr_signer\|isv_prod_id\|isv_svn\"" +alias runtime_logfilter="grep -v \"FUTEX\|measured\|memory entry\|cleaning up\|async event\|shim_exit\"" + +function get_env() { + gramine-sgx-get-token -s python.sig -o /dev/null | grep $1 | awk -F ":" '{print $2}' | xargs +} + +function make_custom_env() { + export DEBUG=0 + export CUDA_VISIBLE_DEVICES="" + export DNNL_VERBOSE=0 + export GRPC_VERBOSITY=ERROR + export GRPC_POLL_STRATEGY=epoll1 + export TF_CPP_MIN_LOG_LEVEL=1 + export TF_GRPC_SGX_RA_TLS_ENABLE=on + export FL_GRPC_SGX_RA_TLS_ENABLE=on + export TF_DISABLE_MKL=0 + export TF_ENABLE_MKL_NATIVE_FORMAT=1 + export parallel_num_threads=$1 + export INTRA_OP_PARALLELISM_THREADS=$parallel_num_threads + export INTER_OP_PARALLELISM_THREADS=$parallel_num_threads + export GRPC_SERVER_CHANNEL_THREADS=4 + export KMP_SETTINGS=1 + export KMP_BLOCKTIME=0 + export MR_ENCLAVE=`get_env mr_enclave` + export MR_SIGNER=`get_env mr_signer` + export ISV_PROD_ID=`get_env isv_prod_id` + export ISV_SVN=`get_env isv_svn` + # network proxy + unset http_proxy https_proxy +} + +ROLE=$1 +if [ "$ROLE" == "data" ]; then + rm -rf data + cp ../tensorflow_io.py . + cp -r $FEDLEARNER_PATH/example/wide_n_deep/*.py . + python make_data.py +elif [ "$ROLE" == "make" ]; then + rm -rf *.log model + make clean && make | make_logfilter + jq ' .sgx_mrs[0].mr_enclave = ''"'`get_env mr_enclave`'" | .sgx_mrs[0].mr_signer = ''"'`get_env mr_signer`'" ' $GRPC_PATH/examples/dynamic_config.json > ./dynamic_config.json + kill -9 `pgrep -f python` + kill -9 `pgrep -f gramine` +elif [ "$ROLE" == "leader" ]; then + rm -rf model/leader + make_custom_env 4 + taskset -c 0-3 stdbuf -o0 gramine-sgx python -u -m fedlearner.trainer.parameter_server localhost:40051 2>&1 | runtime_logfilter | tee -a leader-gramine-ps.log & + sleep 2m + make_custom_env 4 + taskset -c 4-7 stdbuf -o0 gramine-sgx python -u leader.py --local-addr=localhost:50051 \ + --peer-addr=localhost:50053 \ + --data-path=data/leader \ + --checkpoint-path=model/leader/checkpoint \ + --export-path=model/leader/saved_model \ + --save-checkpoint-steps=10 \ + --epoch-num=2 \ + --batch-size=32 \ + --cluster-spec='{"clusterSpec":{"PS":["localhost:40051"]}}' \ + --loglevel=debug 2>&1 | runtime_logfilter | tee -a leader-gramine.log & + if [ "$DEBUG" != "0" ]; then + wait && kill -9 `pgrep -f gramine` + fi +elif [ "$ROLE" == "follower" ]; then + rm -rf model/follower + make_custom_env 4 + taskset -c 0-3 stdbuf -o0 gramine-sgx python -u -m fedlearner.trainer.parameter_server localhost:40061 2>&1 | runtime_logfilter | tee -a follower-gramine-ps.log & + sleep 2m + make_custom_env 4 + taskset -c 4-7 stdbuf -o0 gramine-sgx python -u follower.py --local-addr=localhost:50051 \ + --peer-addr=localhost:50053 \ + --data-path=data/follower \ + --checkpoint-path=model/follower/checkpoint \ + --export-path=model/follower/saved_model \ + --save-checkpoint-steps=10 \ + --epoch-num=2 \ + --batch-size=32 \ + --cluster-spec='{"clusterSpec":{"PS":["localhost:40061"]}}' \ + --loglevel=debug 2>&1 | runtime_logfilter | tee -a follower-gramine.log & + if [ "$DEBUG" != "0" ]; then + wait && kill -9 `pgrep -f gramine` + fi +fi \ No newline at end of file diff --git a/sgx/gramine/CI-Examples/wide_n_deep/test-ps.sh b/sgx/gramine/CI-Examples/wide_n_deep/test-ps.sh new file mode 100755 index 000000000..02d8fc69f --- /dev/null +++ b/sgx/gramine/CI-Examples/wide_n_deep/test-ps.sh @@ -0,0 +1,59 @@ +#!/bin/bash +set -x + +function make_custom_env() { + export CUDA_VISIBLE_DEVICES="" + export DNNL_VERBOSE=0 + export GRPC_VERBOSITY=ERROR + export GRPC_POLL_STRATEGY=epoll1 + export TF_CPP_MIN_LOG_LEVEL=1 + export TF_GRPC_SGX_RA_TLS_ENABLE="" + export FL_GRPC_SGX_RA_TLS_ENABLE="" + export TF_DISABLE_MKL=0 + export TF_ENABLE_MKL_NATIVE_FORMAT=1 + export parallel_num_threads=4 + export INTRA_OP_PARALLELISM_THREADS=$parallel_num_threads + export INTER_OP_PARALLELISM_THREADS=$parallel_num_threads + export GRPC_SERVER_CHANNEL_THREADS=2 + export KMP_SETTINGS=1 + export KMP_BLOCKTIME=0 + # network proxy + unset http_proxy https_proxy +} + +ROLE=$1 +if [ "$ROLE" == "data" ]; then + rm -rf data model *.log + cp ../tensorflow_io.py . + cp -r ${FEDLEARNER_PATH}/example/wide_n_deep/*.py . + python make_data.py +elif [ "$ROLE" == "leader" ]; then + kill -9 `pgrep -f python` + make_custom_env + rm -rf model/leader + taskset -c 0-3 python -u -m fedlearner.trainer.parameter_server localhost:40051 2>&1 | tee -a leader-ps.log & + taskset -c 4-7 python -u leader.py --local-addr=localhost:50051 \ + --peer-addr=localhost:50052 \ + --data-path=data/leader \ + --checkpoint-path=model/leader/checkpoint \ + --export-path=model/leader/saved_model \ + --save-checkpoint-steps=10 \ + --epoch-num=2 \ + --batch-size=32 \ + --cluster-spec='{"clusterSpec":{"PS":["localhost:40051"]}}' \ + --loglevel=debug 2>&1 | tee -a leader-native.log & +elif [ "$ROLE" == "follower" ]; then + make_custom_env + rm -rf model/follower + taskset -c 8-11 python -u -m fedlearner.trainer.parameter_server localhost:40061 2>&1 | tee -a follower-ps.log & + taskset -c 12-15 python -u follower.py --local-addr=localhost:50052 \ + --peer-addr=localhost:50051 \ + --data-path=data/follower \ + --checkpoint-path=model/follower/checkpoint \ + --export-path=model/follower/saved_model \ + --save-checkpoint-steps=10 \ + --epoch-num=2 \ + --batch-size=32 \ + --cluster-spec='{"clusterSpec":{"PS":["localhost:40061"]}}' \ + --loglevel=debug 2>&1 | tee -a follower-native.log & +fi diff --git a/sgx/gramine/patches/ipv6_support.diff b/sgx/gramine/patches/ipv6_support.diff new file mode 100644 index 000000000..75885af19 --- /dev/null +++ b/sgx/gramine/patches/ipv6_support.diff @@ -0,0 +1,166 @@ +diff --git a/libos/src/net/ip.c b/libos/src/net/ip.c +index 20278149..d335ff5b 100644 +--- a/libos/src/net/ip.c ++++ b/libos/src/net/ip.c +@@ -318,6 +318,12 @@ static int set_ipv6_option(struct libos_handle* handle, int optname, void* optva + case IPV6_RECVERR: + /* See the comment in `set_ipv4_option` for why we handle it this way. */ + return 0; ++ case IP_MULTICAST_ALL: ++ attr.socket.ip_multicast_all = !!*(int*)optval; ++ break; ++ case IPV6_MULTICAST_HOPS: ++ attr.socket.ipv6_multicast_hops = !!*(int*)optval; ++ break; + default: + return -ENOPROTOOPT; + } +@@ -529,6 +535,12 @@ static int get_ipv6_option(struct libos_handle* handle, int optname, void* optva + case IPV6_V6ONLY: + val = attr.socket.ipv6_v6only; + break; ++ case IP_MULTICAST_ALL: ++ val = attr.socket.ip_multicast_all; ++ break; ++ case IPV6_MULTICAST_HOPS: ++ val = attr.socket.ipv6_multicast_hops; ++ break; + default: + return -ENOPROTOOPT; + } +diff --git a/pal/include/pal/pal.h b/pal/include/pal/pal.h +index e4f98c01..4cae9ea9 100644 +--- a/pal/include/pal/pal.h ++++ b/pal/include/pal/pal.h +@@ -480,6 +480,8 @@ typedef struct _PAL_STREAM_ATTR { + bool tcp_cork; + bool tcp_nodelay; + bool ipv6_v6only; ++ bool ip_multicast_all; ++ bool ipv6_multicast_hops; + } socket; + }; + } PAL_STREAM_ATTR; +diff --git a/pal/src/host/linux-sgx/pal_host.h b/pal/src/host/linux-sgx/pal_host.h +index b6e00d09..258cbc4c 100644 +--- a/pal/src/host/linux-sgx/pal_host.h ++++ b/pal/src/host/linux-sgx/pal_host.h +@@ -104,6 +104,8 @@ typedef struct { + bool tcp_cork; + bool tcp_nodelay; + bool ipv6_v6only; ++ bool ip_multicast_all; ++ bool ipv6_multicast_hops; + } sock; + + struct { +diff --git a/pal/src/host/linux-sgx/pal_sockets.c b/pal/src/host/linux-sgx/pal_sockets.c +index 08560ba9..cceb6dd6 100644 +--- a/pal/src/host/linux-sgx/pal_sockets.c ++++ b/pal/src/host/linux-sgx/pal_sockets.c +@@ -95,6 +95,8 @@ static PAL_HANDLE create_sock_handle(int fd, enum pal_socket_domain domain, + handle->sock.tcp_cork = false; + handle->sock.tcp_nodelay = false; + handle->sock.ipv6_v6only = false; ++ handle->sock.ip_multicast_all = false; ++ handle->sock.ipv6_multicast_hops = false; + + return handle; + } +@@ -320,6 +322,8 @@ static int attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { + attr->socket.tcp_cork = handle->sock.tcp_cork; + attr->socket.tcp_nodelay = handle->sock.tcp_nodelay; + attr->socket.ipv6_v6only = handle->sock.ipv6_v6only; ++ attr->socket.ip_multicast_all = handle->sock.ip_multicast_all; ++ attr->socket.ipv6_multicast_hops = handle->sock.ipv6_multicast_hops; + + return 0; + }; +@@ -441,6 +445,25 @@ static int attrsetbyhdl_common(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { + handle->sock.ipv6_v6only = attr->socket.ipv6_v6only; + } + ++ if (attr->socket.ip_multicast_all != handle->sock.ip_multicast_all) { ++ int val = attr->socket.ip_multicast_all; ++ int ret = ocall_setsockopt(handle->sock.fd, IPPROTO_IPV6, IP_MULTICAST_ALL, &val, sizeof(val)); ++ if (ret < 0) { ++ return unix_to_pal_error(ret); ++ } ++ handle->sock.ip_multicast_all = attr->socket.ip_multicast_all; ++ } ++ ++ if (attr->socket.ipv6_multicast_hops != handle->sock.ipv6_multicast_hops) { ++ int val = attr->socket.ipv6_multicast_hops; ++ int ret = ocall_setsockopt(handle->sock.fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, ++ sizeof(val)); ++ if (ret < 0) { ++ return unix_to_pal_error(ret); ++ } ++ handle->sock.ipv6_multicast_hops = attr->socket.ipv6_multicast_hops; ++ } ++ + return 0; + } + +diff --git a/pal/src/host/linux/pal_host.h b/pal/src/host/linux/pal_host.h +index 155d72cd..89678877 100644 +--- a/pal/src/host/linux/pal_host.h ++++ b/pal/src/host/linux/pal_host.h +@@ -81,6 +81,8 @@ typedef struct { + bool tcp_cork; + bool tcp_nodelay; + bool ipv6_v6only; ++ bool ip_multicast_all; ++ bool ipv6_multicast_hops; + } sock; + + struct { +diff --git a/pal/src/host/linux/pal_sockets.c b/pal/src/host/linux/pal_sockets.c +index 7757ffc2..ee48843b 100644 +--- a/pal/src/host/linux/pal_sockets.c ++++ b/pal/src/host/linux/pal_sockets.c +@@ -78,6 +78,8 @@ static PAL_HANDLE create_sock_handle(int fd, enum pal_socket_domain domain, + handle->sock.tcp_cork = false; + handle->sock.tcp_nodelay = false; + handle->sock.ipv6_v6only = false; ++ handle->sock.ip_multicast_all = false; ++ handle->sock.ipv6_multicast_hops = false; + + return handle; + } +@@ -351,6 +353,8 @@ static int attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { + attr->socket.tcp_cork = handle->sock.tcp_cork; + attr->socket.tcp_nodelay = handle->sock.tcp_nodelay; + attr->socket.ipv6_v6only = handle->sock.ipv6_v6only; ++ attr->socket.ip_multicast_all = handle->sock.ip_multicast_all; ++ attr->socket.ipv6_multicast_hops = handle->sock.ipv6_multicast_hops; + + return 0; + }; +@@ -487,6 +491,26 @@ static int attrsetbyhdl_common(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) { + handle->sock.ipv6_v6only = attr->socket.ipv6_v6only; + } + ++ if (attr->socket.ip_multicast_all != handle->sock.ip_multicast_all) { ++ int val = attr->socket.ip_multicast_all; ++ int ret = ++ DO_SYSCALL(setsockopt, handle->sock.fd, IPPROTO_IPV6, IP_MULTICAST_ALL, &val, sizeof(val)); ++ if (ret < 0) { ++ return unix_to_pal_error(ret); ++ } ++ handle->sock.ip_multicast_all = attr->socket.ip_multicast_all; ++ } ++ ++ if (attr->socket.ipv6_multicast_hops != handle->sock.ipv6_multicast_hops) { ++ int val = attr->socket.ipv6_multicast_hops; ++ int ret = DO_SYSCALL(setsockopt, handle->sock.fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &val, ++ sizeof(val)); ++ if (ret < 0) { ++ return unix_to_pal_error(ret); ++ } ++ handle->sock.ipv6_multicast_hops = attr->socket.ipv6_multicast_hops; ++ } ++ + return 0; + } + diff --git a/sgx/gramine/patches/ra_tls.diff b/sgx/gramine/patches/ra_tls.diff new file mode 100644 index 000000000..c7dd5fa90 --- /dev/null +++ b/sgx/gramine/patches/ra_tls.diff @@ -0,0 +1,13 @@ +diff --git a/tools/sgx/ra-tls/ra_tls.h b/tools/sgx/ra-tls/ra_tls.h +index cb5a7805..3968f3a2 100644 +--- a/tools/sgx/ra-tls/ra_tls.h ++++ b/tools/sgx/ra-tls/ra_tls.h +@@ -61,7 +61,7 @@ int verify_quote_body_against_envvar_measurements(const sgx_quote_body_t* quote_ + __attribute__ ((visibility("hidden"))) + int ra_tls_verify_callback(void* data, mbedtls_x509_crt* crt, int depth, uint32_t* flags); + +-__attribute__ ((visibility("hidden"))) ++__attribute__ ((visibility("default"))) + int ra_tls_create_key_and_crt(mbedtls_pk_context* key, mbedtls_x509_crt* crt); + + /*! diff --git a/sgx/graphene/Examples/grpc/cpp/helloworld/Makefile b/sgx/graphene/Examples/grpc/cpp/helloworld/Makefile deleted file mode 100644 index 2e66813d0..000000000 --- a/sgx/graphene/Examples/grpc/cpp/helloworld/Makefile +++ /dev/null @@ -1,104 +0,0 @@ -# Build Redis as follows: -# -# - make -- create non-SGX no-debug-log manifest -# - make SGX=1 -- create SGX no-debug-log manifest -# - make SGX=1 DEBUG=1 -- create SGX debug-log manifest -# -# Any of these invocations clones Redis' git repository and builds Redis in -# default configuration and in the latest-to-date (5.0.5) version. -# -# By default, Redis uses poll/epoll mechanism of Linux. To build Redis with -# select, use `make USE_SELECT=1`. For correct re-builds, always clean up -# Redis source code beforehand via `make distclean`. -# -# Use `make clean` to remove Graphene-generated files and `make distclean` to -# additionally remove the cloned Redis git repository. - -################################# CONSTANTS ################################### - -# Relative path to Graphene root -GRAPHENEDIR ?= ../../.. -SGX_SIGNER_KEY ?= $(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem -INSTALL_PREFIX ?= /usr/local -export PATH := $(INSTALL_PREFIX)/bin:$(PATH) - -ifeq ($(DEBUG),1) -GRAPHENE_LOG_LEVEL = debug -else -GRAPHENE_LOG_LEVEL = error -endif - -.PHONY: all -all: grpc-server.manifest -ifeq ($(SGX),1) -all: grpc-server.manifest.sgx grpc-server.sig grpc-server.token -endif - -include $(GRAPHENEDIR)/Scripts/Makefile.configs - -################################ gRPC MANIFEST ############################### - -# The template file contains almost all necessary information to run grpc -# under Graphene / Graphene-SGX. We create grpc-server.manifest (to be run under -# non-SGX Graphene) by simply replacing variables in the template file via sed. - -grpc-server.manifest: grpc-server.manifest.template - graphene-manifest \ - -Dlog_level=$(GRAPHENE_LOG_LEVEL) \ - -Darch_libdir=$(ARCH_LIBDIR) \ - $< > $@ - -# Manifest for Graphene-SGX requires special "graphene-sgx-sign" procedure. This procedure measures -# all Redis trusted files, adds the measurement to the resulting manifest.sgx file (among other, -# less important SGX options) and creates redis-server.sig (SIGSTRUCT object). -# -# Graphene-SGX requires EINITTOKEN and SIGSTRUCT objects (see SGX hardware ABI, in particular EINIT -# instruction). The "graphene-sgx-get-token" script generates EINITTOKEN based on a SIGSTRUCT and -# puts it in .token file. Note that filenames must be the same as the manifest name (i.e., -# "redis-server"). EINITTOKEN must be generated on the machine where the application will run, not -# where it was built. - -# Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), -# we need to hack around. -grpc-server.sig grpc-server.manifest.sgx: sgx_outputs - @: - -.INTERMEDIATE: sgx_outputs -sgx_outputs: grpc-server.manifest - graphene-sgx-sign \ - --key $(SGX_SIGNER_KEY) \ - --manifest grpc-server.manifest \ - --output grpc-server.manifest.sgx - -grpc-server.token: grpc-server.sig - graphene-sgx-get-token --output $@ --sig $< - -############################## RUNNING TESTS ################################## -.PHONY: start-native-server -start-native-server: all - ./grpc-server -ssl=1 - -ifeq ($(SGX),) -GRAPHENE = graphene-direct -else -GRAPHENE = graphene-sgx -endif - -.PHONY: start-graphene-server -start-graphene-server: all - $(GRAPHENE) grpc-server - -################################## CLEANUP #################################### - -.PHONY: clean -clean: - $(RM) *.token *.sig *.manifest.sgx *.manifest - -.PHONY: distclean -distclean: clean - $(RM) -rf grpc .local - -################################## RUN #################################### -run: - graphene-sgx grpc-server - diff --git a/sgx/graphene/Examples/grpc/cpp/helloworld/build.sh b/sgx/graphene/Examples/grpc/cpp/helloworld/build.sh deleted file mode 100755 index bf4a35c49..000000000 --- a/sgx/graphene/Examples/grpc/cpp/helloworld/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -set -e - -export MBEDTLS_PATH=${GRAPHENEDIR}/Examples/ra-tls-mbedtls -export HELLO_PATH=${GRPC_PATH}/examples/cpp/helloworld - -# Build ra-tls-mbedtls -if [ ! -d "${MBEDTLS_PATH}/mbedtls" ]; then - ${MBEDTLS_PATH}/build_install.sh -fi - -# build c++ example -${HELLO_PATH}/build.sh - -cp ${HELLO_PATH}/build/greeter_server ./grpc-server -cp ${HELLO_PATH}/build/greeter_client ./grpc-client - -# build with graphene -make clean -make - -ls -l /usr/lib/x86_64-linux-gnu/libsgx_dcap_quoteverify.s* diff --git a/sgx/graphene/Examples/grpc/cpp/helloworld/grpc-server.manifest.template b/sgx/graphene/Examples/grpc/cpp/helloworld/grpc-server.manifest.template deleted file mode 100644 index bd78b1706..000000000 --- a/sgx/graphene/Examples/grpc/cpp/helloworld/grpc-server.manifest.template +++ /dev/null @@ -1,148 +0,0 @@ -# gRPC server manifest file example -# -# This manifest was prepared and tested on Ubuntu 18.04. - -################################## GRAPHENE ################################### - -# LibOS layer library of Graphene. There is currently only one implementation, -# so it is always set to libsysdb.so. Note that GRAPHENEDIR macro is expanded -# to relative path to Graphene repository in the Makefile as part of the -# build process. -loader.preload = "file:{{ graphene.libos }}" -libos.entrypoint = "file:grpc-server" - -# Verbosity of Graphene debug log (none/error/warning/debug/trace/all). Note -# that GRAPHENE_LOG_LEVEL macro is expanded in the Makefile as part of the -# building process: the default is "error" for non-debug builds, and "debug" -# for debug builds. -loader.log_level = "{{ log_level }}" - -################################# ARGUMENTS ################################### - -# Read application arguments directly from the command line. Don't use this on production! -loader.insecure__use_cmdline_argv = 1 - -################################# ENV VARS #################################### - -# Specify paths to search for libraries. The usual LD_LIBRARY_PATH syntax -# applies. Paths must be in-Graphene visible paths, not host-OS paths (i.e., -# paths must be taken from fs.mount.xxx.path, not fs.mount.xxx.uri). -# -# In case of gRPC: -# - /lib is searched for Glibc libraries (ld, libc, libpthread) -# - {{ arch_libdir }} is searched for Name Service Switch (NSS) libraries -loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}" - -################################## SIGNALS #################################### - -# Allow for injecting SIGTERM signal from the host. -sys.enable_sigterm_injection = 1 - -################################## REMOTE ATTESTATION #################################### - -# Request remote attestation functionality from Graphene -sgx.remote_attestation = 1 - -################################# MOUNT FS ################################### - -# General notes: -# - There is only one supported type of mount points: 'chroot'. -# - Directory names are (somewhat confusingly) prepended by 'file:'. -# - Names of mount entries (lib, lib2, lib3) are irrelevant but must be unique. -# - In-Graphene visible path names may be arbitrary but we reuse host-OS URIs -# for simplicity (except for the first 'lib' case). - -# Mount host-OS directory to Graphene glibc/runtime libraries (in 'uri') into -# in-Graphene visible directory /lib (in 'path'). Note that GRAPHENEDIR macro -# is expanded to relative path to Graphene repository in the Makefile as part -# of the build process. -fs.mount.lib.type = "chroot" -fs.mount.lib.path = "/lib" -fs.mount.lib.uri = "file:{{ graphene.runtimedir() }}" - -# Mount host-OS directory to Name Service Switch (NSS) libraries (in 'uri') -# into in-Graphene visible directory /lib/x86_64-linux-gnu (in 'path'). -fs.mount.lib2.type = "chroot" -fs.mount.lib2.path = "{{ arch_libdir }}" -fs.mount.lib2.uri = "file:{{ arch_libdir }}" - -fs.mount.lib3.type = "chroot" -fs.mount.lib3.path = "/usr/{{ arch_libdir }}" -fs.mount.lib3.uri = "file:/usr/{{ arch_libdir }}" - -# Mount host-OS directory to NSS files required by Glibc + NSS libs (in 'uri') -# into in-Graphene visible directory /etc (in 'path'). -fs.mount.etc.type = "chroot" -fs.mount.etc.path = "/etc" -fs.mount.etc.uri = "file:/etc" - -############################### SGX: GENERAL ################################## - -# Set enclave size (somewhat arbitrarily) to 1024MB. Recall that SGX v1 requires -# to specify enclave size at enclave creation time. If Redis exhausts these -# 1024MB then it will start failing with random errors. Greater enclave sizes -# result in longer startup times, smaller enclave sizes are not enough for -# typical Redis workloads. -sgx.enclave_size = "1024M" - -sgx.nonpie_binary = 1 - -# Set maximum number of in-enclave threads (somewhat arbitrarily) to 8. Recall -# that SGX v1 requires to specify the maximum number of simulteneous threads at -# enclave creation time. -# -# Note that internally Graphene may spawn two additional threads, one for IPC -# and one for asynchronous events/alarms. Redis is technically single-threaded -# but spawns couple additional threads to do background bookkeeping. Therefore, -# specifying '8' allows to run a maximum of 6 Redis threads which is enough. -sgx.thread_num = 8 - -############################# SGX: TRUSTED FILES ############################### - -# Specify all files used by Redis and its dependencies (including all -# libraries which can be loaded at runtime via dlopen). The paths to files -# are host-OS paths. These files will be searched for in in-Graphene visible -# paths according to mount points above. -# -# As part of the build process, Graphene-SGX script (`graphene-sgx-sign`) finds each -# specified file, measures its hash, and outputs the hash in auto-generated -# entry 'sgx.trusted_checksum.xxx' in auto-generated redis-server.manifest.sgx. -# Note that this happens on the developer machine or a build server. -# -# At runtime, during loading of each "trusted file", Graphene-SGX measures its hash -# and compares with the one specified in 'sgx.trusted_checksum.xxx'. If hashes -# match, this file is trusted and allowed to be loaded and used. Note that -# this happens on the client machine. - -sgx.trusted_files.grpc-server = "file:grpc-server" -#sgx.trusted_files.libra_tls_attest = "file:ra-tls-mbedtls" - -sgx.trusted_files.runtime = "file:{{ graphene.runtimedir() }}/" -sgx.trusted_files.arch_libdir = "file:{{ arch_libdir }}/" -sgx.trusted_files.usr_arch_libdir = "file:/usr/{{ arch_libdir }}/" - -# Trusted no-library files include configuration files, read-only files, and -# other static files. It is useful to specify such files here to make sure -# they are not maliciously modified (modifications will be detected as hash -# mismatch by Graphene-SGX). -# -# Redis by default does not use configuration files, so this section is empty. -# sgx.trusted_files.config = "file:" - -############################# SGX: ALLOWED FILES ############################### - -# Specify all non-static files used by app. These files may be accessed by -# Graphene-SGX but their integrity is not verified (Graphene-SGX does not -# measure their hashes). This may pose a security risk! - -# Name Service Switch (NSS) files. Glibc reads these files as part of name- -# service information gathering. For more info, see 'man nsswitch.conf'. -sgx.allowed_files.nsswitch = "file:/etc/nsswitch.conf" -sgx.allowed_files.ethers = "file:/etc/ethers" -sgx.allowed_files.hosts = "file:/etc/hosts" -sgx.allowed_files.group = "file:/etc/group" -sgx.allowed_files.passwd = "file:/etc/passwd" - -# getaddrinfo(3) configuration file. Glibc reads this file to correctly find -# network addresses. For more info, see 'man gai.conf'. -sgx.allowed_files.gaiconf = "file:/etc/gai.conf" diff --git a/sgx/graphene/Examples/mnist/Makefile b/sgx/graphene/Examples/mnist/Makefile deleted file mode 100644 index 3dabb5638..000000000 --- a/sgx/graphene/Examples/mnist/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# Use one of the following commands to build the manifest for Python3: -# -# - make Building for Linux -# - make DEBUG=1 Building for Linux (with Graphene debug output) -# - make SGX=1 Building for SGX -# - make SGX=1 DEBUG=1 Building for SGX (with Graphene debug output) -# -# Use `make clean` to remove Graphene-generated files. - -include ../../Scripts/Makefile.configs - -# Relative path to Graphene root -GRAPHENEDIR ?= ../.. -SGX_SIGNER_KEY ?= $(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem - -ifeq ($(DEBUG),1) -GRAPHENE_LOG_LEVEL = debug -else -GRAPHENE_LOG_LEVEL = error -endif - -ifeq ($(ROLE),1) -GRAPHENE_LOG_FILE = leader-graphene-sgx.log -else -GRAPHENE_LOG_FILE = follower-graphene-sgx.log -endif - -.PHONY: all -all: python.manifest -ifeq ($(SGX),1) -all: python.manifest.sgx python.sig python.token -endif - -python.manifest: python.manifest.template - graphene-manifest \ - -Dlog_level=$(GRAPHENE_LOG_LEVEL) \ - -Dlog_file=$(GRAPHENE_LOG_FILE) \ - -Darch_libdir=$(ARCH_LIBDIR) \ - -Dsession_parallelism=$(session_parallelism) \ - -Dintra_op_parallelism=$(intra_op_parallelism) \ - -Dinter_op_parallelism=$(inter_op_parallelism) \ - -DOMP_NUM_THREADS=$(OMP_NUM_THREADS) \ - -DMKL_NUM_THREADS=$(MKL_NUM_THREADS) \ - -Dentrypoint=$(realpath $(shell sh -c "command -v python3")) \ - $< >$@ - -# Python manifests for SGX: -# Generating the SGX-specific manifest (python.manifest.sgx), the enclave signature, -# and the token for enclave initialization. - -python.manifest.sgx: python.manifest - graphene-sgx-sign \ - --key $(SGX_SIGNER_KEY) \ - --manifest $< \ - --output $@ - -python.sig: python.manifest.sgx - -python.token: python.sig - graphene-sgx-get-token --output $@ --sig $< - -.PHONY: clean -clean: - $(RM) *.manifest *.manifest.sgx *.token *.sig OUTPUT* *.PID TEST_STDOUT TEST_STDERR - $(RM) -r scripts/__pycache__ - -.PHONY: distclean -distclean: clean diff --git a/sgx/graphene/Examples/mnist/follower.py b/sgx/graphene/Examples/mnist/follower.py deleted file mode 100644 index b81cf1e23..000000000 --- a/sgx/graphene/Examples/mnist/follower.py +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright 2020 The FedLearner Authors. All Rights Reserved. -# -# 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. - -# coding: utf-8 -# pylint: disable=no-else-return, inconsistent-return-statements - -import tensorflow.compat.v1 as tf -import fedlearner.trainer as flt - - -ROLE = 'follower' -parser = flt.trainer_worker.create_argument_parser() -parser.add_argument('--batch-size', type=int, default=256, - help='Training batch size.') -args = parser.parse_args() - - -def input_fn(bridge, trainer_master): - dataset = flt.data.DataBlockLoader(args.batch_size, ROLE, - bridge, trainer_master).make_dataset() - - def parse_fn(example): - feature_map = dict() - feature_map["example_id"] = tf.FixedLenFeature([], tf.string) - feature_map["x"] = tf.FixedLenFeature([28 * 28 // 2], tf.float32) - features = tf.parse_example(example, features=feature_map) - return features, dict(y=tf.constant(0)) - - dataset = dataset.map(map_func=parse_fn, - num_parallel_calls=tf.data.experimental.AUTOTUNE) - return dataset - -def serving_input_receiver_fn(): - feature_map = { - "example_id": tf.FixedLenFeature([], tf.string), - "x": tf.FixedLenFeature([28 * 28 // 2], tf.float32), - } - record_batch = tf.placeholder(dtype=tf.string, name='examples') - features = tf.parse_example(record_batch, features=feature_map) - return tf.estimator.export.ServingInputReceiver(features, - {'examples': record_batch}) - - -def model_fn(model, features, labels, mode): - x = features['x'] - - w1f = tf.get_variable('w1f', - shape=[28 * 28 // 2, 128], - dtype=tf.float32, - initializer=tf.random_uniform_initializer( - -0.01, 0.01)) - b1f = tf.get_variable('b1f', - shape=[128], - dtype=tf.float32, - initializer=tf.zeros_initializer()) - - act1_f = tf.nn.relu(tf.nn.bias_add(tf.matmul(x, w1f), b1f)) - - if mode == tf.estimator.ModeKeys.TRAIN: - gact1_f = model.send('act1_f', act1_f, require_grad=True) - optimizer = tf.train.GradientDescentOptimizer(0.1) - train_op = model.minimize( - optimizer, - act1_f, - grad_loss=gact1_f, - global_step=tf.train.get_or_create_global_step()) - return model.make_spec(mode, - loss=tf.math.reduce_mean(act1_f), - train_op=train_op) - - if mode == tf.estimator.ModeKeys.EVAL: - model.send('act1_f', act1_f, require_grad=False) - fake_loss = tf.reduce_mean(act1_f) - return model.make_spec(mode=mode, loss=fake_loss) - - # mode == tf.estimator.ModeKeys.PREDICT: - return model.make_spec(mode=mode, predictions={'act1_f': act1_f}) - - -if __name__ == '__main__': - parser = flt.trainer_worker.create_argument_parser() - flt.trainer_worker.train( - ROLE, parser.parse_args(), input_fn, - model_fn, serving_input_receiver_fn) diff --git a/sgx/graphene/Examples/mnist/leader.py b/sgx/graphene/Examples/mnist/leader.py deleted file mode 100644 index 43e82bc42..000000000 --- a/sgx/graphene/Examples/mnist/leader.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright 2020 The FedLearner Authors. All Rights Reserved. -# -# 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. - -# coding: utf-8 -# pylint: disable=no-else-return, inconsistent-return-statements - -import tensorflow.compat.v1 as tf -import fedlearner.trainer as flt - -ROLE = 'leader' - -parser = flt.trainer_worker.create_argument_parser() -parser.add_argument('--batch-size', type=int, default=256, - help='Training batch size.') -args = parser.parse_args() - -def input_fn(bridge, trainer_master): - dataset = flt.data.DataBlockLoader(args.batch_size, ROLE, - bridge, trainer_master).make_dataset() - - def parse_fn(example): - feature_map = dict() - feature_map['example_id'] = tf.FixedLenFeature([], tf.string) - feature_map['x'] = tf.FixedLenFeature([28 * 28 // 2], tf.float32) - feature_map['y'] = tf.FixedLenFeature([], tf.int64) - features = tf.parse_example(example, features=feature_map) - return features, dict(y=features.pop('y')) - - dataset = dataset.map(map_func=parse_fn, - num_parallel_calls=tf.data.experimental.AUTOTUNE) - return dataset - - -def serving_input_receiver_fn(): - feature_map = { - "example_id": tf.FixedLenFeature([], tf.string), - "x": tf.FixedLenFeature([28 * 28 // 2], tf.float32), - } - record_batch = tf.placeholder(dtype=tf.string, name='examples') - features = tf.parse_example(record_batch, features=feature_map) - features['act1_f'] = tf.placeholder(dtype=tf.float32, name='act1_f') - receiver_tensors = {'examples': record_batch, 'act1_f': features['act1_f']} - return tf.estimator.export.ServingInputReceiver(features, receiver_tensors) - - -def model_fn(model, features, labels, mode): - x = features['x'] - - w1l = tf.get_variable('w1l', - shape=[28 * 28 // 2, 128], - dtype=tf.float32, - initializer=tf.random_uniform_initializer( - -0.01, 0.01)) - b1l = tf.get_variable('b1l', - shape=[128], - dtype=tf.float32, - initializer=tf.zeros_initializer()) - w2 = tf.get_variable('w2', - shape=[128 * 2, 10], - dtype=tf.float32, - initializer=tf.random_uniform_initializer( - -0.01, 0.01)) - b2 = tf.get_variable('b2', - shape=[10], - dtype=tf.float32, - initializer=tf.zeros_initializer()) - - act1_l = tf.nn.relu(tf.nn.bias_add(tf.matmul(x, w1l), b1l)) - if mode == tf.estimator.ModeKeys.TRAIN: - act1_f = model.recv('act1_f', tf.float32, require_grad=True) - elif mode == tf.estimator.ModeKeys.EVAL: - act1_f = model.recv('act1_f', tf.float32, require_grad=False) - else: - act1_f = features['act1_f'] - act1 = tf.concat([act1_l, act1_f], axis=1) - logits = tf.nn.bias_add(tf.matmul(act1, w2), b2) - - if mode == tf.estimator.ModeKeys.PREDICT: - return model.make_spec(mode=mode, predictions=logits) - - y = labels['y'] - loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, - logits=logits) - loss = tf.math.reduce_mean(loss) - - if mode == tf.estimator.ModeKeys.EVAL: - classes = tf.argmax(logits, axis=1) - acc_pair = tf.metrics.accuracy(y, classes) - return model.make_spec( - mode=mode, loss=loss, eval_metric_ops={'accuracy': acc_pair}) - - # mode == tf.estimator.ModeKeys.TRAIN - optimizer = tf.train.GradientDescentOptimizer(0.1) - train_op = model.minimize( - optimizer, loss, global_step=tf.train.get_or_create_global_step()) - correct = tf.nn.in_top_k(predictions=logits, targets=y, k=1) - acc = tf.reduce_mean(input_tensor=tf.cast(correct, tf.float32)) - logging_hook = tf.train.LoggingTensorHook( - {"loss" : loss, "acc" : acc}, every_n_iter=10) - return model.make_spec( - mode=mode, loss=loss, train_op=train_op, - training_hooks=[logging_hook]) - - -if __name__ == '__main__': - flt.trainer_worker.train( - ROLE, args, input_fn, - model_fn, serving_input_receiver_fn) diff --git a/sgx/graphene/Examples/mnist/make_data.py b/sgx/graphene/Examples/mnist/make_data.py deleted file mode 100644 index e7964b40a..000000000 --- a/sgx/graphene/Examples/mnist/make_data.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2020 The FedLearner Authors. All Rights Reserved. -# -# 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. - -# coding: utf-8 - -import os -import shutil -import numpy as np -import tensorflow as tf - -from tensorflow.core.example.example_pb2 import Example -from tensorflow.core.example.feature_pb2 import FloatList, Features, Feature, \ - Int64List, BytesList - -current_dir = os.path.dirname(__file__) -shutil.rmtree(os.path.join(current_dir, 'data'), ignore_errors=True) -os.makedirs(os.path.join(current_dir, 'data/leader')) -os.makedirs(os.path.join(current_dir, 'data/follower')) - - -(x, y), _ = tf.keras.datasets.mnist.load_data() -x = x.reshape(x.shape[0], -1).astype(np.float32) / 255.0 -y = y.astype(np.int64) - -xl = x[:, :x.shape[1]//2] -xf = x[:, x.shape[1]//2:] - -N = 10 -chunk_size = x.shape[0]//N - -for i in range(N): - filename_l = os.path.join(current_dir, 'data/leader/%02d.tfrecord'%i) - filename_f = os.path.join(current_dir, 'data/follower/%02d.tfrecord'%i) - fl = tf.io.TFRecordWriter(filename_l) - ff = tf.io.TFRecordWriter(filename_f) - - for j in range(chunk_size): - idx = i*chunk_size + j - features_l = {} - features_l['example_id'] = Feature( - bytes_list=BytesList(value=[str(idx).encode('utf-8')])) - features_l['y'] = Feature(int64_list=Int64List(value=[y[idx]])) - features_l['x'] = Feature(float_list=FloatList(value=list(xl[idx]))) - fl.write( - Example(features=Features(feature=features_l)).SerializeToString()) - - features_f = {} - features_f['example_id'] = Feature( - bytes_list=BytesList(value=[str(idx).encode('utf-8')])) - features_f['x'] = Feature(float_list=FloatList(value=list(xf[idx]))) - ff.write( - Example(features=Features(feature=features_f)).SerializeToString()) - - fl.close() - ff.close() diff --git a/sgx/graphene/Examples/mnist/python.manifest.template b/sgx/graphene/Examples/mnist/python.manifest.template deleted file mode 100644 index a29f38f94..000000000 --- a/sgx/graphene/Examples/mnist/python.manifest.template +++ /dev/null @@ -1,131 +0,0 @@ -# Python manifest example - -libos.entrypoint = "file:{{ entrypoint }}" - -loader.pal_internal_mem_size = "200M" - -# Path to the library OS -loader.preload = "file:{{ graphene.libos }}" - -# Graphene log level -loader.log_level = "{{ log_level }}" -# loader.log_file = "{{ log_file }}" - -# Read application arguments directly from the command line. Don't use this on production! -loader.insecure__use_cmdline_argv = 1 - -# Environment variables for Python -loader.env.LD_LIBRARY_PATH = "{{ python.stdlib }}/lib:/lib:{{ arch_libdir }}:/usr/lib:/usr/{{ arch_libdir }}" -loader.env.tensorflow_session_parallelism = "{{ session_parallelism }}" -loader.env.tensorflow_intra_op_parallelism = "{{ intra_op_parallelism }}" -loader.env.tensorflow_inter_op_parallelism = "{{ inter_op_parallelism }}" -loader.env.OMP_NUM_THREADS = "{{ OMP_NUM_THREADS }}" -loader.env.MKL_NUM_THREADS = "{{ MKL_NUM_THREADS }}" - -# Allow for injecting SIGTERM signal from the host. -sys.enable_sigterm_injection = 1 - -# Mounted FSes. The following "chroot" FSes mount a part of the host FS into the -# guest. Other parts of the host FS will not be available in the guest. - -# Default glibc files, mounted from the Runtime directory in GRAPHENEDIR. -fs.mount.lib.type = "chroot" -fs.mount.lib.path = "/lib" -fs.mount.lib.uri = "file:{{ graphene.runtimedir() }}" - -# Host-level libraries (e.g., /lib/x86_64-linux-gnu) required by the Python executable -fs.mount.lib2.type = "chroot" -fs.mount.lib2.path = "{{ arch_libdir }}" -fs.mount.lib2.uri = "file:{{ arch_libdir }}" - -# Host-level directory (/usr) required by the Python executable -fs.mount.usr.type = "chroot" -fs.mount.usr.path = "/usr" -fs.mount.usr.uri = "file:/usr" - -# Mount $PYTHONHOME -fs.mount.pyhome.type = "chroot" -fs.mount.pyhome.path = "{{ python.stdlib }}" -fs.mount.pyhome.uri = "file:{{ python.stdlib }}" - -# Mount $PYTHONDISTHOME -fs.mount.pydisthome.type = "chroot" -fs.mount.pydisthome.path = "{{ python.distlib }}" -fs.mount.pydisthome.uri = "file:{{ python.distlib }}" - -# Mount /tmp -fs.mount.tmp.type = "chroot" -fs.mount.tmp.path = "/tmp" -fs.mount.tmp.uri = "file:/tmp" - -# Mount /etc -fs.mount.etc.type = "chroot" -fs.mount.etc.path = "/etc" -fs.mount.etc.uri = "file:/etc" - -# SGX general options - -# Set the virtual memory size of the SGX enclave. For SGX v1, the enclave -# size must be specified during signing. If Python needs more virtual memory -# than the enclave size, Graphene will not be able to allocate it. -sgx.enclave_size = "32G" - -# Graphene creates stacks of 256KB by default. It is not enough for SciPy/NumPy -# packages, e.g., libopenblas dependency assumes more than 512KB-sized stacks. -sys.stack.size = "16M" - -# Set the maximum number of enclave threads. For SGX v1, the number of enclave -# TCSes must be specified during signing, so the application cannot use more -# threads than the number of TCSes. Note that Graphene also creates an internal -# thread for handling inter-process communication (IPC), and potentially another -# thread for asynchronous events. Therefore, the actual number of threads that -# the application can create is (sgx.thread_num - 2). -sgx.thread_num = 1024 - -sgx.nonpie_binary = 1 - -sgx.remote_attestation = 0 - -# SGX trusted libraries - -sgx.trusted_files.python = "file:{{ entrypoint }}" - -sgx.trusted_files.runtime = "file:{{ graphene.runtimedir() }}/" -sgx.trusted_files.arch_libdir = "file:{{ arch_libdir }}/" -sgx.trusted_files.usr_arch_libdir = "file:/usr/{{ arch_libdir }}/" -sgx.trusted_files.python_dir = "file:{{ python.stdlib }}/" -sgx.trusted_files.dist = "file:{{ python.distlib }}/" - -# etc files required by Python -sgx.trusted_files.mimetypes = "file:/etc/mime.types" -sgx.trusted_files.defapport = "file:/etc/default/apport" - -# Name Service Switch (NSS) and getaddrinfo(3) configuration files -sgx.allowed_files.nsswitch = "file:/etc/nsswitch.conf" -sgx.allowed_files.ethers = "file:/etc/ethers" -sgx.allowed_files.hosts = "file:/etc/hosts" -sgx.allowed_files.group = "file:/etc/group" -sgx.allowed_files.passwd = "file:/etc/passwd" -sgx.allowed_files.gaiconf = "file:/etc/gai.conf" -sgx.allowed_files.hostconf = "file:/etc/host.conf" -sgx.allowed_files.resolv = "file:/etc/resolv.conf" -sgx.allowed_files.proc_stat = "file:/proc/stat" - -# SGX untrusted (allowed) files/directories -sgx.allowed_files.tmp = "file:/tmp" - -# Project Configure - -fs.mount.keras.type = "chroot" -fs.mount.keras.path = "/root/.keras/keras.json" -fs.mount.keras.uri = "file:/root/.keras/keras.json" - -sgx.allowed_files.project_project_py36dist = "file:/usr/local/lib/python3.6/dist-packages" -sgx.allowed_files.project_keras = "file:/root/.keras/keras.json" -sgx.allowed_files.project_model = "file:model" -sgx.allowed_files.project_data = "file:data" -sgx.allowed_files.tensorflow_io = "file:tensorflow_io.py" - -sgx.trusted_files.project_makedata = "file:make_data.py" -sgx.trusted_files.project_leader = "file:leader.py" -sgx.trusted_files.project_follower = "file:follower.py" diff --git a/sgx/graphene/Examples/mnist/test-sgx.sh b/sgx/graphene/Examples/mnist/test-sgx.sh deleted file mode 100755 index fc2769bcf..000000000 --- a/sgx/graphene/Examples/mnist/test-sgx.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -set -e - -shopt -s expand_aliases -alias logfilter="grep -v \"FUTEX\|measured\|memory entry\|cleaning up\|async event\|shim_exit\"" - -export CUDA_VISIBLE_DEVICES="" - -ROLE=$1 -if [ "$ROLE" == "data" ]; then - rm -rf data - python make_data.py -fi - -unset http_proxy https_proxy - -export DEBUG=0 -export parallel_num_threads=16 -export session_parallelism=0 -export intra_op_parallelism=${parallel_num_threads} -export inter_op_parallelism=${parallel_num_threads} -export OMP_NUM_THREADS=${parallel_num_threads} -export MKL_NUM_THREADS=${parallel_num_threads} - -if [ "$ROLE" == "leader" ]; then - rm -rf model/leader leader-graphene-python.log - make clean && make ROLE=1 - taskset -c 0-15 graphene-sgx python -u leader.py --local-addr=localhost:50051 \ - --peer-addr=localhost:50052 \ - --data-path=data/leader \ - --checkpoint-path=model/leader/checkpoint \ - --export-path=model/leader/saved_model \ - --save-checkpoint-steps=10 \ - --epoch-num=2 \ - --loglevel=debug 2>&1 | logfilter | tee -a leader-graphene-python.log & - if [ "$DEBUG" != "0" ]; then - wait && kill -9 `pgrep -f graphene` - fi -elif [ "$ROLE" == "follower" ]; then - rm -rf model/follower follower-graphene-python.log - make clean && make ROLE=0 - taskset -c 16-31 graphene-sgx python -u follower.py --local-addr=localhost:50052 \ - --peer-addr=localhost:50051 \ - --data-path=data/follower \ - --checkpoint-path=model/follower/checkpoint \ - --export-path=model/follower/saved_model \ - --save-checkpoint-steps=10 \ - --epoch-num=2 \ - --loglevel=debug 2>&1 | logfilter | tee -a follower-graphene-python.log & - if [ "$DEBUG" != "0" ]; then - wait && kill -9 `pgrep -f graphene` - fi -fi diff --git a/sgx/graphene/Examples/mnist/test.sh b/sgx/graphene/Examples/mnist/test.sh deleted file mode 100755 index 0f8381c9a..000000000 --- a/sgx/graphene/Examples/mnist/test.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -set -e - -export CUDA_VISIBLE_DEVICES="" - -rm -rf model # data - -python make_data.py - -unset http_proxy https_proxy - -python -u leader.py --local-addr=localhost:50051 \ - --peer-addr=localhost:50052 \ - --data-path=data/leader \ - --checkpoint-path=model/leader/checkpoint \ - --export-path=model/leader/saved_model \ - --save-checkpoint-steps=10 \ - --epoch-num=2 \ - --loglevel=info & - -sleep 5s - -python -u follower.py --local-addr=localhost:50052 \ - --peer-addr=localhost:50051 \ - --data-path=data/follower \ - --checkpoint-path=model/follower/checkpoint \ - --export-path=model/follower/saved_model \ - --save-checkpoint-steps=10 \ - --epoch-num=2 \ - --loglevel=info & - -wait -echo "test done" diff --git a/sgx/graphene/Examples/ra-tls-mbedtls/build_install.sh b/sgx/graphene/Examples/ra-tls-mbedtls/build_install.sh deleted file mode 100755 index 092069143..000000000 --- a/sgx/graphene/Examples/ra-tls-mbedtls/build_install.sh +++ /dev/null @@ -1,21 +0,0 @@ -set -e - -export QUOTE_VERIFY_PATH=${ISGX_DRIVER_PATH}/QuoteVerification -export MBEDTLS_PATH=${GRAPHENEDIR}/Examples/ra-tls-mbedtls - -# rm -rf /usr/lib/x86_64-linux-gnu/libsgx_dcap_quoteverify.s* -# cp libsgx_dcap_quoteverify.s* from PCCS to /usr/lib/x86_64-linux-gnu - -make -C ${GRAPHENEDIR}/Pal/src/host/Linux-SGX/tools/ra-tls dcap - -cd ${MBEDTLS_PATH} - -make clean -make app dcap - -cp -r ${MBEDTLS_PATH}/mbedtls/install/include ${INSTALL_PREFIX} -cp -r ${MBEDTLS_PATH}/libs/* /usr/lib/x86_64-linux-gnu - -ls -l /usr/lib/x86_64-linux-gnu/libsgx_dcap_quoteverify.s* - -cd - diff --git a/sgx/graphene/Examples/ra-tls-secret-prov/build.sh b/sgx/graphene/Examples/ra-tls-secret-prov/build.sh deleted file mode 100755 index 3aaddb2ec..000000000 --- a/sgx/graphene/Examples/ra-tls-secret-prov/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -set -e - -make -C ${GRAPHENEDIR}/Pal/src/host/Linux-SGX/tools/ra-tls dcap - -cd ${GRAPHENEDIR}/Examples/ra-tls-secret-prov - -make dcap pf_crypt - -cd - diff --git a/sgx/graphene/Examples/ra-tls-secret-prov/copy_resource.sh b/sgx/graphene/Examples/ra-tls-secret-prov/copy_resource.sh deleted file mode 100755 index b27aa7159..000000000 --- a/sgx/graphene/Examples/ra-tls-secret-prov/copy_resource.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -set -e - -if [ ! -n "$1" ] ; then - target=. -else - target=$1 -fi - -${GRAPHENEDIR}/Examples/ra-tls-secret-prov/build.sh - -cp -r ${GRAPHENEDIR}/Examples/ra-tls-secret-prov/libs/* ${target} -cp -r ${GRAPHENEDIR}/Examples/ra-tls-secret-prov/pf_crypt ${target} diff --git a/sgx/grpc/build_install.sh b/sgx/grpc/build_install.sh deleted file mode 100755 index b9360a1ba..000000000 --- a/sgx/grpc/build_install.sh +++ /dev/null @@ -1,56 +0,0 @@ -set -e - -# build and install grpc library -#cd ${GRPC_PATH} -#mkdir -p build -#cd build -#cmake -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. -#make -j `nproc` -#make install -#cd - -# -## build and install abseil -#if [ ! -d "${INSTALL_PREFIX}/include/absl" ]; then -# cd ${GRPC_PATH}/third_party/abseil-cpp -# mkdir -p build -# cd build -# cmake -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. -# make -j `nproc` -# make install -# cd - -#fi - - -set -e - -export MBEDTLS_PATH=${GRAPHENEDIR}/Examples/ra-tls-mbedtls -export ABSEIL_PATH=${GRPC_PATH}/third_party/abseil-cpp - -# Build ra-tls-mbedtls -if [ ! -d "${MBEDTLS_PATH}/mbedtls" ]; then - ${MBEDTLS_PATH}/build_install.sh -fi - -# build and install abseil library -# https://abseil.io/docs/cpp/quickstart-cmake.html -if [ ! -d "${ABSEIL_PATH}/build" ]; then - mkdir -p ${ABSEIL_PATH}/build - cd ${ABSEIL_PATH}/build - cmake -DCMAKE_CXX_STANDARD=11 -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ - -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. - make -j `nproc` - make install - cd - -fi - -# build and install grpc library -mkdir -p ${GRPC_PATH}/build -cd ${GRPC_PATH}/build -cmake -DgRPC_INSTALL=ON -DABSL_ENABLE_INSTALL=ON \ - -DgRPC_ABSL_PROVIDER=package -DgRPC_BUILD_TESTS=OFF \ - -DgRPC_BUILD_CSHARP_EXT=OFF -DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF \ - -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF -DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF \ - -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. -make -j `nproc` -make install -cd - diff --git a/sgx/grpc/common/build_cpp.sh b/sgx/grpc/common/build_cpp.sh new file mode 100755 index 000000000..2d3df8cf3 --- /dev/null +++ b/sgx/grpc/common/build_cpp.sh @@ -0,0 +1,31 @@ +set -ex + +export ABSEIL_PATH=${GRPC_PATH}/third_party/abseil-cpp + +if [ ! -d "${BUILD_TYPE}" ]; then + BUILD_TYPE=Release +fi + +# build and install abseil library +# https://abseil.io/docs/cpp/quickstart-cmake.html +if [ ! -d "${ABSEIL_PATH}/build" ]; then + mkdir -p ${ABSEIL_PATH}/build + cd ${ABSEIL_PATH}/build + cmake -DCMAKE_CXX_STANDARD=11 -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. + make -j `nproc` + make install + cd - +fi + +# build and install grpc library +mkdir -p ${GRPC_PATH}/build +cd ${GRPC_PATH}/build +cmake -DgRPC_INSTALL=ON -DABSL_ENABLE_INSTALL=ON \ + -DgRPC_ABSL_PROVIDER=package -DgRPC_BUILD_TESTS=OFF \ + -DgRPC_BUILD_CSHARP_EXT=OFF -DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF -DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF \ + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. +make -j `nproc` +make install +cd - diff --git a/sgx/grpc/common/build_python.sh b/sgx/grpc/common/build_python.sh new file mode 100755 index 000000000..17099199e --- /dev/null +++ b/sgx/grpc/common/build_python.sh @@ -0,0 +1,12 @@ +set -ex + +# build grpc c / cpp library +${GRPC_PATH}/build_cpp.sh + +# build grpc python wheel +cd ${GRPC_PATH} +rm -rf python_build None src/python/grpcio/__pycache__ src/python/grpcio/grpc/_cython/cygrpc.cpp +python3 setup.py bdist_wheel +cd - + +ldd ${GRPC_PATH}/python_build/lib.linux-x86_64-3.6/grpc/_cython/cygrpc.cpython-36m-x86_64-linux-gnu.so diff --git a/sgx/grpc/examples/cpp/helloworld/CMakeLists.txt b/sgx/grpc/examples/cpp/helloworld/CMakeLists.txt deleted file mode 100644 index 034cafe13..000000000 --- a/sgx/grpc/examples/cpp/helloworld/CMakeLists.txt +++ /dev/null @@ -1,193 +0,0 @@ -# Copyright 2018 gRPC 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. -# -# cmake build file for C++ helloworld example. -# Assumes protobuf and gRPC have been installed using cmake. -# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build -# that automatically builds all the dependencies before building helloworld. - -cmake_minimum_required(VERSION 3.5.1) - -project(HelloWorld C CXX) - -if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -else() - add_definitions(-D_WIN32_WINNT=0x600) -endif() - -find_package(Threads REQUIRED) - -if(GRPC_AS_SUBMODULE) - # One way to build a projects that uses gRPC is to just include the - # entire gRPC project tree via "add_subdirectory". - # This approach is very simple to use, but the are some potential - # disadvantages: - # * it includes gRPC's CMakeLists.txt directly into your build script - # without and that can make gRPC's internal setting interfere with your - # own build. - # * depending on what's installed on your system, the contents of submodules - # in gRPC's third_party/* might need to be available (and there might be - # additional prerequisites required to build them). Consider using - # the gRPC_*_PROVIDER options to fine-tune the expected behavior. - # - # A more robust approach to add dependency on gRPC is using - # cmake's ExternalProject_Add (see cmake_externalproject/CMakeLists.txt). - - # Include the gRPC's cmake build (normally grpc source code would live - # in a git submodule called "third_party/grpc", but this example lives in - # the same repository as gRPC sources, so we just look a few directories up) - add_subdirectory(../../.. ${CMAKE_CURRENT_BINARY_DIR}/grpc EXCLUDE_FROM_ALL) - message(STATUS "Using gRPC via add_subdirectory.") - - # After using add_subdirectory, we can now use the grpc targets directly from - # this build. - set(_PROTOBUF_LIBPROTOBUF libprotobuf) - set(_REFLECTION grpc++_reflection) - set(_PROTOBUF_PROTOC $) - set(_GRPC_GRPCPP grpc++) - set(_GRPC grpc) - set(_GPR gpr) - set(_UPB upb) - if(CMAKE_CROSSCOMPILING) - find_program(_PROTOBUF_PROTOC protoc) - else() - set(_PROTOBUF_PROTOC $) - endif() - if(CMAKE_CROSSCOMPILING) - find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) - else() - set(_GRPC_CPP_PLUGIN_EXECUTABLE $) - endif() -elseif(GRPC_FETCHCONTENT) - # Another way is to use CMake's FetchContent module to clone gRPC at - # configure time. This makes gRPC's source code available to your project, - # similar to a git submodule. - message(STATUS "Using gRPC via add_subdirectory (FetchContent).") - include(FetchContent) - FetchContent_Declare( - grpc - GIT_REPOSITORY https://github.com/grpc/grpc.git - # when using gRPC, you will actually set this to an existing tag, such as - # v1.25.0, v1.26.0 etc.. - # For the purpose of testing, we override the tag used to the commit - # that's currently under test. - GIT_TAG vGRPC_TAG_VERSION_OF_YOUR_CHOICE) - FetchContent_MakeAvailable(grpc) - - # Since FetchContent uses add_subdirectory under the hood, we can use - # the grpc targets directly from this build. - set(_PROTOBUF_LIBPROTOBUF libprotobuf) - set(_PROTOBUF_PROTOC $) - set(_REFLECTION grpc++_reflection) - set(_PROTOBUF_PROTOC $) - set(_GRPC_GRPCPP grpc++) - set(_GRPC grpc) - set(_GPR gpr) - set(_UPB upb) - if(CMAKE_CROSSCOMPILING) - find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) - else() - set(_GRPC_CPP_PLUGIN_EXECUTABLE $) - endif() -else() - # This branch assumes that gRPC and all its dependencies are already installed - # on this system, so they can be located by find_package(). - - # Find Protobuf installation - # Looks for protobuf-config.cmake file installed by Protobuf's cmake installation. - set(protobuf_MODULE_COMPATIBLE TRUE) - find_package(Protobuf CONFIG REQUIRED) - message(STATUS "Using protobuf ${protobuf_VERSION}") - - set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf) - set(_REFLECTION grpc++_reflection) - set(_PROTOBUF_PROTOC $) - set(_GRPC_GRPCPP grpc++) - set(_GRPC grpc) - set(_GPR gpr) - set(_UPB upb) - if(CMAKE_CROSSCOMPILING) - find_program(_PROTOBUF_PROTOC protoc) - else() - set(_PROTOBUF_PROTOC $) - endif() - - # Find gRPC installation - # Looks for gRPCConfig.cmake file installed by gRPC's cmake installation. - find_package(gRPC CONFIG REQUIRED) - message(STATUS "Using gRPC ${gRPC_VERSION}") - - if(CMAKE_CROSSCOMPILING) - find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) - else() - set(_GRPC_CPP_PLUGIN_EXECUTABLE $) - endif() -endif() - -# Proto file -get_filename_component(hw_proto "../../protos/helloworld.proto" ABSOLUTE) -get_filename_component(hw_proto_path "${hw_proto}" PATH) - -# Generated sources -set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.cc") -set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.pb.h") -set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.cc") -set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.h") -add_custom_command( - OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}" "${hw_grpc_srcs}" "${hw_grpc_hdrs}" - COMMAND ${_PROTOBUF_PROTOC} - ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}" - --cpp_out "${CMAKE_CURRENT_BINARY_DIR}" - -I "${hw_proto_path}" - --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}" - "${hw_proto}" - DEPENDS "${hw_proto}") - -# Include generated *.pb.h files -include_directories("${CMAKE_CURRENT_BINARY_DIR}") - -# Targets greeter_[async_](client|server) -foreach(_target - greeter_client greeter_server) - add_executable(${_target} "${_target}.cc" "grpc_sgx_ra_tls_client.cc" "grpc_sgx_ra_tls_server.cc" "grpc_sgx_ra_tls_utils.cc" "grpc_sgx_credentials_provider.cc" - ${hw_proto_srcs} - ${hw_grpc_srcs}) - target_link_libraries(${_target} - ${_PROTOBUF_LIBPROTOBUF} - ${_REFLECTION} - ${_GRPC_GRPCPP} - ${_GRPC} - ${_GPR} - ${_UPB} - - cares - absl_strings - absl_base - absl_flags_parse - absl_flags_usage_internal - absl_flags_program_name - absl_flags_config - absl_throw_delegate - z - ssl - crypto - address_sorting - dl - - libmbedtls.so - libmbedx509.so - libmbedcrypto.so - ra_tls_attest) -endforeach() diff --git a/sgx/grpc/examples/cpp/helloworld/Makefile b/sgx/grpc/examples/cpp/helloworld/Makefile deleted file mode 100644 index aafe3ba9d..000000000 --- a/sgx/grpc/examples/cpp/helloworld/Makefile +++ /dev/null @@ -1,112 +0,0 @@ -# -# Copyright 2015 gRPC 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. -# - -HOST_SYSTEM = $(shell uname | cut -f 1 -d_) -SYSTEM ?= $(HOST_SYSTEM) -CXX = g++ -CPPFLAGS += `pkg-config --cflags protobuf grpc` -CXXFLAGS += -std=c++11 -ifeq ($(SYSTEM),Darwin) -LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++`\ - -pthread\ - -lgrpc++_reflection\ - -ldl -else -LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++`\ - -pthread\ - -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ - -ldl -endif -PROTOC = protoc -GRPC_CPP_PLUGIN = grpc_cpp_plugin -GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` - -PROTOS_PATH = ../../protos - -vpath %.proto $(PROTOS_PATH) - -all: system-check greeter_client greeter_server - -greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o - $(CXX) $^ $(LDFLAGS) -o $@ - -greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o - $(CXX) $^ $(LDFLAGS) -o $@ - -.PRECIOUS: %.grpc.pb.cc -%.grpc.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< - -.PRECIOUS: %.pb.cc -%.pb.cc: %.proto - $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< - -clean: - rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server - - -# The following is to test your system and ensure a smoother experience. -# They are by no means necessary to actually compile a grpc-enabled software. - -PROTOC_CMD = which $(PROTOC) -PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 -PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) -HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) -ifeq ($(HAS_PROTOC),true) -HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) -endif -HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) - -SYSTEM_OK = false -ifeq ($(HAS_VALID_PROTOC),true) -ifeq ($(HAS_PLUGIN),true) -SYSTEM_OK = true -endif -endif - -system-check: -ifneq ($(HAS_VALID_PROTOC),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have protoc 3.0.0 installed in your path." - @echo "Please install Google protocol buffers 3.0.0 and its compiler." - @echo "You can find it here:" - @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" - @echo - @echo "Here is what I get when trying to evaluate your version of protoc:" - @echo - -$(PROTOC) --version - @echo - @echo -endif -ifneq ($(HAS_PLUGIN),true) - @echo " DEPENDENCY ERROR" - @echo - @echo "You don't have the grpc c++ protobuf plugin installed in your path." - @echo "Please install grpc. You can find it here:" - @echo - @echo " https://github.com/grpc/grpc" - @echo - @echo "Here is what I get when trying to detect if you have the plugin:" - @echo - -which $(GRPC_CPP_PLUGIN) - @echo - @echo -endif -ifneq ($(SYSTEM_OK),true) - @false -endif diff --git a/sgx/grpc/examples/cpp/helloworld/README.md b/sgx/grpc/examples/cpp/helloworld/README.md deleted file mode 100644 index 813a80f28..000000000 --- a/sgx/grpc/examples/cpp/helloworld/README.md +++ /dev/null @@ -1,260 +0,0 @@ -# gRPC C++ Hello World Tutorial - -### Install gRPC -Make sure you have installed gRPC on your system. Follow the -[BUILDING.md](../../../BUILDING.md) instructions. - -### Get the tutorial source code - -The example code for this and our other examples lives in the `examples` -directory. Clone this repository to your local machine by running the -following command: - - -```sh -$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc -``` - -Change your current directory to examples/cpp/helloworld - -```sh -$ cd examples/cpp/helloworld/ -``` - -### Defining a service - -The first step in creating our example is to define a *service*: an RPC -service specifies the methods that can be called remotely with their parameters -and return types. As you saw in the -[overview](#protocolbuffers) above, gRPC does this using [protocol -buffers](https://developers.google.com/protocol-buffers/docs/overview). We -use the protocol buffers interface definition language (IDL) to define our -service methods, and define the parameters and return -types as protocol buffer message types. Both the client and the -server use interface code generated from the service definition. - -Here's our example service definition, defined using protocol buffers IDL in -[helloworld.proto](../../protos/helloworld.proto). The `Greeting` -service has one method, `hello`, that lets the server receive a single -`HelloRequest` -message from the remote client containing the user's name, then send back -a greeting in a single `HelloReply`. This is the simplest type of RPC you -can specify in gRPC - we'll look at some other types later in this document. - -```protobuf -syntax = "proto3"; - -option java_package = "ex.grpc"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} - -``` - - -### Generating gRPC code - -Once we've defined our service, we use the protocol buffer compiler -`protoc` to generate the special client and server code we need to create -our application. The generated code contains both stub code for clients to -use and an abstract interface for servers to implement, both with the method -defined in our `Greeting` service. - -To generate the client and server side interfaces: - -```sh -$ make helloworld.grpc.pb.cc helloworld.pb.cc -``` -Which internally invokes the proto-compiler as: - -```sh -$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto -$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto -``` - -### Writing a client - -- Create a channel. A channel is a logical connection to an endpoint. A gRPC - channel can be created with the target address, credentials to use and - arguments as follows - - ```cpp - auto channel = CreateChannel("localhost:50051", InsecureChannelCredentials()); - ``` - -- Create a stub. A stub implements the rpc methods of a service and in the - generated code, a method is provided to create a stub with a channel: - - ```cpp - auto stub = helloworld::Greeter::NewStub(channel); - ``` - -- Make a unary rpc, with `ClientContext` and request/response proto messages. - - ```cpp - ClientContext context; - HelloRequest request; - request.set_name("hello"); - HelloReply reply; - Status status = stub->SayHello(&context, request, &reply); - ``` - -- Check returned status and response. - - ```cpp - if (status.ok()) { - // check reply.message() - } else { - // rpc failed. - } - ``` - -For a working example, refer to [greeter_client.cc](greeter_client.cc). - -### Writing a server - -- Implement the service interface - - ```cpp - class GreeterServiceImpl final : public Greeter::Service { - Status SayHello(ServerContext* context, const HelloRequest* request, - HelloReply* reply) override { - std::string prefix("Hello "); - reply->set_message(prefix + request->name()); - return Status::OK; - } - }; - - ``` - -- Build a server exporting the service - - ```cpp - GreeterServiceImpl service; - ServerBuilder builder; - builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr server(builder.BuildAndStart()); - ``` - -For a working example, refer to [greeter_server.cc](greeter_server.cc). - -### Writing asynchronous client and server - -gRPC uses `CompletionQueue` API for asynchronous operations. The basic work flow -is -- bind a `CompletionQueue` to a rpc call -- do something like a read or write, present with a unique `void*` tag -- call `CompletionQueue::Next` to wait for operations to complete. If a tag - appears, it indicates that the corresponding operation is complete. - -#### Async client - -The channel and stub creation code is the same as the sync client. - -- Initiate the rpc and create a handle for the rpc. Bind the rpc to a - `CompletionQueue`. - - ```cpp - CompletionQueue cq; - auto rpc = stub->AsyncSayHello(&context, request, &cq); - ``` - -- Ask for reply and final status, with a unique tag - - ```cpp - Status status; - rpc->Finish(&reply, &status, (void*)1); - ``` - -- Wait for the completion queue to return the next tag. The reply and status are - ready once the tag passed into the corresponding `Finish()` call is returned. - - ```cpp - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - if (ok && got_tag == (void*)1) { - // check reply and status - } - ``` - -For a working example, refer to [greeter_async_client.cc](greeter_async_client.cc). - -#### Async server - -The server implementation requests a rpc call with a tag and then wait for the -completion queue to return the tag. The basic flow is - -- Build a server exporting the async service - - ```cpp - helloworld::Greeter::AsyncService service; - ServerBuilder builder; - builder.AddListeningPort("0.0.0.0:50051", InsecureServerCredentials()); - builder.RegisterService(&service); - auto cq = builder.AddCompletionQueue(); - auto server = builder.BuildAndStart(); - ``` - -- Request one rpc - - ```cpp - ServerContext context; - HelloRequest request; - ServerAsyncResponseWriter responder; - service.RequestSayHello(&context, &request, &responder, &cq, &cq, (void*)1); - ``` - -- Wait for the completion queue to return the tag. The context, request and - responder are ready once the tag is retrieved. - - ```cpp - HelloReply reply; - Status status; - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - if (ok && got_tag == (void*)1) { - // set reply and status - responder.Finish(reply, status, (void*)2); - } - ``` - -- Wait for the completion queue to return the tag. The rpc is finished when the - tag is back. - - ```cpp - void* got_tag; - bool ok = false; - cq.Next(&got_tag, &ok); - if (ok && got_tag == (void*)2) { - // clean up - } - ``` - -To handle multiple rpcs, the async server creates an object `CallData` to -maintain the state of each rpc and use the address of it as the unique tag. For -simplicity the server only uses one completion queue for all events, and runs a -main loop in `HandleRpcs` to query the queue. - -For a working example, refer to [greeter_async_server.cc](greeter_async_server.cc). - - - - diff --git a/sgx/grpc/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt b/sgx/grpc/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt deleted file mode 100644 index dd646bf5d..000000000 --- a/sgx/grpc/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright 2018 gRPC 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. -# -# cmake "superbuild" file for C++ helloworld example. -# This build file demonstrates how to build the helloworld project -# and all its dependencies in a single cmake build (hence "superbuild") -# that is easy to build and maintain. -# cmake's ExternalProject_Add() is used to import all the sub-projects, -# including the "helloworld" project itself. -# See https://blog.kitware.com/cmake-superbuilds-git-submodules/ - -cmake_minimum_required(VERSION 3.5.1) - -# Project -project(HelloWorld-SuperBuild C CXX) - -include(ExternalProject) - -# Note: For all external projects, instead of using checked-out code, one could -# specify GIT_REPOSITORY and GIT_TAG to have cmake download the dependency directly, -# without needing to add a submodule to your project. - -# Builds absl project from the git submodule. -ExternalProject_Add(absl - PREFIX absl - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/abseil-cpp" - CMAKE_CACHE_ARGS - -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=TRUE - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/absl -) - -# Builds c-ares project from the git submodule. -ExternalProject_Add(c-ares - PREFIX c-ares - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/cares/cares" - CMAKE_CACHE_ARGS - -DCARES_SHARED:BOOL=OFF - -DCARES_STATIC:BOOL=ON - -DCARES_STATIC_PIC:BOOL=ON - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares -) - -# Builds protobuf project from the git submodule. -ExternalProject_Add(protobuf - PREFIX protobuf - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/protobuf/cmake" - CMAKE_CACHE_ARGS - -Dprotobuf_BUILD_TESTS:BOOL=OFF - -Dprotobuf_WITH_ZLIB:BOOL=OFF - -Dprotobuf_MSVC_STATIC_RUNTIME:BOOL=OFF - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/protobuf -) - -# Builds zlib project from the git submodule. -ExternalProject_Add(zlib - PREFIX zlib - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../third_party/zlib" - CMAKE_CACHE_ARGS - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/zlib -) - -# the location where protobuf-config.cmake will be installed varies by platform -if (WIN32) - set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf/cmake") -else() - set(_FINDPACKAGE_PROTOBUF_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/protobuf/lib/cmake/protobuf") -endif() - -# if OPENSSL_ROOT_DIR is set, propagate that hint path to the external projects with OpenSSL dependency. -set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "") -if (OPENSSL_ROOT_DIR) - set(_CMAKE_ARGS_OPENSSL_ROOT_DIR "-DOPENSSL_ROOT_DIR:PATH=${OPENSSL_ROOT_DIR}") -endif() - -# Builds gRPC based on locally checked-out sources and set arguments so that all the dependencies -# are correctly located. -ExternalProject_Add(grpc - PREFIX grpc - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../.." - CMAKE_CACHE_ARGS - -DgRPC_INSTALL:BOOL=ON - -DgRPC_BUILD_TESTS:BOOL=OFF - -DgRPC_PROTOBUF_PROVIDER:STRING=package - -DgRPC_PROTOBUF_PACKAGE_TYPE:STRING=CONFIG - -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR} - -DgRPC_ZLIB_PROVIDER:STRING=package - -DZLIB_ROOT:STRING=${CMAKE_CURRENT_BINARY_DIR}/zlib - -DgRPC_ABSL_PROVIDER:STRING=package - -Dabsl_DIR:STRING=${CMAKE_CURRENT_BINARY_DIR}/absl/lib/cmake/absl - -DgRPC_CARES_PROVIDER:STRING=package - -Dc-ares_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares/lib/cmake/c-ares - -DgRPC_SSL_PROVIDER:STRING=package - ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/grpc - DEPENDS c-ares protobuf zlib absl -) - -# Build the helloworld projects itself using a CMakeLists.txt that assumes all the dependencies -# have already been installed. -# Even though helloworld is not really an "external project" from perspective of this build, -# we are still importing it using ExternalProject_Add because that allows us to use find_package() -# to locate all the dependencies (if we were building helloworld directly in this build we, -# we would have needed to manually import the libraries as opposed to reusing targets exported by -# gRPC and protobuf). -ExternalProject_Add(helloworld - PREFIX helloworld - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/helloworld" - INSTALL_COMMAND "" - CMAKE_CACHE_ARGS - -DProtobuf_DIR:PATH=${_FINDPACKAGE_PROTOBUF_CONFIG_DIR} - -Dc-ares_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/c-ares/lib/cmake/c-ares - -DZLIB_ROOT:STRING=${CMAKE_CURRENT_BINARY_DIR}/zlib - -Dabsl_DIR:STRING=${CMAKE_CURRENT_BINARY_DIR}/absl/lib/cmake/absl - ${_CMAKE_ARGS_OPENSSL_ROOT_DIR} - -DgRPC_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/grpc/lib/cmake/grpc - DEPENDS protobuf grpc -) diff --git a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_credentials_provider.cc b/sgx/grpc/examples/cpp/helloworld/grpc_sgx_credentials_provider.cc deleted file mode 100644 index 83ffe9938..000000000 --- a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_credentials_provider.cc +++ /dev/null @@ -1,173 +0,0 @@ - -/* - * - * Copyright 2016 gRPC 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. - * - */ - -#include "grpc_sgx_credentials_provider.h" - -#include -#include -#include - -#include -#include - -#include -#include -#include - -//#include "test/core/end2end/data/ssl_test_data.h" - -namespace grpc { -namespace sgx { -namespace { - -grpc::string ReadFile(const grpc::string& src_path) { - std::ifstream src; - src.open(src_path, std::ifstream::in | std::ifstream::binary); - - grpc::string contents; - src.seekg(0, std::ios::end); - contents.reserve(src.tellg()); - src.seekg(0, std::ios::beg); - contents.assign((std::istreambuf_iterator(src)), - (std::istreambuf_iterator())); - return contents; -} - -class DefaultCredentialsProvider : public CredentialsProvider { - public: - DefaultCredentialsProvider(const std::string& server_key, const std::string& server_cert) { - custom_server_key_ = server_key; - custom_server_cert_ = server_cert; - } - ~DefaultCredentialsProvider() override {} - - void AddSecureType( - const grpc::string& type, - std::unique_ptr type_provider) override { - // This clobbers any existing entry for type, except the defaults, which - // can't be clobbered. - std::unique_lock lock(mu_); - auto it = std::find(added_secure_type_names_.begin(), - added_secure_type_names_.end(), type); - if (it == added_secure_type_names_.end()) { - added_secure_type_names_.push_back(type); - added_secure_type_providers_.push_back(std::move(type_provider)); - } else { - added_secure_type_providers_[it - added_secure_type_names_.begin()] = - std::move(type_provider); - } - } - - std::shared_ptr GetChannelCredentials( - const grpc::string& type, ChannelArguments* args) override { - if (type == grpc::sgx::kInsecureCredentialsType) { - return InsecureChannelCredentials(); - } else if (type == grpc::sgx::kAltsCredentialsType) { - grpc::experimental::AltsCredentialsOptions alts_opts; - return grpc::experimental::AltsCredentials(alts_opts); - } else if (type == grpc::sgx::kTlsCredentialsType) { - SslCredentialsOptions ssl_opts; //TODO - args->SetSslTargetNameOverride("RATLS"); - return grpc::SslCredentials(ssl_opts); - } else if (type == grpc::sgx::kGoogleDefaultCredentialsType) { - return grpc::GoogleDefaultCredentials(); - } else { - std::unique_lock lock(mu_); - auto it(std::find(added_secure_type_names_.begin(), - added_secure_type_names_.end(), type)); - if (it == added_secure_type_names_.end()) { - gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str()); - return nullptr; - } - return added_secure_type_providers_[it - added_secure_type_names_.begin()] - ->GetChannelCredentials(args); - } - } - - std::shared_ptr GetServerCredentials( - const grpc::string& type) override { - if (type == grpc::sgx::kInsecureCredentialsType) { - return InsecureServerCredentials(); - } else if (type == grpc::sgx::kAltsCredentialsType) { - grpc::experimental::AltsServerCredentialsOptions alts_opts; - return grpc::experimental::AltsServerCredentials(alts_opts); - } else if (type == grpc::sgx::kTlsCredentialsType) { - SslServerCredentialsOptions ssl_opts; - ssl_opts.pem_root_certs = ""; - if (!custom_server_key_.empty() && !custom_server_cert_.empty()) { - SslServerCredentialsOptions::PemKeyCertPair pkcp = { - custom_server_key_, custom_server_cert_}; - ssl_opts.pem_key_cert_pairs.push_back(pkcp); - } else { - SslServerCredentialsOptions::PemKeyCertPair pkcp = {custom_server_key_, - custom_server_cert_}; - ssl_opts.pem_key_cert_pairs.push_back(pkcp); - } - return SslServerCredentials(ssl_opts); - } else { - std::unique_lock lock(mu_); - auto it(std::find(added_secure_type_names_.begin(), - added_secure_type_names_.end(), type)); - if (it == added_secure_type_names_.end()) { - gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str()); - return nullptr; - } - return added_secure_type_providers_[it - added_secure_type_names_.begin()] - ->GetServerCredentials(); - } - } - std::vector GetSecureCredentialsTypeList() override { - std::vector types; - types.push_back(grpc::sgx::kTlsCredentialsType); - std::unique_lock lock(mu_); - for (auto it = added_secure_type_names_.begin(); - it != added_secure_type_names_.end(); it++) { - types.push_back(*it); - } - return types; - } - - private: - std::mutex mu_; - std::vector added_secure_type_names_; - std::vector> - added_secure_type_providers_; - grpc::string custom_server_key_; - grpc::string custom_server_cert_; -}; - -CredentialsProvider* g_provider = nullptr; - -} // namespace - -CredentialsProvider* GetCredentialsProvider(const std::string& key, const std::string& cert) { - if (g_provider == nullptr) { - g_provider = new DefaultCredentialsProvider(key, cert); - } - return g_provider; -} - -void SetCredentialsProvider(CredentialsProvider* provider) { - // For now, forbids overriding provider. - GPR_ASSERT(g_provider == nullptr); - g_provider = provider; -} - -} // namespace sgx -} // namespace grpc diff --git a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_credentials_provider.h b/sgx/grpc/examples/cpp/helloworld/grpc_sgx_credentials_provider.h deleted file mode 100644 index 14703875e..000000000 --- a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_credentials_provider.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * - * Copyright 2016 gRPC 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H -#define GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H - -#include - -#include -#include -#include - -namespace grpc { -namespace sgx { - -const char kInsecureCredentialsType[] = "INSECURE_CREDENTIALS"; -// For real credentials, like tls/ssl, this name should match the AuthContext -// property "transport_security_type". -const char kTlsCredentialsType[] = "ssl"; -const char kAltsCredentialsType[] = "alts"; -const char kGoogleDefaultCredentialsType[] = "google_default_credentials"; - -// Provide test credentials of a particular type. -class CredentialTypeProvider { - public: - virtual ~CredentialTypeProvider() {} - - virtual std::shared_ptr GetChannelCredentials( - ChannelArguments* args) = 0; - virtual std::shared_ptr GetServerCredentials() = 0; -}; - -// Provide test credentials. Thread-safe. -class CredentialsProvider { - public: - virtual ~CredentialsProvider() {} - - // Add a secure type in addition to the defaults. The default provider has - // (kInsecureCredentialsType, kTlsCredentialsType). - virtual void AddSecureType( - const grpc::string& type, - std::unique_ptr type_provider) = 0; - - // Provide channel credentials according to the given type. Alter the channel - // arguments if needed. Return nullptr if type is not registered. - virtual std::shared_ptr GetChannelCredentials( - const grpc::string& type, ChannelArguments* args) = 0; - - // Provide server credentials according to the given type. - // Return nullptr if type is not registered. - virtual std::shared_ptr GetServerCredentials( - const grpc::string& type) = 0; - - // Provide a list of secure credentials type. - virtual std::vector GetSecureCredentialsTypeList() = 0; -}; - -// Get the current provider. Create a default one if not set. -// Not thread-safe. -CredentialsProvider* GetCredentialsProvider(const std::string& key, const std::string& cert); - -// Set the global provider. Takes ownership. The previous set provider will be -// destroyed. -// Not thread-safe. -void SetCredentialsProvider(CredentialsProvider* provider); - -} // namespace sgx -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H diff --git a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls.h b/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls.h deleted file mode 100644 index 005d34e52..000000000 --- a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Copyright 2019 gRPC 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. - * - */ - -#ifndef GRPC_SGX_RA_TLS_H -#define GRPC_SGX_RA_TLS_H - -#include - -#include -#include - -namespace grpc { -namespace sgx { - -std::shared_ptr TlsCredentials( - const char* mrenclave, const char* mrsigner, - const char* isv_prod_id, const char* isv_svn); - -std::shared_ptr CreateSecureChannel(string, std::shared_ptr); - -std::shared_ptr TlsServerCredentials(); - -} // namespace sgx -} // namespace grpc - -#endif // GRPC_SGX_RA_TLS_H diff --git a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_client.cc b/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_client.cc deleted file mode 100644 index 0d9ab6ac6..000000000 --- a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_client.cc +++ /dev/null @@ -1,254 +0,0 @@ -/* - * - * Copyright 2019 gRPC 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. - * - */ - -#include -#include "grpc_sgx_ra_tls_utils.h" - -namespace grpc { -namespace sgx { - -/* -RA-TLS: on client, only need to register ra_tls_verify_callback() for cert verification - 1. convert cert form pem format to der format - 2. extract SGX quote from "quote" OID extension from crt - 3. compare public key's hash from cert against quote's report_data - 4. prepare user-supplied verification parameter "allow outdated TCB" - 5. call into libsgx_dcap_quoteverify to verify ECDSA/based SGX quote - 6. verify all measurements from the SGX quote -*/ - -class TlsServerAuthorizationCheck; - -static int (*ra_tls_verify_callback_f)(uint8_t* der_crt, size_t der_crt_size) = nullptr; - -static std::shared_ptr server_authorization_check = nullptr; -static std::shared_ptr server_authorization_check_config = nullptr; - -static library_engine helper_sgx_urts_lib("libsgx_urts.so", RTLD_NOW | RTLD_GLOBAL); -static library_engine ra_tls_verify_lib("libra_tls_verify_dcap.so", RTLD_LAZY); - -static char g_expected_mrenclave[32]; -static char g_expected_mrsigner[32]; -static char g_expected_isv_prod_id[2]; -static char g_expected_isv_svn[2]; - -static bool g_verify_mrenclave = true; -static bool g_verify_mrsigner = true; -static bool g_verify_isv_prod_id = true; -static bool g_verify_isv_svn = true; - -static pthread_mutex_t g_print_lock; - -void parse_args(const char* s_mrenclave, const char* s_mrsigner, const char* s_isv_prod_id, const char* s_isv_svn) { - if (parse_hex(s_mrenclave, g_expected_mrenclave, sizeof(g_expected_mrenclave)) < 0) { - mbedtls_printf("Cannot parse MRENCLAVE!\n"); - return; - } - - if (parse_hex(s_mrsigner, g_expected_mrsigner, sizeof(g_expected_mrsigner)) < 0) { - mbedtls_printf("Cannot parse MRSIGNER!\n"); - return; - } - - errno = 0; - uint16_t isv_prod_id = (uint16_t)strtoul(s_isv_prod_id, NULL, 10); - if (errno) { - mbedtls_printf("Cannot parse ISV_PROD_ID!\n"); - return; - } - memcpy(g_expected_isv_prod_id, &isv_prod_id, sizeof(isv_prod_id)); - - errno = 0; - uint16_t isv_svn = (uint16_t)strtoul(s_isv_svn, NULL, 10); - if (errno) { - mbedtls_printf("Cannot parse ISV_SVN\n"); - return; - } - memcpy(g_expected_isv_svn, &isv_svn, sizeof(isv_svn)); -} - -// RA-TLS: our own callback to verify SGX measurements -int ra_tls_verify_measurements_callback(const char* mrenclave, const char* mrsigner, - const char* isv_prod_id, const char* isv_svn) { - assert(mrenclave && mrsigner && isv_prod_id && isv_svn); - - pthread_mutex_lock(&g_print_lock); - - mbedtls_printf("MRENCLAVE\n"); - mbedtls_printf(" |- Expect : "); hexdump_mem(g_expected_mrenclave, 32); - mbedtls_printf(" |- Get : "); hexdump_mem(mrenclave, 32); - mbedtls_printf("MRSIGNER\n"); - mbedtls_printf(" |- Expect : "); hexdump_mem(g_expected_mrsigner, 32); - mbedtls_printf(" |- Get : "); hexdump_mem(mrsigner, 32); - mbedtls_printf("ISV_PROD_ID\n"); - mbedtls_printf(" |- Expect : %hu\n", *((uint16_t*)g_expected_isv_prod_id)); - mbedtls_printf(" |- Get : %hu\n", *((uint16_t*)isv_prod_id)); - mbedtls_printf("ISV_SVN\n"); - mbedtls_printf(" |- Expect : %hu\n", *((uint16_t*)g_expected_isv_svn)); - mbedtls_printf(" |- Get : %hu\n", *((uint16_t*)isv_svn)); - - bool status = true; - if (status && g_verify_mrenclave && memcmp(mrenclave, g_expected_mrenclave, sizeof(g_expected_mrenclave))) { - status = false; - } - - if (status && g_verify_mrsigner && memcmp(mrsigner, g_expected_mrsigner, sizeof(g_expected_mrsigner))) { - status = false; - } - - if (status && g_verify_isv_prod_id && memcmp(isv_prod_id, g_expected_isv_prod_id, sizeof(g_expected_isv_prod_id))) { - status = false; - } - - if (status && g_verify_isv_svn && memcmp(isv_svn, g_expected_isv_svn, sizeof(g_expected_isv_svn))) { - status = false; - } - - if (status) { - mbedtls_printf("Quote Verify\n |- Result : Success\n"); - pthread_mutex_unlock(&g_print_lock); - return 0; - } else { - mbedtls_printf("Quote Verify\n |- Result : Failed\n"); - pthread_mutex_unlock(&g_print_lock); - return -1; - } -} - -void ra_tls_verify_init() { - ra_tls_verify_callback_f = reinterpret_cast(ra_tls_verify_lib.get_func("ra_tls_verify_callback_der")); - - auto ra_tls_set_measurement_callback_f = reinterpret_cast(ra_tls_verify_lib.get_func("ra_tls_set_measurement_callback")); - (*ra_tls_set_measurement_callback_f)(ra_tls_verify_measurements_callback); -} - -// test/cpp/client/credentials_test.cc : class TestTlsServerAuthorizationCheck -class TlsServerAuthorizationCheck -: public grpc_impl::experimental::TlsServerAuthorizationCheckInterface { - int Schedule(grpc_impl::experimental::TlsServerAuthorizationCheckArg* arg) override { - GPR_ASSERT(arg != nullptr); - - char cert_pem[16000]; - auto peer_cert_buf = arg->peer_cert(); - peer_cert_buf.copy(cert_pem, peer_cert_buf.length(), 0); - - int ret = (*ra_tls_verify_callback_f)(reinterpret_cast(cert_pem), 16000); - if (ret != 0) { - mbedtls_printf("something went wrong while verifying quote"); - arg->set_success(0); - arg->set_status(GRPC_STATUS_UNAUTHENTICATED); - return 0; - } else { - arg->set_success(1); - arg->set_status(GRPC_STATUS_OK); - return 0; - } - } - - void Cancel(grpc_impl::experimental::TlsServerAuthorizationCheckArg* arg) override { - GPR_ASSERT(arg != nullptr); - arg->set_status(GRPC_STATUS_PERMISSION_DENIED); - arg->set_error_details("cancelled"); - } -}; - -typedef class ::grpc_impl::experimental::TlsKeyMaterialsConfig -TlsKeyMaterialsConfig; -typedef class ::grpc_impl::experimental::TlsCredentialReloadArg -TlsCredentialReloadArg; -typedef struct ::grpc_impl::experimental::TlsCredentialReloadInterface -TlsCredentialReloadInterface; -typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckArg -TlsServerAuthorizationCheckArg; -typedef struct ::grpc_impl::experimental::TlsServerAuthorizationCheckInterface -TlsServerAuthorizationCheckInterface; - -typedef class ::grpc_impl::experimental::TlsCredentialReloadConfig TlsCredentialReloadConfig; - -class TestTlsCredentialReload : public TlsCredentialReloadInterface { - int Schedule(TlsCredentialReloadArg* arg) override { - - std::cout << "000" << std::endl; - if (!arg->is_pem_key_cert_pair_list_empty()) { - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED); - return 0; - } - std::cout << "11" << std::endl; - GPR_ASSERT(arg != nullptr); - struct TlsKeyMaterialsConfig::PemKeyCertPair pair3 = {}; - std::cout << "12" << std::endl; - arg->set_pem_root_certs("new_pem_root_certs"); - arg->add_pem_key_cert_pair(pair3); - std::cout << "13" << std::endl; - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); - return 0; - } - - void Cancel(TlsCredentialReloadArg* arg) override { - GPR_ASSERT(arg != nullptr); - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL); - arg->set_error_details("cancelled"); - } -}; - -std::shared_ptr TlsCredentials( - const char* mrenclave, const char* mrsigner, - const char* isv_prod_id, const char* isv_svn) { - parse_args(mrenclave, mrsigner, isv_prod_id, isv_svn); - - ra_tls_verify_init(); - - server_authorization_check = std::make_shared(); - server_authorization_check_config = std::make_shared( - server_authorization_check); - grpc_impl::experimental::TlsCredentialsOptions options( - GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, - GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION, - nullptr, - nullptr, - server_authorization_check_config - ); - - return grpc_impl::experimental::TlsCredentials(options); - - /* - grpc_tls_credentials_options* options = grpc_tls_credentials_options_create(); - grpc_tls_credentials_options_set_server_verification_option(options, GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION); - - server_authorization_check = std::make_shared(); - server_authorization_check_config = std::make_shared( - server_authorization_check); - grpc_tls_credentials_options_set_server_authorization_check_config(options, server_authorization_check_config); - grpc_channel_credentials* creds = grpc_tls_credentials_create(options); - return std::shared_ptr( - new ::grpc::SecureChannelCredentials(std::move(creds))); - */ -}; - -std::shared_ptr CreateSecureChannel(string target_str, std::shared_ptr channel_creds) { - GPR_ASSERT(channel_creds.get() != nullptr); - auto channel_args = grpc::ChannelArguments(); - channel_args.SetSslTargetNameOverride("RATLS"); - return grpc::CreateCustomChannel(target_str, std::move(channel_creds), channel_args); -}; - -} // namespace sgx -} // namespace grpc diff --git a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_server.cc b/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_server.cc deleted file mode 100644 index 6ccea5426..000000000 --- a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_server.cc +++ /dev/null @@ -1,142 +0,0 @@ -/* - * - * Copyright 2019 gRPC 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. - * - */ - -#include -#include -#include -#include "grpc_sgx_ra_tls_utils.h" -#include "grpc_sgx_credentials_provider.h" - -namespace grpc { -namespace sgx { - -#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" -#define PEM_END_CRT "-----END CERTIFICATE-----\n" - - -// Server side is required to use a provider, because server always needs to use identity certs. -::grpc_impl::experimental::TlsKeyMaterialsConfig::PemKeyCertPair get_cred_key_pair() { - mbedtls_x509_crt srvcert; - mbedtls_pk_context pkey; - - mbedtls_x509_crt_init(&srvcert); - mbedtls_pk_init(&pkey); - - library_engine ra_tls_attest_lib("libra_tls_attest.so", RTLD_LAZY); - auto ra_tls_create_key_and_crt_f = reinterpret_cast(ra_tls_attest_lib.get_func("ra_tls_create_key_and_crt")); - - int ret = (*ra_tls_create_key_and_crt_f)(&pkey, &srvcert); - if (ret != 0) { - throw std::runtime_error(std::string("ra_tls_create_key_and_crt failed and returned %d\n\n", ret)); - } - - unsigned char private_key_pem[16000], cert_pem[16000]; - size_t olen; - - ret = mbedtls_pk_write_key_pem(&pkey, private_key_pem, 16000); - if (ret != 0) { - throw std::runtime_error(std::string("something went wrong while extracting private key\n\n")); - } - - ret = mbedtls_pem_write_buffer(PEM_BEGIN_CRT, PEM_END_CRT, - srvcert.raw.p, srvcert.raw.len, - cert_pem, 16000, &olen); - if (ret != 0) { - throw std::runtime_error(std::string("mbedtls_pem_write_buffer failed\n\n")); - }; - - auto private_key = std::string((char*) private_key_pem); - auto certificate_chain = std::string((char*) cert_pem); - - ::grpc_impl::experimental::TlsKeyMaterialsConfig::PemKeyCertPair pkcp = {private_key, - certificate_chain}; - - mbedtls_printf("Server key:\n%s\n", private_key_pem); - mbedtls_printf("Server crt:\n%s\n", cert_pem); - - mbedtls_x509_crt_free(&srvcert); - mbedtls_pk_free(&pkey); - return pkcp; -} - -typedef class ::grpc_impl::experimental::TlsKeyMaterialsConfig -TlsKeyMaterialsConfig; -typedef class ::grpc_impl::experimental::TlsCredentialReloadArg -TlsCredentialReloadArg; -typedef struct ::grpc_impl::experimental::TlsCredentialReloadInterface -TlsCredentialReloadInterface; -typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckArg -TlsServerAuthorizationCheckArg; -typedef struct ::grpc_impl::experimental::TlsServerAuthorizationCheckInterface -TlsServerAuthorizationCheckInterface; - -class TestTlsCredentialReload : public TlsCredentialReloadInterface { - int Schedule(TlsCredentialReloadArg* arg) override { - std::cout << "000" << std::endl; - if (!arg->is_pem_key_cert_pair_list_empty()) { - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED); - return 0; - } - std::cout << "11" << std::endl; - GPR_ASSERT(arg != nullptr); - auto key_pair = get_cred_key_pair(); - struct TlsKeyMaterialsConfig::PemKeyCertPair pair3 = { key_pair.private_key.c_str(), - key_pair.cert_chain.c_str()}; - std::cout << "12" << std::endl; - arg->set_pem_root_certs("new_pem_root_certs"); - arg->add_pem_key_cert_pair(pair3); - std::cout << "13" << std::endl; - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); - return 0; - } - - void Cancel(TlsCredentialReloadArg* arg) override { - GPR_ASSERT(arg != nullptr); - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL); - arg->set_error_details("cancelled"); - } -}; - - -class TestTlsServerAuthorizationCheck -: public TlsServerAuthorizationCheckInterface { - int Schedule(TlsServerAuthorizationCheckArg* arg) override { - GPR_ASSERT(arg != nullptr); - return 0; - } - - void Cancel(TlsServerAuthorizationCheckArg* arg) override { - GPR_ASSERT(arg != nullptr); - arg->set_status(GRPC_STATUS_PERMISSION_DENIED); - arg->set_error_details("cancelled"); - } -}; - -std::shared_ptr TlsServerCredentials() { - using namespace ::grpc_impl::experimental; - auto key_pair = get_cred_key_pair(); - - auto provider = GetCredentialsProvider(key_pair.private_key, key_pair.cert_chain); - auto server_creds = provider->GetServerCredentials(kTlsCredentialsType); - auto processor = std::shared_ptr(); - server_creds->SetAuthMetadataProcessor(processor); - return server_creds; -}; - -} // namespace sgx -} // namespace grpc diff --git a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_utils.cc b/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_utils.cc deleted file mode 100644 index ce9d06c71..000000000 --- a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_utils.cc +++ /dev/null @@ -1,87 +0,0 @@ -/* - * - * Copyright 2019 gRPC 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. - * - */ - -#include "grpc_sgx_ra_tls_utils.h" - -namespace grpc { -namespace sgx { - -void hexdump_mem(const void* data, size_t size) { - uint8_t* ptr = (uint8_t*)data; - for (size_t i = 0; i < size; i++) - printf("%02x", ptr[i]); - printf("\n"); -} - -int parse_hex(const char* hex, void* buffer, size_t buffer_size) { - if (strlen(hex) != buffer_size * 2) { - return -1; - } else { - for (size_t i = 0; i < buffer_size; i++) { - if (!isxdigit(hex[i * 2]) || !isxdigit(hex[i * 2 + 1])) { - return -1; - } - sscanf(hex + i * 2, "%02hhx", &((uint8_t*)buffer)[i]); - } - return 0; - } -} - -library_engine::library_engine() : handle(nullptr), error(nullptr) {}; - -library_engine::library_engine(const char* file, int mode) : handle(nullptr), error(nullptr) { - open(file, mode); -} - -library_engine::~library_engine() { - close(); -} - -void library_engine::open(const char* file, int mode) { - handle = dlopen(file, mode); - if (!handle) { - mbedtls_printf("Failed to open lib %s", file); - throw std::runtime_error(std::string("dlopen error\n")); - } -} - -void library_engine::close() { - if (handle) { - dlclose(handle); - } - handle = nullptr; - error = nullptr; -} - -void* library_engine::get_func(const char* name) { - auto func = dlsym(handle, name); - error = dlerror(); - if (error != nullptr || func == nullptr) { - throw std::runtime_error(std::string(std::string(error)+"\n")); - return nullptr; - } else { - return func; - } -} - -void* library_engine::get_handle() { - return handle; -} - -} // namespace sgx -} // namespace grpc diff --git a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_utils.h b/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_utils.h deleted file mode 100644 index fabb290c4..000000000 --- a/sgx/grpc/examples/cpp/helloworld/grpc_sgx_ra_tls_utils.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * - * Copyright 2019 gRPC 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. - * - */ - -#ifndef GRPC_SGX_RA_TLS_UTILS_H -#define GRPC_SGX_RA_TLS_UTILS_H - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#define mbedtls_printf printf -#define mbedtls_fprintf fprintf - -namespace grpc { -namespace sgx { - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void hexdump_mem(const void*, size_t); - -int parse_hex(const char*, void*, size_t); - -class library_engine { - public: - library_engine(); - - library_engine(const char*, int); - - ~library_engine(); - - void open(const char*, int); - - void close(); - - void* get_func(const char*); - - void* get_handle(); - - private: - void* handle; - char* error; -}; - -} // namespace sgx -} // namespace grpc - -#endif // GRPC_SGX_RA_TLS_UTILS_H diff --git a/sgx/grpc/grpc_skip_client_sanity_check.diff b/sgx/grpc/grpc_skip_client_sanity_check.diff deleted file mode 100644 index 9268ce077..000000000 --- a/sgx/grpc/grpc_skip_client_sanity_check.diff +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/src/core/lib/security/credentials/tls/tls_credentials.cc b/src/core/lib/security/credentials/tls/tls_credentials.cc -index 701fd3b150..0826d05933 100644 ---- a/src/core/lib/security/credentials/tls/tls_credentials.cc -+++ b/src/core/lib/security/credentials/tls/tls_credentials.cc -@@ -111,9 +111,9 @@ TlsServerCredentials::create_security_connector() { - - grpc_channel_credentials* grpc_tls_credentials_create( - grpc_tls_credentials_options* options) { -- if (!CredentialOptionSanityCheck(options, true /* is_client */)) { -- return nullptr; -- } -+ //if (!CredentialOptionSanityCheck(options, true /* is_client */)) { -+ // return nullptr; -+ //} - return new TlsCredentials( - grpc_core::RefCountedPtr(options)); - } diff --git a/sgx/grpc/v1.38.1/CMakeLists.txt b/sgx/grpc/v1.38.1/CMakeLists.txt new file mode 100644 index 000000000..749af17b5 --- /dev/null +++ b/sgx/grpc/v1.38.1/CMakeLists.txt @@ -0,0 +1,15743 @@ +# GRPC global cmake file +# This currently builds C and C++ code. +# This file has been automatically generated from a template file. +# Please look at the templates directory instead. +# This file can be regenerated from the template by running +# tools/buildgen/generate_projects.sh +# +# Copyright 2015 gRPC 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. + + + + +cmake_minimum_required(VERSION 3.5.1) + +set(PACKAGE_NAME "grpc") +set(PACKAGE_VERSION "1.38.1") +set(gRPC_CORE_VERSION "16.0.0") +set(gRPC_CORE_SOVERSION "16") +set(gRPC_CPP_VERSION "1.38.1") +set(gRPC_CPP_SOVERSION "1.38") +set(gRPC_CSHARP_VERSION "2.38.1") +set(gRPC_CSHARP_SOVERSION "2.38") +set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") +set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") +set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") +project(${PACKAGE_NAME} LANGUAGES C CXX) + +set(gRPC_INSTALL_BINDIR "bin" CACHE STRING "Installation directory for executables") +set(gRPC_INSTALL_LIBDIR "lib" CACHE STRING "Installation directory for libraries") +set(gRPC_INSTALL_INCLUDEDIR "include" CACHE STRING "Installation directory for headers") +set(gRPC_INSTALL_CMAKEDIR "lib/cmake/${PACKAGE_NAME}" CACHE STRING "Installation directory for cmake config files") +set(gRPC_INSTALL_SHAREDIR "share/grpc" CACHE STRING "Installation directory for root certificates") + +# Options +option(gRPC_BUILD_TESTS "Build tests" OFF) +option(gRPC_BUILD_CODEGEN "Build codegen" ON) +option(gRPC_BUILD_CSHARP_EXT "Build C# extensions" ON) +option(gRPC_BACKWARDS_COMPATIBILITY_MODE "Build libraries that are binary compatible across a larger number of OS and libc versions" OFF) + +set(gRPC_INSTALL_default ON) +if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + # Disable gRPC_INSTALL by default if building as a submodule + set(gRPC_INSTALL_default OFF) +endif() +set(gRPC_INSTALL ${gRPC_INSTALL_default} CACHE BOOL + "Generate installation target") + +# We can install dependencies from submodules if we're running +# CMake v3.13 or newer. +if(CMAKE_VERSION VERSION_LESS 3.13) + set(_gRPC_INSTALL_SUPPORTED_FROM_MODULE OFF) +else() + set(_gRPC_INSTALL_SUPPORTED_FROM_MODULE ON) +endif() + +# Providers for third-party dependencies (gRPC_*_PROVIDER properties): +# "module": build the dependency using sources from git submodule (under third_party) +# "package": use cmake's find_package functionality to locate a pre-installed dependency + +set(gRPC_ZLIB_PROVIDER "module" CACHE STRING "Provider of zlib library") +set_property(CACHE gRPC_ZLIB_PROVIDER PROPERTY STRINGS "module" "package") + +set(gRPC_CARES_PROVIDER "module" CACHE STRING "Provider of c-ares library") +set_property(CACHE gRPC_CARES_PROVIDER PROPERTY STRINGS "module" "package") + +set(gRPC_RE2_PROVIDER "module" CACHE STRING "Provider of re2 library") +set_property(CACHE gRPC_RE2_PROVIDER PROPERTY STRINGS "module" "package") + +set(gRPC_SSL_PROVIDER "module" CACHE STRING "Provider of ssl library") +set_property(CACHE gRPC_SSL_PROVIDER PROPERTY STRINGS "module" "package") + +set(gRPC_PROTOBUF_PROVIDER "module" CACHE STRING "Provider of protobuf library") +set_property(CACHE gRPC_PROTOBUF_PROVIDER PROPERTY STRINGS "module" "package") + +set(gRPC_PROTOBUF_PACKAGE_TYPE "" CACHE STRING "Algorithm for searching protobuf package") +set_property(CACHE gRPC_PROTOBUF_PACKAGE_TYPE PROPERTY STRINGS "CONFIG" "MODULE") + +if(gRPC_BUILD_TESTS) + set(gRPC_BENCHMARK_PROVIDER "module" CACHE STRING "Provider of benchmark library") + set_property(CACHE gRPC_BENCHMARK_PROVIDER PROPERTY STRINGS "module" "package") +else() + set(gRPC_BENCHMARK_PROVIDER "none") +endif() + +set(gRPC_ABSL_PROVIDER "module" CACHE STRING "Provider of absl library") +set_property(CACHE gRPC_ABSL_PROVIDER PROPERTY STRINGS "module" "package") + +set(gRPC_ABSL_USED_TARGETS + absl_algorithm + absl_algorithm_container + absl_atomic_hook + absl_bad_optional_access + absl_bad_variant_access + absl_base + absl_base_internal + absl_bind_front + absl_bits + absl_city + absl_civil_time + absl_compressed_tuple + absl_config + absl_container_common + absl_container_memory + absl_cord + absl_core_headers + absl_debugging_internal + absl_demangle_internal + absl_dynamic_annotations + absl_endian + absl_errno_saver + absl_exponential_biased + absl_fixed_array + absl_flat_hash_map + absl_function_ref + absl_graphcycles_internal + absl_hash + absl_hash_function_defaults + absl_hash_policy_traits + absl_hashtable_debug_hooks + absl_hashtablez_sampler + absl_have_sse + absl_inlined_vector + absl_inlined_vector_internal + absl_int128 + absl_kernel_timeout_internal + absl_layout + absl_log_severity + absl_malloc_internal + absl_memory + absl_numeric_representation + absl_optional + absl_raw_hash_map + absl_raw_hash_set + absl_raw_logging_internal + absl_span + absl_spinlock_wait + absl_stacktrace + absl_status + absl_statusor + absl_str_format + absl_str_format_internal + absl_strings + absl_strings_internal + absl_symbolize + absl_synchronization + absl_throw_delegate + absl_time + absl_time_zone + absl_type_traits + absl_utility + absl_variant + absl_wyhash + absl_meta +) + +set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library") + +if(UNIX) + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(_gRPC_PLATFORM_LINUX ON) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(_gRPC_PLATFORM_MAC ON) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "iOS") + set(_gRPC_PLATFORM_IOS ON) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Android") + set(_gRPC_PLATFORM_ANDROID ON) + else() + set(_gRPC_PLATFORM_POSIX ON) + endif() +endif() +if(WIN32) + set(_gRPC_PLATFORM_WINDOWS ON) +endif() + + # Use C99 standard +if (NOT DEFINED CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Add c++11 flags +if (NOT DEFINED CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) +else() + if (CMAKE_CXX_STANDARD LESS 11) + message(FATAL_ERROR "CMAKE_CXX_STANDARD is less than 11, please specify at least SET(CMAKE_CXX_STANDARD 11)") + endif() +endif() +if (NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED) + set(CMAKE_CXX_STANDARD_REQUIRED ON) +endif() +if (NOT DEFINED CMAKE_CXX_EXTENSIONS) + set(CMAKE_CXX_EXTENSIONS OFF) +endif() + +if (NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE) + set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) +endif() +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") + +if(MSVC) + include(cmake/msvc_static_runtime.cmake) + add_definitions(-D_WIN32_WINNT=0x600 -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS) + # needed to compile protobuf + set(_gRPC_C_CXX_FLAGS "${_gRPC_C_CXX_FLAGS} /wd4065 /wd4506") + # TODO(jtattermusch): revisit warnings that were silenced as part of upgrade to protobuf3.6.0 + set(_gRPC_C_CXX_FLAGS "${_gRPC_C_CXX_FLAGS} /wd4200 /wd4291 /wd4244") + # TODO(jtattermusch): revisit C4267 occurrences throughout the code + set(_gRPC_C_CXX_FLAGS "${_gRPC_C_CXX_FLAGS} /wd4267") + # TODO(jtattermusch): needed to build boringssl with VS2017, revisit later + set(_gRPC_C_CXX_FLAGS "${_gRPC_C_CXX_FLAGS} /wd4987 /wd4774 /wd4819 /wd4996 /wd4619") +endif() +if (MINGW) + add_definitions(-D_WIN32_WINNT=0x600) +endif() +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_gRPC_C_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_gRPC_C_CXX_FLAGS}") + +if(gRPC_USE_PROTO_LITE) + set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf-lite") + add_definitions("-DGRPC_USE_PROTO_LITE") +else() + set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf") +endif() + +if(gRPC_BACKWARDS_COMPATIBILITY_MODE) + add_definitions(-DGPR_BACKWARDS_COMPATIBILITY_MODE) + if(_gRPC_PLATFORM_MAC) + # some C++11 constructs not supported before OS X 10.10 + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.10) + endif() +endif() + +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_IOS) + set(_gRPC_CORE_NOSTDCXX_FLAGS -fno-exceptions -fno-rtti) +else() + set(_gRPC_CORE_NOSTDCXX_FLAGS "") +endif() + +include(cmake/abseil-cpp.cmake) +include(cmake/address_sorting.cmake) +include(cmake/benchmark.cmake) +include(cmake/cares.cmake) +include(cmake/protobuf.cmake) +include(cmake/re2.cmake) +include(cmake/ssl.cmake) +include(cmake/upb.cmake) +include(cmake/xxhash.cmake) +include(cmake/zlib.cmake) + +if(_gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_IOS) + set(_gRPC_ALLTARGETS_LIBRARIES ${CMAKE_DL_LIBS} m pthread) +elseif(_gRPC_PLATFORM_ANDROID) + set(_gRPC_ALLTARGETS_LIBRARIES ${CMAKE_DL_LIBS} m) +elseif(UNIX) + set(_gRPC_ALLTARGETS_LIBRARIES ${CMAKE_DL_LIBS} rt m pthread) +endif() + +if(WIN32) + set(_gRPC_BASELIB_LIBRARIES wsock32 ws2_32 crypt32) +endif() + +# Create directory for generated .proto files +set(_gRPC_PROTO_GENS_DIR ${CMAKE_BINARY_DIR}/gens) +file(MAKE_DIRECTORY ${_gRPC_PROTO_GENS_DIR}) + +# protobuf_generate_grpc_cpp +# -------------------------- +# +# Add custom commands to process ``.proto`` files to C++ using protoc and +# GRPC plugin:: +# +# protobuf_generate_grpc_cpp [...] +# +# ``ARGN`` +# ``.proto`` files +# +function(protobuf_generate_grpc_cpp) + if(NOT ARGN) + message(SEND_ERROR "Error: PROTOBUF_GENERATE_GRPC_CPP() called without any proto files") + return() + endif() + + set(_protobuf_include_path -I . -I ${_gRPC_PROTOBUF_WELLKNOWN_INCLUDE_DIR}) + foreach(FIL ${ARGN}) + get_filename_component(ABS_FIL ${FIL} ABSOLUTE) + get_filename_component(FIL_WE ${FIL} NAME_WE) + file(RELATIVE_PATH REL_FIL ${CMAKE_CURRENT_SOURCE_DIR} ${ABS_FIL}) + get_filename_component(REL_DIR ${REL_FIL} DIRECTORY) + set(RELFIL_WE "${REL_DIR}/${FIL_WE}") + + #if cross-compiling, find host plugin + if(CMAKE_CROSSCOMPILING) + find_program(_gRPC_CPP_PLUGIN grpc_cpp_plugin) + else() + set(_gRPC_CPP_PLUGIN $) + endif() + + add_custom_command( + OUTPUT "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" + "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" + "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}_mock.grpc.pb.h" + "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc" + "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h" + COMMAND ${_gRPC_PROTOBUF_PROTOC_EXECUTABLE} + ARGS --grpc_out=generate_mock_code=true:${_gRPC_PROTO_GENS_DIR} + --cpp_out=${_gRPC_PROTO_GENS_DIR} + --plugin=protoc-gen-grpc=${_gRPC_CPP_PLUGIN} + ${_protobuf_include_path} + ${REL_FIL} + DEPENDS ${ABS_FIL} ${_gRPC_PROTOBUF_PROTOC} grpc_cpp_plugin + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Running gRPC C++ protocol buffer compiler on ${FIL}" + VERBATIM) + endforeach() +endfunction() + +# These options allow users to enable or disable the building of the various +# protoc plugins. For example, running CMake with +# -DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF will disable building the C# plugin. +set(_gRPC_PLUGIN_LIST) +option(gRPC_BUILD_GRPC_CPP_PLUGIN "Build grpc_cpp_plugin" ON) +if (gRPC_BUILD_GRPC_CPP_PLUGIN) + list(APPEND _gRPC_PLUGIN_LIST grpc_cpp_plugin) +endif () +option(gRPC_BUILD_GRPC_CSHARP_PLUGIN "Build grpc_csharp_plugin" ON) +if (gRPC_BUILD_GRPC_CSHARP_PLUGIN) + list(APPEND _gRPC_PLUGIN_LIST grpc_csharp_plugin) +endif () +option(gRPC_BUILD_GRPC_NODE_PLUGIN "Build grpc_node_plugin" ON) +if (gRPC_BUILD_GRPC_NODE_PLUGIN) + list(APPEND _gRPC_PLUGIN_LIST grpc_node_plugin) +endif () +option(gRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN "Build grpc_objective_c_plugin" ON) +if (gRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN) + list(APPEND _gRPC_PLUGIN_LIST grpc_objective_c_plugin) +endif () +option(gRPC_BUILD_GRPC_PHP_PLUGIN "Build grpc_php_plugin" ON) +if (gRPC_BUILD_GRPC_PHP_PLUGIN) + list(APPEND _gRPC_PLUGIN_LIST grpc_php_plugin) +endif () +option(gRPC_BUILD_GRPC_PYTHON_PLUGIN "Build grpc_python_plugin" ON) +if (gRPC_BUILD_GRPC_PYTHON_PLUGIN) + list(APPEND _gRPC_PLUGIN_LIST grpc_python_plugin) +endif () +option(gRPC_BUILD_GRPC_RUBY_PLUGIN "Build grpc_ruby_plugin" ON) +if (gRPC_BUILD_GRPC_RUBY_PLUGIN) + list(APPEND _gRPC_PLUGIN_LIST grpc_ruby_plugin) +endif () + +add_custom_target(plugins + DEPENDS ${_gRPC_PLUGIN_LIST} +) + +add_custom_target(tools_c + DEPENDS + check_epollexclusive +) + +add_custom_target(tools_cxx + DEPENDS + gen_hpack_tables + gen_legal_metadata_characters + gen_percent_encoding_tables +) + +add_custom_target(tools + DEPENDS tools_c tools_cxx) + +protobuf_generate_grpc_cpp( + src/proto/grpc/channelz/channelz.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/core/stats.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/health/v1/health.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/lb/v1/load_balancer.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/reflection/v1alpha/reflection.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/status/status.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/benchmark_service.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/control.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/duplicate/echo_duplicate.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/echo.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/echo_messages.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/empty.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/messages.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/payloads.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/report_qps_scenario_service.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/simple_messages.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/stats.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/test.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/worker_service.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/ads_for_test.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/cds_for_test.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/eds_for_test.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/lds_rds_for_test.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/lrs_for_test.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/orca_load_report_for_test.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/address.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/ads.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/aggregate_cluster.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/base.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/cluster.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/config_dump.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/config_source.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/csds.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/discovery.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/endpoint.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/fault.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/fault_common.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/http_connection_manager.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/listener.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/load_report.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/lrs.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/percent.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/protocol.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/range.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/regex.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/route.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/router.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/string.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/tls.proto +) +protobuf_generate_grpc_cpp( + test/core/tsi/alts/fake_handshaker/handshaker.proto +) +protobuf_generate_grpc_cpp( + test/core/tsi/alts/fake_handshaker/transport_security_common.proto +) + +if(gRPC_BUILD_TESTS) + add_custom_target(buildtests_c) + add_dependencies(buildtests_c algorithm_test) + add_dependencies(buildtests_c alloc_test) + add_dependencies(buildtests_c alpn_test) + add_dependencies(buildtests_c alts_counter_test) + add_dependencies(buildtests_c alts_crypt_test) + add_dependencies(buildtests_c alts_crypter_test) + add_dependencies(buildtests_c alts_frame_protector_test) + add_dependencies(buildtests_c alts_grpc_record_protocol_test) + add_dependencies(buildtests_c alts_handshaker_client_test) + add_dependencies(buildtests_c alts_iovec_record_protocol_test) + add_dependencies(buildtests_c alts_security_connector_test) + add_dependencies(buildtests_c alts_tsi_handshaker_test) + add_dependencies(buildtests_c alts_tsi_utils_test) + add_dependencies(buildtests_c alts_zero_copy_grpc_protector_test) + add_dependencies(buildtests_c arena_test) + add_dependencies(buildtests_c auth_context_test) + add_dependencies(buildtests_c avl_test) + add_dependencies(buildtests_c b64_test) + add_dependencies(buildtests_c bad_server_response_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c bad_ssl_alpn_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c bad_ssl_cert_test) + endif() + add_dependencies(buildtests_c bin_decoder_test) + add_dependencies(buildtests_c bin_encoder_test) + add_dependencies(buildtests_c buffer_list_test) + add_dependencies(buildtests_c channel_args_test) + add_dependencies(buildtests_c channel_create_test) + add_dependencies(buildtests_c channel_stack_builder_test) + add_dependencies(buildtests_c channel_stack_test) + add_dependencies(buildtests_c check_gcp_environment_linux_test) + add_dependencies(buildtests_c check_gcp_environment_windows_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c client_ssl_test) + endif() + add_dependencies(buildtests_c cmdline_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c combiner_test) + endif() + add_dependencies(buildtests_c completion_queue_threading_test) + add_dependencies(buildtests_c compression_test) + add_dependencies(buildtests_c concurrent_connectivity_test) + add_dependencies(buildtests_c connection_refused_test) + add_dependencies(buildtests_c cpu_test) + add_dependencies(buildtests_c dns_resolver_connectivity_using_ares_test) + add_dependencies(buildtests_c dns_resolver_connectivity_using_native_test) + add_dependencies(buildtests_c dns_resolver_cooldown_test) + add_dependencies(buildtests_c dns_resolver_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c dualstack_socket_test) + endif() + add_dependencies(buildtests_c endpoint_pair_test) + add_dependencies(buildtests_c env_test) + add_dependencies(buildtests_c error_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c ev_epollex_linux_test) + endif() + add_dependencies(buildtests_c fake_resolver_test) + add_dependencies(buildtests_c fake_transport_security_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c fd_conservation_posix_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c fd_posix_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c fling_stream_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c fling_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c fork_test) + endif() + add_dependencies(buildtests_c format_request_test) + add_dependencies(buildtests_c frame_handler_test) + add_dependencies(buildtests_c goaway_server_test) + add_dependencies(buildtests_c grpc_alts_credentials_options_test) + add_dependencies(buildtests_c grpc_byte_buffer_reader_test) + add_dependencies(buildtests_c grpc_completion_queue_test) + add_dependencies(buildtests_c grpc_ipv6_loopback_available_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c handshake_server_with_readahead_handshaker_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c handshake_verify_peer_options_test) + endif() + add_dependencies(buildtests_c histogram_test) + add_dependencies(buildtests_c host_port_test) + add_dependencies(buildtests_c hpack_encoder_test) + add_dependencies(buildtests_c hpack_parser_test) + add_dependencies(buildtests_c hpack_table_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c httpcli_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c httpscli_test) + endif() + add_dependencies(buildtests_c inproc_callback_test) + add_dependencies(buildtests_c invalid_call_argument_test) + add_dependencies(buildtests_c json_token_test) + add_dependencies(buildtests_c jwt_verifier_test) + add_dependencies(buildtests_c lame_client_test) + add_dependencies(buildtests_c load_file_test) + add_dependencies(buildtests_c manual_constructor_test) + add_dependencies(buildtests_c message_compress_test) + add_dependencies(buildtests_c metadata_test) + add_dependencies(buildtests_c minimal_stack_is_minimal_test) + add_dependencies(buildtests_c mpmcqueue_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c mpscq_test) + endif() + add_dependencies(buildtests_c multiple_server_queues_test) + add_dependencies(buildtests_c murmur_hash_test) + add_dependencies(buildtests_c no_server_test) + add_dependencies(buildtests_c num_external_connectivity_watchers_test) + add_dependencies(buildtests_c parse_address_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c parse_address_with_named_scope_id_test) + endif() + add_dependencies(buildtests_c parser_test) + add_dependencies(buildtests_c percent_encoding_test) + add_dependencies(buildtests_c public_headers_must_be_c89) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c resolve_address_using_ares_resolver_posix_test) + endif() + add_dependencies(buildtests_c resolve_address_using_ares_resolver_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c resolve_address_using_native_resolver_posix_test) + endif() + add_dependencies(buildtests_c resolve_address_using_native_resolver_test) + add_dependencies(buildtests_c resource_quota_test) + add_dependencies(buildtests_c secure_channel_create_test) + add_dependencies(buildtests_c secure_endpoint_test) + add_dependencies(buildtests_c security_connector_test) + add_dependencies(buildtests_c sequential_connectivity_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c server_ssl_test) + endif() + add_dependencies(buildtests_c server_test) + add_dependencies(buildtests_c slice_buffer_test) + add_dependencies(buildtests_c slice_string_helpers_test) + add_dependencies(buildtests_c sockaddr_resolver_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c socket_utils_test) + endif() + add_dependencies(buildtests_c spinlock_test) + add_dependencies(buildtests_c ssl_credentials_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c ssl_transport_security_test) + endif() + add_dependencies(buildtests_c status_conversion_test) + add_dependencies(buildtests_c stream_compression_test) + add_dependencies(buildtests_c stream_map_test) + add_dependencies(buildtests_c stream_owned_slice_test) + add_dependencies(buildtests_c string_test) + add_dependencies(buildtests_c sync_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c tcp_client_posix_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c tcp_posix_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c tcp_server_posix_test) + endif() + add_dependencies(buildtests_c test_core_gpr_time_test) + add_dependencies(buildtests_c test_core_security_credentials_test) + add_dependencies(buildtests_c test_core_slice_slice_test) + add_dependencies(buildtests_c thd_test) + add_dependencies(buildtests_c threadpool_test) + add_dependencies(buildtests_c time_averaged_stats_test) + add_dependencies(buildtests_c timeout_encoding_test) + add_dependencies(buildtests_c timer_heap_test) + add_dependencies(buildtests_c timer_list_test) + add_dependencies(buildtests_c tls_test) + add_dependencies(buildtests_c transport_security_common_api_test) + add_dependencies(buildtests_c transport_security_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_c udp_server_test) + endif() + add_dependencies(buildtests_c useful_test) + add_dependencies(buildtests_c varint_test) + + add_custom_target(buildtests_cxx) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx address_sorting_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx address_sorting_test_unsecure) + endif() + add_dependencies(buildtests_cxx admin_services_end2end_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx alarm_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx alts_concurrent_connectivity_test) + endif() + add_dependencies(buildtests_cxx alts_util_test) + add_dependencies(buildtests_cxx async_end2end_test) + add_dependencies(buildtests_cxx auth_property_iterator_test) + add_dependencies(buildtests_cxx authorization_matchers_test) + add_dependencies(buildtests_cxx aws_request_signer_test) + add_dependencies(buildtests_cxx backoff_test) + add_dependencies(buildtests_cxx bad_streaming_id_bad_client_test) + add_dependencies(buildtests_cxx badreq_bad_client_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bdp_estimator_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_alarm) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_arena) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_byte_buffer) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_call_create) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_callback_streaming_ping_pong) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_callback_unary_ping_pong) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_channel) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_chttp2_hpack) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_chttp2_transport) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_closure) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_cq) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_cq_multiple_threads) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_error) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_fullstack_streaming_ping_pong) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_fullstack_streaming_pump) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_fullstack_trickle) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_fullstack_unary_ping_pong) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_metadata) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_pollset) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_threadpool) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx bm_timer) + endif() + add_dependencies(buildtests_cxx byte_buffer_test) + add_dependencies(buildtests_cxx byte_stream_test) + add_dependencies(buildtests_cxx cancel_ares_query_test) + add_dependencies(buildtests_cxx cel_authorization_engine_test) + add_dependencies(buildtests_cxx certificate_provider_registry_test) + add_dependencies(buildtests_cxx certificate_provider_store_test) + add_dependencies(buildtests_cxx cfstream_test) + add_dependencies(buildtests_cxx channel_arguments_test) + add_dependencies(buildtests_cxx channel_filter_test) + add_dependencies(buildtests_cxx channel_trace_test) + add_dependencies(buildtests_cxx channelz_registry_test) + add_dependencies(buildtests_cxx channelz_service_test) + add_dependencies(buildtests_cxx channelz_test) + add_dependencies(buildtests_cxx cli_call_test) + add_dependencies(buildtests_cxx client_callback_end2end_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx client_channel_stress_test) + endif() + add_dependencies(buildtests_cxx client_interceptors_end2end_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx client_lb_end2end_test) + endif() + add_dependencies(buildtests_cxx codegen_test_full) + add_dependencies(buildtests_cxx codegen_test_minimal) + add_dependencies(buildtests_cxx connection_prefix_bad_client_test) + add_dependencies(buildtests_cxx connectivity_state_test) + add_dependencies(buildtests_cxx context_allocator_end2end_test) + add_dependencies(buildtests_cxx context_list_test) + add_dependencies(buildtests_cxx delegating_channel_test) + add_dependencies(buildtests_cxx destroy_grpclb_channel_with_active_connect_stress_test) + add_dependencies(buildtests_cxx dual_ref_counted_test) + add_dependencies(buildtests_cxx duplicate_header_bad_client_test) + add_dependencies(buildtests_cxx end2end_test) + add_dependencies(buildtests_cxx error_details_test) + add_dependencies(buildtests_cxx error_utils_test) + add_dependencies(buildtests_cxx evaluate_args_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx examine_stack_test) + endif() + add_dependencies(buildtests_cxx exception_test) + add_dependencies(buildtests_cxx file_watcher_certificate_provider_factory_test) + add_dependencies(buildtests_cxx filter_end2end_test) + add_dependencies(buildtests_cxx flaky_network_test) + add_dependencies(buildtests_cxx generic_end2end_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx global_config_env_test) + endif() + add_dependencies(buildtests_cxx global_config_test) + add_dependencies(buildtests_cxx google_mesh_ca_certificate_provider_factory_test) + add_dependencies(buildtests_cxx grpc_authorization_engine_test) + add_dependencies(buildtests_cxx grpc_cli) + add_dependencies(buildtests_cxx grpc_tls_certificate_distributor_test) + add_dependencies(buildtests_cxx grpc_tls_certificate_provider_test) + add_dependencies(buildtests_cxx grpc_tls_credentials_options_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx grpc_tool_test) + endif() + add_dependencies(buildtests_cxx grpclb_api_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx grpclb_end2end_test) + endif() + add_dependencies(buildtests_cxx h2_ssl_session_reuse_test) + add_dependencies(buildtests_cxx head_of_line_blocking_bad_client_test) + add_dependencies(buildtests_cxx headers_bad_client_test) + add_dependencies(buildtests_cxx health_service_end2end_test) + add_dependencies(buildtests_cxx http2_client) + add_dependencies(buildtests_cxx hybrid_end2end_test) + add_dependencies(buildtests_cxx init_test) + add_dependencies(buildtests_cxx initial_settings_frame_bad_client_test) + add_dependencies(buildtests_cxx insecure_security_connector_test) + add_dependencies(buildtests_cxx interop_client) + add_dependencies(buildtests_cxx interop_server) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx interop_test) + endif() + add_dependencies(buildtests_cxx json_test) + add_dependencies(buildtests_cxx large_metadata_bad_client_test) + add_dependencies(buildtests_cxx lb_get_cpu_stats_test) + add_dependencies(buildtests_cxx lb_load_data_store_test) + add_dependencies(buildtests_cxx linux_system_roots_test) + add_dependencies(buildtests_cxx log_test) + add_dependencies(buildtests_cxx matchers_test) + add_dependencies(buildtests_cxx message_allocator_end2end_test) + add_dependencies(buildtests_cxx mock_stream_test) + add_dependencies(buildtests_cxx mock_test) + add_dependencies(buildtests_cxx nonblocking_test) + add_dependencies(buildtests_cxx noop-benchmark) + add_dependencies(buildtests_cxx orphanable_test) + add_dependencies(buildtests_cxx out_of_bounds_bad_client_test) + add_dependencies(buildtests_cxx pid_controller_test) + add_dependencies(buildtests_cxx port_sharing_end2end_test) + add_dependencies(buildtests_cxx proto_server_reflection_test) + add_dependencies(buildtests_cxx proto_utils_test) + add_dependencies(buildtests_cxx qps_json_driver) + add_dependencies(buildtests_cxx qps_worker) + add_dependencies(buildtests_cxx raw_end2end_test) + add_dependencies(buildtests_cxx rbac_translator_test) + add_dependencies(buildtests_cxx ref_counted_ptr_test) + add_dependencies(buildtests_cxx ref_counted_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx remove_stream_from_stalled_lists_test) + endif() + add_dependencies(buildtests_cxx retry_throttle_test) + add_dependencies(buildtests_cxx secure_auth_context_test) + add_dependencies(buildtests_cxx server_builder_plugin_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx server_builder_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx server_builder_with_socket_mutator_test) + endif() + add_dependencies(buildtests_cxx server_chttp2_test) + add_dependencies(buildtests_cxx server_context_test_spouse_test) + add_dependencies(buildtests_cxx server_early_return_test) + add_dependencies(buildtests_cxx server_interceptors_end2end_test) + add_dependencies(buildtests_cxx server_registered_method_bad_client_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx server_request_call_test) + endif() + add_dependencies(buildtests_cxx service_config_end2end_test) + add_dependencies(buildtests_cxx service_config_test) + add_dependencies(buildtests_cxx settings_timeout_test) + add_dependencies(buildtests_cxx shutdown_test) + add_dependencies(buildtests_cxx simple_request_bad_client_test) + add_dependencies(buildtests_cxx sockaddr_utils_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx stack_tracer_test) + endif() + add_dependencies(buildtests_cxx stat_test) + add_dependencies(buildtests_cxx static_metadata_test) + add_dependencies(buildtests_cxx stats_test) + add_dependencies(buildtests_cxx status_helper_test) + add_dependencies(buildtests_cxx status_metadata_test) + add_dependencies(buildtests_cxx status_util_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx stranded_event_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx streaming_throughput_test) + endif() + add_dependencies(buildtests_cxx string_ref_test) + add_dependencies(buildtests_cxx test_cpp_client_credentials_test) + add_dependencies(buildtests_cxx test_cpp_server_credentials_test) + add_dependencies(buildtests_cxx test_cpp_util_slice_test) + add_dependencies(buildtests_cxx test_cpp_util_time_test) + add_dependencies(buildtests_cxx thread_manager_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx thread_stress_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx time_jump_test) + endif() + add_dependencies(buildtests_cxx time_util_test) + add_dependencies(buildtests_cxx timer_test) + add_dependencies(buildtests_cxx tls_security_connector_test) + add_dependencies(buildtests_cxx too_many_pings_test) + add_dependencies(buildtests_cxx unknown_frame_bad_client_test) + add_dependencies(buildtests_cxx uri_parser_test) + add_dependencies(buildtests_cxx window_overflow_bad_client_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx work_serializer_test) + endif() + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx writes_per_rpc_test) + endif() + add_dependencies(buildtests_cxx xds_bootstrap_test) + add_dependencies(buildtests_cxx xds_certificate_provider_test) + add_dependencies(buildtests_cxx xds_credentials_end2end_test) + add_dependencies(buildtests_cxx xds_credentials_test) + if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_dependencies(buildtests_cxx xds_end2end_test) + endif() + add_dependencies(buildtests_cxx xds_interop_client) + add_dependencies(buildtests_cxx xds_interop_server) + add_dependencies(buildtests_cxx alts_credentials_fuzzer_one_entry) + add_dependencies(buildtests_cxx client_fuzzer_one_entry) + add_dependencies(buildtests_cxx hpack_parser_fuzzer_test_one_entry) + add_dependencies(buildtests_cxx http_request_fuzzer_test_one_entry) + add_dependencies(buildtests_cxx http_response_fuzzer_test_one_entry) + add_dependencies(buildtests_cxx json_fuzzer_test_one_entry) + add_dependencies(buildtests_cxx nanopb_fuzzer_response_test_one_entry) + add_dependencies(buildtests_cxx nanopb_fuzzer_serverlist_test_one_entry) + add_dependencies(buildtests_cxx percent_decode_fuzzer_one_entry) + add_dependencies(buildtests_cxx percent_encode_fuzzer_one_entry) + add_dependencies(buildtests_cxx server_fuzzer_one_entry) + add_dependencies(buildtests_cxx ssl_server_fuzzer_one_entry) + add_dependencies(buildtests_cxx uri_fuzzer_test_one_entry) + + add_custom_target(buildtests + DEPENDS buildtests_c buildtests_cxx) +endif() + + +add_library(address_sorting + third_party/address_sorting/address_sorting.c + third_party/address_sorting/address_sorting_posix.c + third_party/address_sorting/address_sorting_windows.c +) + +set_target_properties(address_sorting PROPERTIES + VERSION ${gRPC_CORE_VERSION} + SOVERSION ${gRPC_CORE_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(address_sorting PROPERTIES COMPILE_PDB_NAME "address_sorting" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/address_sorting.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(address_sorting + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) +target_link_libraries(address_sorting + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} +) + + + +if(gRPC_INSTALL) + install(TARGETS address_sorting EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +if(gRPC_BUILD_TESTS) + +add_library(end2end_nosec_tests + test/core/end2end/cq_verifier.cc + test/core/end2end/data/client_certs.cc + test/core/end2end/data/server1_cert.cc + test/core/end2end/data/server1_key.cc + test/core/end2end/data/test_root_cert.cc + test/core/end2end/end2end_nosec_tests.cc + test/core/end2end/end2end_test_utils.cc + test/core/end2end/fixtures/http_proxy_fixture.cc + test/core/end2end/fixtures/local_util.cc + test/core/end2end/fixtures/proxy.cc + test/core/end2end/tests/authority_not_supported.cc + test/core/end2end/tests/bad_hostname.cc + test/core/end2end/tests/bad_ping.cc + test/core/end2end/tests/binary_metadata.cc + test/core/end2end/tests/call_host_override.cc + test/core/end2end/tests/cancel_after_accept.cc + test/core/end2end/tests/cancel_after_client_done.cc + test/core/end2end/tests/cancel_after_invoke.cc + test/core/end2end/tests/cancel_after_round_trip.cc + test/core/end2end/tests/cancel_before_invoke.cc + test/core/end2end/tests/cancel_in_a_vacuum.cc + test/core/end2end/tests/cancel_with_status.cc + test/core/end2end/tests/channelz.cc + test/core/end2end/tests/client_streaming.cc + test/core/end2end/tests/compressed_payload.cc + test/core/end2end/tests/connectivity.cc + test/core/end2end/tests/default_host.cc + test/core/end2end/tests/disappearing_server.cc + test/core/end2end/tests/empty_batch.cc + test/core/end2end/tests/filter_causes_close.cc + test/core/end2end/tests/filter_context.cc + test/core/end2end/tests/filter_init_fails.cc + test/core/end2end/tests/filter_latency.cc + test/core/end2end/tests/filter_status_code.cc + test/core/end2end/tests/graceful_server_shutdown.cc + test/core/end2end/tests/high_initial_seqno.cc + test/core/end2end/tests/hpack_size.cc + test/core/end2end/tests/idempotent_request.cc + test/core/end2end/tests/invoke_large_request.cc + test/core/end2end/tests/keepalive_timeout.cc + test/core/end2end/tests/large_metadata.cc + test/core/end2end/tests/max_concurrent_streams.cc + test/core/end2end/tests/max_connection_age.cc + test/core/end2end/tests/max_connection_idle.cc + test/core/end2end/tests/max_message_length.cc + test/core/end2end/tests/negative_deadline.cc + test/core/end2end/tests/no_error_on_hotpath.cc + test/core/end2end/tests/no_logging.cc + test/core/end2end/tests/no_op.cc + test/core/end2end/tests/payload.cc + test/core/end2end/tests/ping.cc + test/core/end2end/tests/ping_pong_streaming.cc + test/core/end2end/tests/proxy_auth.cc + test/core/end2end/tests/registered_call.cc + test/core/end2end/tests/request_with_flags.cc + test/core/end2end/tests/request_with_payload.cc + test/core/end2end/tests/resource_quota_server.cc + test/core/end2end/tests/retry.cc + test/core/end2end/tests/retry_cancel_during_delay.cc + test/core/end2end/tests/retry_cancellation.cc + test/core/end2end/tests/retry_disabled.cc + test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc + test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc + test/core/end2end/tests/retry_lb_drop.cc + test/core/end2end/tests/retry_non_retriable_status.cc + test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc + test/core/end2end/tests/retry_recv_initial_metadata.cc + test/core/end2end/tests/retry_recv_message.cc + test/core/end2end/tests/retry_server_pushback_delay.cc + test/core/end2end/tests/retry_server_pushback_disabled.cc + test/core/end2end/tests/retry_streaming.cc + test/core/end2end/tests/retry_streaming_after_commit.cc + test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc + test/core/end2end/tests/retry_throttled.cc + test/core/end2end/tests/retry_too_many_attempts.cc + test/core/end2end/tests/server_finishes_request.cc + test/core/end2end/tests/server_streaming.cc + test/core/end2end/tests/shutdown_finishes_calls.cc + test/core/end2end/tests/shutdown_finishes_tags.cc + test/core/end2end/tests/simple_cacheable_request.cc + test/core/end2end/tests/simple_delayed_request.cc + test/core/end2end/tests/simple_metadata.cc + test/core/end2end/tests/simple_request.cc + test/core/end2end/tests/stream_compression_compressed_payload.cc + test/core/end2end/tests/stream_compression_payload.cc + test/core/end2end/tests/stream_compression_ping_pong_streaming.cc + test/core/end2end/tests/streaming_error_response.cc + test/core/end2end/tests/trailing_metadata.cc + test/core/end2end/tests/workaround_cronet_compression.cc + test/core/end2end/tests/write_buffering.cc + test/core/end2end/tests/write_buffering_at_end.cc + test/core/util/test_lb_policies.cc +) + +set_target_properties(end2end_nosec_tests PROPERTIES + VERSION ${gRPC_CORE_VERSION} + SOVERSION ${gRPC_CORE_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(end2end_nosec_tests PROPERTIES COMPILE_PDB_NAME "end2end_nosec_tests" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/end2end_nosec_tests.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(end2end_nosec_tests + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) +target_link_libraries(end2end_nosec_tests + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_library(end2end_tests + test/core/end2end/cq_verifier.cc + test/core/end2end/data/client_certs.cc + test/core/end2end/data/server1_cert.cc + test/core/end2end/data/server1_key.cc + test/core/end2end/data/test_root_cert.cc + test/core/end2end/end2end_test_utils.cc + test/core/end2end/end2end_tests.cc + test/core/end2end/fixtures/http_proxy_fixture.cc + test/core/end2end/fixtures/local_util.cc + test/core/end2end/fixtures/proxy.cc + test/core/end2end/tests/authority_not_supported.cc + test/core/end2end/tests/bad_hostname.cc + test/core/end2end/tests/bad_ping.cc + test/core/end2end/tests/binary_metadata.cc + test/core/end2end/tests/call_creds.cc + test/core/end2end/tests/call_host_override.cc + test/core/end2end/tests/cancel_after_accept.cc + test/core/end2end/tests/cancel_after_client_done.cc + test/core/end2end/tests/cancel_after_invoke.cc + test/core/end2end/tests/cancel_after_round_trip.cc + test/core/end2end/tests/cancel_before_invoke.cc + test/core/end2end/tests/cancel_in_a_vacuum.cc + test/core/end2end/tests/cancel_with_status.cc + test/core/end2end/tests/channelz.cc + test/core/end2end/tests/client_streaming.cc + test/core/end2end/tests/compressed_payload.cc + test/core/end2end/tests/connectivity.cc + test/core/end2end/tests/default_host.cc + test/core/end2end/tests/disappearing_server.cc + test/core/end2end/tests/empty_batch.cc + test/core/end2end/tests/filter_causes_close.cc + test/core/end2end/tests/filter_context.cc + test/core/end2end/tests/filter_init_fails.cc + test/core/end2end/tests/filter_latency.cc + test/core/end2end/tests/filter_status_code.cc + test/core/end2end/tests/graceful_server_shutdown.cc + test/core/end2end/tests/high_initial_seqno.cc + test/core/end2end/tests/hpack_size.cc + test/core/end2end/tests/idempotent_request.cc + test/core/end2end/tests/invoke_large_request.cc + test/core/end2end/tests/keepalive_timeout.cc + test/core/end2end/tests/large_metadata.cc + test/core/end2end/tests/max_concurrent_streams.cc + test/core/end2end/tests/max_connection_age.cc + test/core/end2end/tests/max_connection_idle.cc + test/core/end2end/tests/max_message_length.cc + test/core/end2end/tests/negative_deadline.cc + test/core/end2end/tests/no_error_on_hotpath.cc + test/core/end2end/tests/no_logging.cc + test/core/end2end/tests/no_op.cc + test/core/end2end/tests/payload.cc + test/core/end2end/tests/ping.cc + test/core/end2end/tests/ping_pong_streaming.cc + test/core/end2end/tests/proxy_auth.cc + test/core/end2end/tests/registered_call.cc + test/core/end2end/tests/request_with_flags.cc + test/core/end2end/tests/request_with_payload.cc + test/core/end2end/tests/resource_quota_server.cc + test/core/end2end/tests/retry.cc + test/core/end2end/tests/retry_cancel_during_delay.cc + test/core/end2end/tests/retry_cancellation.cc + test/core/end2end/tests/retry_disabled.cc + test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc + test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc + test/core/end2end/tests/retry_lb_drop.cc + test/core/end2end/tests/retry_non_retriable_status.cc + test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc + test/core/end2end/tests/retry_recv_initial_metadata.cc + test/core/end2end/tests/retry_recv_message.cc + test/core/end2end/tests/retry_server_pushback_delay.cc + test/core/end2end/tests/retry_server_pushback_disabled.cc + test/core/end2end/tests/retry_streaming.cc + test/core/end2end/tests/retry_streaming_after_commit.cc + test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc + test/core/end2end/tests/retry_throttled.cc + test/core/end2end/tests/retry_too_many_attempts.cc + test/core/end2end/tests/server_finishes_request.cc + test/core/end2end/tests/server_streaming.cc + test/core/end2end/tests/shutdown_finishes_calls.cc + test/core/end2end/tests/shutdown_finishes_tags.cc + test/core/end2end/tests/simple_cacheable_request.cc + test/core/end2end/tests/simple_delayed_request.cc + test/core/end2end/tests/simple_metadata.cc + test/core/end2end/tests/simple_request.cc + test/core/end2end/tests/stream_compression_compressed_payload.cc + test/core/end2end/tests/stream_compression_payload.cc + test/core/end2end/tests/stream_compression_ping_pong_streaming.cc + test/core/end2end/tests/streaming_error_response.cc + test/core/end2end/tests/trailing_metadata.cc + test/core/end2end/tests/workaround_cronet_compression.cc + test/core/end2end/tests/write_buffering.cc + test/core/end2end/tests/write_buffering_at_end.cc + test/core/util/test_lb_policies.cc +) + +set_target_properties(end2end_tests PROPERTIES + VERSION ${gRPC_CORE_VERSION} + SOVERSION ${gRPC_CORE_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(end2end_tests PROPERTIES COMPILE_PDB_NAME "end2end_tests" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/end2end_tests.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(end2end_tests + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) +target_link_libraries(end2end_tests + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() + +add_library(gpr + src/core/ext/upb-generated/google/api/annotations.upb.c + src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c + src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c + src/core/ext/upb-generated/google/api/http.upb.c + src/core/ext/upb-generated/google/protobuf/any.upb.c + src/core/ext/upb-generated/google/protobuf/duration.upb.c + src/core/ext/upb-generated/google/protobuf/empty.upb.c + src/core/ext/upb-generated/google/protobuf/struct.upb.c + src/core/ext/upb-generated/google/protobuf/timestamp.upb.c + src/core/ext/upb-generated/google/protobuf/wrappers.upb.c + src/core/ext/upb-generated/google/rpc/status.upb.c + src/core/lib/gpr/alloc.cc + src/core/lib/gpr/atm.cc + src/core/lib/gpr/cpu_iphone.cc + src/core/lib/gpr/cpu_linux.cc + src/core/lib/gpr/cpu_posix.cc + src/core/lib/gpr/cpu_windows.cc + src/core/lib/gpr/env_linux.cc + src/core/lib/gpr/env_posix.cc + src/core/lib/gpr/env_windows.cc + src/core/lib/gpr/log.cc + src/core/lib/gpr/log_android.cc + src/core/lib/gpr/log_linux.cc + src/core/lib/gpr/log_posix.cc + src/core/lib/gpr/log_windows.cc + src/core/lib/gpr/murmur_hash.cc + src/core/lib/gpr/string.cc + src/core/lib/gpr/string_posix.cc + src/core/lib/gpr/string_util_windows.cc + src/core/lib/gpr/string_windows.cc + src/core/lib/gpr/sync.cc + src/core/lib/gpr/sync_abseil.cc + src/core/lib/gpr/sync_posix.cc + src/core/lib/gpr/sync_windows.cc + src/core/lib/gpr/time.cc + src/core/lib/gpr/time_posix.cc + src/core/lib/gpr/time_precise.cc + src/core/lib/gpr/time_windows.cc + src/core/lib/gpr/tls_pthread.cc + src/core/lib/gpr/tmpfile_msys.cc + src/core/lib/gpr/tmpfile_posix.cc + src/core/lib/gpr/tmpfile_windows.cc + src/core/lib/gpr/wrap_memcpy.cc + src/core/lib/gprpp/arena.cc + src/core/lib/gprpp/examine_stack.cc + src/core/lib/gprpp/fork.cc + src/core/lib/gprpp/global_config_env.cc + src/core/lib/gprpp/host_port.cc + src/core/lib/gprpp/mpscq.cc + src/core/lib/gprpp/stat_posix.cc + src/core/lib/gprpp/stat_windows.cc + src/core/lib/gprpp/status_helper.cc + src/core/lib/gprpp/thd_posix.cc + src/core/lib/gprpp/thd_windows.cc + src/core/lib/gprpp/time_util.cc + src/core/lib/profiling/basic_timers.cc + src/core/lib/profiling/stap_timers.cc +) + +set_target_properties(gpr PROPERTIES + VERSION ${gRPC_CORE_VERSION} + SOVERSION ${gRPC_CORE_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(gpr PROPERTIES COMPILE_PDB_NAME "gpr" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gpr.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(gpr + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) +target_link_libraries(gpr + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::base + absl::memory + absl::status + absl::str_format + absl::strings + absl::synchronization + absl::time + absl::optional + upb +) +if(_gRPC_PLATFORM_ANDROID) + target_link_libraries(gpr + android + log + ) +endif() + +foreach(_hdr + include/grpc/impl/codegen/atm.h + include/grpc/impl/codegen/atm_gcc_atomic.h + include/grpc/impl/codegen/atm_gcc_sync.h + include/grpc/impl/codegen/atm_windows.h + include/grpc/impl/codegen/byte_buffer.h + include/grpc/impl/codegen/byte_buffer_reader.h + include/grpc/impl/codegen/compression_types.h + include/grpc/impl/codegen/connectivity_state.h + include/grpc/impl/codegen/fork.h + include/grpc/impl/codegen/gpr_slice.h + include/grpc/impl/codegen/gpr_types.h + include/grpc/impl/codegen/grpc_types.h + include/grpc/impl/codegen/log.h + include/grpc/impl/codegen/port_platform.h + include/grpc/impl/codegen/propagation_bits.h + include/grpc/impl/codegen/slice.h + include/grpc/impl/codegen/status.h + include/grpc/impl/codegen/sync.h + include/grpc/impl/codegen/sync_abseil.h + include/grpc/impl/codegen/sync_custom.h + include/grpc/impl/codegen/sync_generic.h + include/grpc/impl/codegen/sync_posix.h + include/grpc/impl/codegen/sync_windows.h + include/grpc/support/alloc.h + include/grpc/support/atm.h + include/grpc/support/atm_gcc_atomic.h + include/grpc/support/atm_gcc_sync.h + include/grpc/support/atm_windows.h + include/grpc/support/cpu.h + include/grpc/support/log.h + include/grpc/support/log_windows.h + include/grpc/support/port_platform.h + include/grpc/support/string_util.h + include/grpc/support/sync.h + include/grpc/support/sync_abseil.h + include/grpc/support/sync_custom.h + include/grpc/support/sync_generic.h + include/grpc/support/sync_posix.h + include/grpc/support/sync_windows.h + include/grpc/support/thd_id.h + include/grpc/support/time.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if(gRPC_INSTALL) + install(TARGETS gpr EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + + +add_library(grpc + src/core/ext/filters/census/grpc_context.cc + src/core/ext/filters/client_channel/backend_metric.cc + src/core/ext/filters/client_channel/backup_poller.cc + src/core/ext/filters/client_channel/channel_connectivity.cc + src/core/ext/filters/client_channel/client_channel.cc + src/core/ext/filters/client_channel/client_channel_channelz.cc + src/core/ext/filters/client_channel/client_channel_factory.cc + src/core/ext/filters/client_channel/client_channel_plugin.cc + src/core/ext/filters/client_channel/config_selector.cc + src/core/ext/filters/client_channel/dynamic_filters.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc + src/core/ext/filters/client_channel/health/health_check_client.cc + src/core/ext/filters/client_channel/http_connect_handshaker.cc + src/core/ext/filters/client_channel/http_proxy.cc + src/core/ext/filters/client_channel/lb_policy.cc + src/core/ext/filters/client_channel/lb_policy/address_filtering.cc + src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc + src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc + src/core/ext/filters/client_channel/lb_policy/priority/priority.cc + src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc + src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc + src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc + src/core/ext/filters/client_channel/lb_policy/xds/cds.cc + src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc + src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc + src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc + src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc + src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/resolver.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc + src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc + src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc + src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc + src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc + src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc + src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc + src/core/ext/filters/client_channel/resolver_registry.cc + src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/retry_filter.cc + src/core/ext/filters/client_channel/retry_service_config.cc + src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc + src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc + src/core/ext/filters/client_channel/service_config_parser.cc + src/core/ext/filters/client_channel/subchannel.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc + src/core/ext/filters/client_idle/client_idle_filter.cc + src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/fault_injection/fault_injection_filter.cc + src/core/ext/filters/fault_injection/service_config_parser.cc + src/core/ext/filters/http/client/http_client_filter.cc + src/core/ext/filters/http/client_authority_filter.cc + src/core/ext/filters/http/http_filters_plugin.cc + src/core/ext/filters/http/message_compress/message_compress_filter.cc + src/core/ext/filters/http/message_compress/message_decompress_filter.cc + src/core/ext/filters/http/server/http_server_filter.cc + src/core/ext/filters/max_age/max_age_filter.cc + src/core/ext/filters/message_size/message_size_filter.cc + src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc + src/core/ext/filters/workarounds/workaround_utils.cc + src/core/ext/transport/chttp2/alpn/alpn.cc + src/core/ext/transport/chttp2/client/authority.cc + src/core/ext/transport/chttp2/client/chttp2_connector.cc + src/core/ext/transport/chttp2/client/insecure/channel_create.cc + src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc + src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc + src/core/ext/transport/chttp2/server/chttp2_server.cc + src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc + src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc + src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc + src/core/ext/transport/chttp2/transport/bin_decoder.cc + src/core/ext/transport/chttp2/transport/bin_encoder.cc + src/core/ext/transport/chttp2/transport/chttp2_plugin.cc + src/core/ext/transport/chttp2/transport/chttp2_transport.cc + src/core/ext/transport/chttp2/transport/context_list.cc + src/core/ext/transport/chttp2/transport/flow_control.cc + src/core/ext/transport/chttp2/transport/frame_data.cc + src/core/ext/transport/chttp2/transport/frame_goaway.cc + src/core/ext/transport/chttp2/transport/frame_ping.cc + src/core/ext/transport/chttp2/transport/frame_rst_stream.cc + src/core/ext/transport/chttp2/transport/frame_settings.cc + src/core/ext/transport/chttp2/transport/frame_window_update.cc + src/core/ext/transport/chttp2/transport/hpack_encoder.cc + src/core/ext/transport/chttp2/transport/hpack_parser.cc + src/core/ext/transport/chttp2/transport/hpack_table.cc + src/core/ext/transport/chttp2/transport/http2_settings.cc + src/core/ext/transport/chttp2/transport/huffsyms.cc + src/core/ext/transport/chttp2/transport/incoming_metadata.cc + src/core/ext/transport/chttp2/transport/parsing.cc + src/core/ext/transport/chttp2/transport/stream_lists.cc + src/core/ext/transport/chttp2/transport/stream_map.cc + src/core/ext/transport/chttp2/transport/varint.cc + src/core/ext/transport/chttp2/transport/writing.cc + src/core/ext/transport/inproc/inproc_plugin.cc + src/core/ext/transport/inproc/inproc_transport.cc + src/core/ext/upb-generated/envoy/admin/v3/config_dump.upb.c + src/core/ext/upb-generated/envoy/annotations/deprecation.upb.c + src/core/ext/upb-generated/envoy/annotations/resource.upb.c + src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c + src/core/ext/upb-generated/envoy/config/bootstrap/v3/bootstrap.upb.c + src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.c + src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c + src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.c + src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.c + src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c + src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.c + src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c + src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.c + src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.c + src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c + src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c + src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c + src/core/ext/upb-generated/envoy/config/metrics/v3/stats.upb.c + src/core/ext/upb-generated/envoy/config/overload/v3/overload.upb.c + src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c + src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c + src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c + src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c + src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c + src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c + src/core/ext/upb-generated/envoy/extensions/filters/common/fault/v3/fault.upb.c + src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c + src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c + src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c + src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c + src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c + src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c + src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c + src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.c + src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.c + src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c + src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.c + src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.c + src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.c + src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.c + src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.c + src/core/ext/upb-generated/envoy/service/status/v3/csds.upb.c + src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.c + src/core/ext/upb-generated/envoy/type/matcher/v3/node.upb.c + src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.c + src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.c + src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c + src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c + src/core/ext/upb-generated/envoy/type/matcher/v3/struct.upb.c + src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c + src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c + src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c + src/core/ext/upb-generated/envoy/type/v3/http.upb.c + src/core/ext/upb-generated/envoy/type/v3/percent.upb.c + src/core/ext/upb-generated/envoy/type/v3/range.upb.c + src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.c + src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c + src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c + src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c + src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c + src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c + src/core/ext/upb-generated/udpa/annotations/migrate.upb.c + src/core/ext/upb-generated/udpa/annotations/security.upb.c + src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c + src/core/ext/upb-generated/udpa/annotations/status.upb.c + src/core/ext/upb-generated/udpa/annotations/versioning.upb.c + src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c + src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c + src/core/ext/upb-generated/validate/validate.upb.c + src/core/ext/upb-generated/xds/core/v3/authority.upb.c + src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c + src/core/ext/upb-generated/xds/core/v3/context_params.upb.c + src/core/ext/upb-generated/xds/core/v3/resource.upb.c + src/core/ext/upb-generated/xds/core/v3/resource_locator.upb.c + src/core/ext/upb-generated/xds/core/v3/resource_name.upb.c + src/core/ext/upbdefs-generated/envoy/admin/v3/config_dump.upbdefs.c + src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.c + src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/bootstrap/v3/bootstrap.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/cluster/v3/circuit_breaker.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/cluster/v3/filter.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/cluster/v3/outlier_detection.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/backoff.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/event_service_config.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/extension.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/grpc_service.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/health_check.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/http_uri.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/proxy_protocol.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint_components.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/load_report.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/listener/v3/api_listener.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/metrics/v3/stats.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/overload/v3/overload.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c + src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c + src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c + src/core/ext/upbdefs-generated/envoy/extensions/filters/common/fault/v3/fault.upbdefs.c + src/core/ext/upbdefs-generated/envoy/extensions/filters/http/fault/v3/fault.upbdefs.c + src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c + src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c + src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c + src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c + src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c + src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c + src/core/ext/upbdefs-generated/envoy/service/cluster/v3/cds.upbdefs.c + src/core/ext/upbdefs-generated/envoy/service/discovery/v3/ads.upbdefs.c + src/core/ext/upbdefs-generated/envoy/service/discovery/v3/discovery.upbdefs.c + src/core/ext/upbdefs-generated/envoy/service/endpoint/v3/eds.upbdefs.c + src/core/ext/upbdefs-generated/envoy/service/listener/v3/lds.upbdefs.c + src/core/ext/upbdefs-generated/envoy/service/load_stats/v3/lrs.upbdefs.c + src/core/ext/upbdefs-generated/envoy/service/route/v3/rds.upbdefs.c + src/core/ext/upbdefs-generated/envoy/service/route/v3/srds.upbdefs.c + src/core/ext/upbdefs-generated/envoy/service/status/v3/csds.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/matcher/v3/metadata.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/matcher/v3/node.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/matcher/v3/number.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/matcher/v3/path.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/matcher/v3/string.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/matcher/v3/struct.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/metadata/v3/metadata.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/tracing/v3/custom_tag.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/v3/http.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/v3/percent.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/v3/range.upbdefs.c + src/core/ext/upbdefs-generated/envoy/type/v3/semantic_version.upbdefs.c + src/core/ext/upbdefs-generated/google/api/annotations.upbdefs.c + src/core/ext/upbdefs-generated/google/api/http.upbdefs.c + src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.c + src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.c + src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.c + src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.c + src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.c + src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c + src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c + src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c + src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c + src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c + src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c + src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c + src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c + src/core/ext/upbdefs-generated/validate/validate.upbdefs.c + src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c + src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c + src/core/ext/upbdefs-generated/xds/core/v3/context_params.upbdefs.c + src/core/ext/upbdefs-generated/xds/core/v3/resource.upbdefs.c + src/core/ext/upbdefs-generated/xds/core/v3/resource_locator.upbdefs.c + src/core/ext/upbdefs-generated/xds/core/v3/resource_name.upbdefs.c + src/core/ext/xds/certificate_provider_registry.cc + src/core/ext/xds/certificate_provider_store.cc + src/core/ext/xds/file_watcher_certificate_provider_factory.cc + src/core/ext/xds/xds_api.cc + src/core/ext/xds/xds_bootstrap.cc + src/core/ext/xds/xds_certificate_provider.cc + src/core/ext/xds/xds_client.cc + src/core/ext/xds/xds_client_stats.cc + src/core/ext/xds/xds_http_fault_filter.cc + src/core/ext/xds/xds_http_filters.cc + src/core/ext/xds/xds_server_config_fetcher.cc + src/core/lib/address_utils/parse_address.cc + src/core/lib/address_utils/sockaddr_utils.cc + src/core/lib/avl/avl.cc + src/core/lib/backoff/backoff.cc + src/core/lib/channel/channel_args.cc + src/core/lib/channel/channel_stack.cc + src/core/lib/channel/channel_stack_builder.cc + src/core/lib/channel/channel_trace.cc + src/core/lib/channel/channelz.cc + src/core/lib/channel/channelz_registry.cc + src/core/lib/channel/connected_channel.cc + src/core/lib/channel/handshaker.cc + src/core/lib/channel/handshaker_registry.cc + src/core/lib/channel/status_util.cc + src/core/lib/compression/compression.cc + src/core/lib/compression/compression_args.cc + src/core/lib/compression/compression_internal.cc + src/core/lib/compression/message_compress.cc + src/core/lib/compression/stream_compression.cc + src/core/lib/compression/stream_compression_gzip.cc + src/core/lib/compression/stream_compression_identity.cc + src/core/lib/debug/stats.cc + src/core/lib/debug/stats_data.cc + src/core/lib/debug/trace.cc + src/core/lib/event_engine/slice_allocator.cc + src/core/lib/event_engine/sockaddr.cc + src/core/lib/http/format_request.cc + src/core/lib/http/httpcli.cc + src/core/lib/http/httpcli_security_connector.cc + src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc + src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc + src/core/lib/iomgr/combiner.cc + src/core/lib/iomgr/dualstack_socket_posix.cc + src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.cc + src/core/lib/iomgr/endpoint_pair_posix.cc + src/core/lib/iomgr/endpoint_pair_uv.cc + src/core/lib/iomgr/endpoint_pair_windows.cc + src/core/lib/iomgr/error.cc + src/core/lib/iomgr/error_cfstream.cc + src/core/lib/iomgr/ev_apple.cc + src/core/lib/iomgr/ev_epoll1_linux.cc + src/core/lib/iomgr/ev_epollex_linux.cc + src/core/lib/iomgr/ev_poll_posix.cc + src/core/lib/iomgr/ev_posix.cc + src/core/lib/iomgr/ev_windows.cc + src/core/lib/iomgr/exec_ctx.cc + src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc + src/core/lib/iomgr/executor/threadpool.cc + src/core/lib/iomgr/fork_posix.cc + src/core/lib/iomgr/fork_windows.cc + src/core/lib/iomgr/gethostname_fallback.cc + src/core/lib/iomgr/gethostname_host_name_max.cc + src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc + src/core/lib/iomgr/internal_errqueue.cc + src/core/lib/iomgr/iocp_windows.cc + src/core/lib/iomgr/iomgr.cc + src/core/lib/iomgr/iomgr_custom.cc + src/core/lib/iomgr/iomgr_internal.cc + src/core/lib/iomgr/iomgr_posix.cc + src/core/lib/iomgr/iomgr_posix_cfstream.cc + src/core/lib/iomgr/iomgr_uv.cc + src/core/lib/iomgr/iomgr_windows.cc + src/core/lib/iomgr/is_epollexclusive_available.cc + src/core/lib/iomgr/load_file.cc + src/core/lib/iomgr/lockfree_event.cc + src/core/lib/iomgr/polling_entity.cc + src/core/lib/iomgr/pollset.cc + src/core/lib/iomgr/pollset_custom.cc + src/core/lib/iomgr/pollset_set.cc + src/core/lib/iomgr/pollset_set_custom.cc + src/core/lib/iomgr/pollset_set_windows.cc + src/core/lib/iomgr/pollset_uv.cc + src/core/lib/iomgr/pollset_windows.cc + src/core/lib/iomgr/resolve_address.cc + src/core/lib/iomgr/resolve_address_custom.cc + src/core/lib/iomgr/resolve_address_posix.cc + src/core/lib/iomgr/resolve_address_windows.cc + src/core/lib/iomgr/resource_quota.cc + src/core/lib/iomgr/socket_factory_posix.cc + src/core/lib/iomgr/socket_mutator.cc + src/core/lib/iomgr/socket_utils_common_posix.cc + src/core/lib/iomgr/socket_utils_linux.cc + src/core/lib/iomgr/socket_utils_posix.cc + src/core/lib/iomgr/socket_utils_uv.cc + src/core/lib/iomgr/socket_utils_windows.cc + src/core/lib/iomgr/socket_windows.cc + src/core/lib/iomgr/tcp_client.cc + src/core/lib/iomgr/tcp_client_cfstream.cc + src/core/lib/iomgr/tcp_client_custom.cc + src/core/lib/iomgr/tcp_client_posix.cc + src/core/lib/iomgr/tcp_client_windows.cc + src/core/lib/iomgr/tcp_custom.cc + src/core/lib/iomgr/tcp_posix.cc + src/core/lib/iomgr/tcp_server.cc + src/core/lib/iomgr/tcp_server_custom.cc + src/core/lib/iomgr/tcp_server_posix.cc + src/core/lib/iomgr/tcp_server_utils_posix_common.cc + src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc + src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc + src/core/lib/iomgr/tcp_server_windows.cc + src/core/lib/iomgr/tcp_uv.cc + src/core/lib/iomgr/tcp_windows.cc + src/core/lib/iomgr/time_averaged_stats.cc + src/core/lib/iomgr/timer.cc + src/core/lib/iomgr/timer_custom.cc + src/core/lib/iomgr/timer_generic.cc + src/core/lib/iomgr/timer_heap.cc + src/core/lib/iomgr/timer_manager.cc + src/core/lib/iomgr/timer_uv.cc + src/core/lib/iomgr/udp_server.cc + src/core/lib/iomgr/unix_sockets_posix.cc + src/core/lib/iomgr/unix_sockets_posix_noop.cc + src/core/lib/iomgr/wakeup_fd_eventfd.cc + src/core/lib/iomgr/wakeup_fd_nospecial.cc + src/core/lib/iomgr/wakeup_fd_pipe.cc + src/core/lib/iomgr/wakeup_fd_posix.cc + src/core/lib/iomgr/work_serializer.cc + src/core/lib/json/json_reader.cc + src/core/lib/json/json_util.cc + src/core/lib/json/json_writer.cc + src/core/lib/matchers/matchers.cc + src/core/lib/security/context/security_context.cc + src/core/lib/security/credentials/alts/alts_credentials.cc + src/core/lib/security/credentials/alts/check_gcp_environment.cc + src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc + src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc + src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc + src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc + src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc + src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc + src/core/lib/security/credentials/composite/composite_credentials.cc + src/core/lib/security/credentials/credentials.cc + src/core/lib/security/credentials/credentials_metadata.cc + src/core/lib/security/credentials/external/aws_external_account_credentials.cc + src/core/lib/security/credentials/external/aws_request_signer.cc + src/core/lib/security/credentials/external/external_account_credentials.cc + src/core/lib/security/credentials/external/file_external_account_credentials.cc + src/core/lib/security/credentials/external/url_external_account_credentials.cc + src/core/lib/security/credentials/fake/fake_credentials.cc + src/core/lib/security/credentials/google_default/credentials_generic.cc + src/core/lib/security/credentials/google_default/google_default_credentials.cc + src/core/lib/security/credentials/iam/iam_credentials.cc + src/core/lib/security/credentials/insecure/insecure_credentials.cc + src/core/lib/security/credentials/jwt/json_token.cc + src/core/lib/security/credentials/jwt/jwt_credentials.cc + src/core/lib/security/credentials/jwt/jwt_verifier.cc + src/core/lib/security/credentials/local/local_credentials.cc + src/core/lib/security/credentials/oauth2/oauth2_credentials.cc + src/core/lib/security/credentials/plugin/plugin_credentials.cc + src/core/lib/security/credentials/ssl/ssl_credentials.cc + src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc + src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc + src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc + src/core/lib/security/credentials/tls/tls_credentials.cc + src/core/lib/security/credentials/tls/tls_utils.cc + src/core/lib/security/credentials/xds/xds_credentials.cc + src/core/lib/security/security_connector/alts/alts_security_connector.cc + src/core/lib/security/security_connector/fake/fake_security_connector.cc + src/core/lib/security/security_connector/insecure/insecure_security_connector.cc + src/core/lib/security/security_connector/load_system_roots_fallback.cc + src/core/lib/security/security_connector/load_system_roots_linux.cc + src/core/lib/security/security_connector/local/local_security_connector.cc + src/core/lib/security/security_connector/security_connector.cc + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc + src/core/lib/security/security_connector/ssl_utils.cc + src/core/lib/security/security_connector/ssl_utils_config.cc + src/core/lib/security/security_connector/tls/tls_security_connector.cc + src/core/lib/security/transport/client_auth_filter.cc + src/core/lib/security/transport/secure_endpoint.cc + src/core/lib/security/transport/security_handshaker.cc + src/core/lib/security/transport/server_auth_filter.cc + src/core/lib/security/transport/tsi_error.cc + src/core/lib/security/util/json_util.cc + src/core/lib/slice/b64.cc + src/core/lib/slice/percent_encoding.cc + src/core/lib/slice/slice.cc + src/core/lib/slice/slice_buffer.cc + src/core/lib/slice/slice_intern.cc + src/core/lib/slice/slice_string_helpers.cc + src/core/lib/surface/api_trace.cc + src/core/lib/surface/byte_buffer.cc + src/core/lib/surface/byte_buffer_reader.cc + src/core/lib/surface/call.cc + src/core/lib/surface/call_details.cc + src/core/lib/surface/call_log_batch.cc + src/core/lib/surface/channel.cc + src/core/lib/surface/channel_init.cc + src/core/lib/surface/channel_ping.cc + src/core/lib/surface/channel_stack_type.cc + src/core/lib/surface/completion_queue.cc + src/core/lib/surface/completion_queue_factory.cc + src/core/lib/surface/event_string.cc + src/core/lib/surface/init.cc + src/core/lib/surface/init_secure.cc + src/core/lib/surface/lame_client.cc + src/core/lib/surface/metadata_array.cc + src/core/lib/surface/server.cc + src/core/lib/surface/validate_metadata.cc + src/core/lib/surface/version.cc + src/core/lib/transport/authority_override.cc + src/core/lib/transport/bdp_estimator.cc + src/core/lib/transport/byte_stream.cc + src/core/lib/transport/connectivity_state.cc + src/core/lib/transport/error_utils.cc + src/core/lib/transport/metadata.cc + src/core/lib/transport/metadata_batch.cc + src/core/lib/transport/pid_controller.cc + src/core/lib/transport/static_metadata.cc + src/core/lib/transport/status_conversion.cc + src/core/lib/transport/status_metadata.cc + src/core/lib/transport/timeout_encoding.cc + src/core/lib/transport/transport.cc + src/core/lib/transport/transport_op_string.cc + src/core/lib/uri/uri_parser.cc + src/core/plugin_registry/grpc_plugin_registry.cc + src/core/tsi/alts/crypt/aes_gcm.cc + src/core/tsi/alts/crypt/gsec.cc + src/core/tsi/alts/frame_protector/alts_counter.cc + src/core/tsi/alts/frame_protector/alts_crypter.cc + src/core/tsi/alts/frame_protector/alts_frame_protector.cc + src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc + src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc + src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc + src/core/tsi/alts/frame_protector/frame_handler.cc + src/core/tsi/alts/handshaker/alts_handshaker_client.cc + src/core/tsi/alts/handshaker/alts_shared_resource.cc + src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc + src/core/tsi/alts/handshaker/alts_tsi_utils.cc + src/core/tsi/alts/handshaker/transport_security_common_api.cc + src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc + src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc + src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc + src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc + src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc + src/core/tsi/fake_transport_security.cc + src/core/tsi/local_transport_security.cc + src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc + src/core/tsi/ssl/session_cache/ssl_session_cache.cc + src/core/tsi/ssl/session_cache/ssl_session_openssl.cc + src/core/tsi/ssl_transport_security.cc + src/core/tsi/transport_security.cc + src/core/tsi/transport_security_grpc.cc +) + +set_target_properties(grpc PROPERTIES + VERSION ${gRPC_CORE_VERSION} + SOVERSION ${gRPC_CORE_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc PROPERTIES COMPILE_PDB_NAME "grpc" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) +target_link_libraries(grpc + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_ZLIB_LIBRARIES} + ${_gRPC_CARES_LIBRARIES} + ${_gRPC_ADDRESS_SORTING_LIBRARIES} + ${_gRPC_RE2_LIBRARIES} + ${_gRPC_UPB_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flat_hash_map + absl::inlined_vector + absl::bind_front + absl::statusor + gpr + ${_gRPC_SSL_LIBRARIES} + address_sorting + + libmbedx509_gramine.a + libmbedcrypto_gramine.a + libcjson.a + libcjson_utils.a +) +if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(grpc "-framework CoreFoundation") +endif() + +foreach(_hdr + include/grpc/byte_buffer.h + include/grpc/byte_buffer_reader.h + include/grpc/census.h + include/grpc/compression.h + include/grpc/event_engine/channel_args.h + include/grpc/event_engine/event_engine.h + include/grpc/event_engine/port.h + include/grpc/event_engine/slice_allocator.h + include/grpc/fork.h + include/grpc/grpc.h + include/grpc/grpc_posix.h + include/grpc/grpc_security.h + include/grpc/grpc_security_constants.h + include/grpc/load_reporting.h + include/grpc/slice.h + include/grpc/slice_buffer.h + include/grpc/status.h + include/grpc/support/workaround_list.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if(gRPC_INSTALL) + install(TARGETS grpc EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +if(gRPC_BUILD_CSHARP_EXT) + +add_library(grpc_csharp_ext SHARED + src/csharp/ext/grpc_csharp_ext.c +) + +set_target_properties(grpc_csharp_ext PROPERTIES + VERSION ${gRPC_CORE_VERSION} + SOVERSION ${gRPC_CORE_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc_csharp_ext PROPERTIES COMPILE_PDB_NAME "grpc_csharp_ext" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_csharp_ext.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc_csharp_ext + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) +target_link_libraries(grpc_csharp_ext + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_library(grpc_test_util + test/core/util/cmdline.cc + test/core/util/fuzzer_util.cc + test/core/util/grpc_profiler.cc + test/core/util/histogram.cc + test/core/util/memory_counters.cc + test/core/util/mock_endpoint.cc + test/core/util/parse_hexstring.cc + test/core/util/passthru_endpoint.cc + test/core/util/port.cc + test/core/util/port_isolated_runtime_environment.cc + test/core/util/port_server_client.cc + test/core/util/reconnect_server.cc + test/core/util/resolve_localhost_ip46.cc + test/core/util/slice_splitter.cc + test/core/util/stack_tracer.cc + test/core/util/subprocess_posix.cc + test/core/util/subprocess_windows.cc + test/core/util/test_config.cc + test/core/util/test_tcp_server.cc + test/core/util/tls_utils.cc + test/core/util/tracer_util.cc + test/core/util/trickle_endpoint.cc +) + +set_target_properties(grpc_test_util PROPERTIES + VERSION ${gRPC_CORE_VERSION} + SOVERSION ${gRPC_CORE_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc_test_util PROPERTIES COMPILE_PDB_NAME "grpc_test_util" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_test_util.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc_test_util + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) +target_link_libraries(grpc_test_util + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::failure_signal_handler + absl::stacktrace + absl::symbolize + grpc +) +if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(grpc_test_util "-framework CoreFoundation") +endif() + + +endif() +if(gRPC_BUILD_TESTS) + +add_library(grpc_test_util_unsecure + test/core/util/cmdline.cc + test/core/util/fuzzer_util.cc + test/core/util/grpc_profiler.cc + test/core/util/histogram.cc + test/core/util/memory_counters.cc + test/core/util/mock_endpoint.cc + test/core/util/parse_hexstring.cc + test/core/util/passthru_endpoint.cc + test/core/util/port.cc + test/core/util/port_isolated_runtime_environment.cc + test/core/util/port_server_client.cc + test/core/util/reconnect_server.cc + test/core/util/resolve_localhost_ip46.cc + test/core/util/slice_splitter.cc + test/core/util/stack_tracer.cc + test/core/util/subprocess_posix.cc + test/core/util/subprocess_windows.cc + test/core/util/test_config.cc + test/core/util/test_tcp_server.cc + test/core/util/tracer_util.cc + test/core/util/trickle_endpoint.cc +) + +set_target_properties(grpc_test_util_unsecure PROPERTIES + VERSION ${gRPC_CORE_VERSION} + SOVERSION ${gRPC_CORE_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc_test_util_unsecure PROPERTIES COMPILE_PDB_NAME "grpc_test_util_unsecure" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_test_util_unsecure.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc_test_util_unsecure + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) +target_link_libraries(grpc_test_util_unsecure + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::failure_signal_handler + absl::stacktrace + absl::symbolize + grpc_unsecure +) +if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(grpc_test_util_unsecure "-framework CoreFoundation") +endif() + + +endif() + +add_library(grpc_unsecure + src/core/ext/filters/census/grpc_context.cc + src/core/ext/filters/client_channel/backend_metric.cc + src/core/ext/filters/client_channel/backup_poller.cc + src/core/ext/filters/client_channel/channel_connectivity.cc + src/core/ext/filters/client_channel/client_channel.cc + src/core/ext/filters/client_channel/client_channel_channelz.cc + src/core/ext/filters/client_channel/client_channel_factory.cc + src/core/ext/filters/client_channel/client_channel_plugin.cc + src/core/ext/filters/client_channel/config_selector.cc + src/core/ext/filters/client_channel/dynamic_filters.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc + src/core/ext/filters/client_channel/health/health_check_client.cc + src/core/ext/filters/client_channel/http_connect_handshaker.cc + src/core/ext/filters/client_channel/http_proxy.cc + src/core/ext/filters/client_channel/lb_policy.cc + src/core/ext/filters/client_channel/lb_policy/address_filtering.cc + src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc + src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc + src/core/ext/filters/client_channel/lb_policy/priority/priority.cc + src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc + src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc + src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc + src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/resolver.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc + src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc + src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc + src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc + src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc + src/core/ext/filters/client_channel/resolver_registry.cc + src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/retry_filter.cc + src/core/ext/filters/client_channel/retry_service_config.cc + src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc + src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc + src/core/ext/filters/client_channel/service_config_parser.cc + src/core/ext/filters/client_channel/subchannel.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc + src/core/ext/filters/client_idle/client_idle_filter.cc + src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/fault_injection/fault_injection_filter.cc + src/core/ext/filters/fault_injection/service_config_parser.cc + src/core/ext/filters/http/client/http_client_filter.cc + src/core/ext/filters/http/client_authority_filter.cc + src/core/ext/filters/http/http_filters_plugin.cc + src/core/ext/filters/http/message_compress/message_compress_filter.cc + src/core/ext/filters/http/message_compress/message_decompress_filter.cc + src/core/ext/filters/http/server/http_server_filter.cc + src/core/ext/filters/max_age/max_age_filter.cc + src/core/ext/filters/message_size/message_size_filter.cc + src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc + src/core/ext/filters/workarounds/workaround_utils.cc + src/core/ext/transport/chttp2/alpn/alpn.cc + src/core/ext/transport/chttp2/client/authority.cc + src/core/ext/transport/chttp2/client/chttp2_connector.cc + src/core/ext/transport/chttp2/client/insecure/channel_create.cc + src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc + src/core/ext/transport/chttp2/server/chttp2_server.cc + src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc + src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc + src/core/ext/transport/chttp2/transport/bin_decoder.cc + src/core/ext/transport/chttp2/transport/bin_encoder.cc + src/core/ext/transport/chttp2/transport/chttp2_plugin.cc + src/core/ext/transport/chttp2/transport/chttp2_transport.cc + src/core/ext/transport/chttp2/transport/context_list.cc + src/core/ext/transport/chttp2/transport/flow_control.cc + src/core/ext/transport/chttp2/transport/frame_data.cc + src/core/ext/transport/chttp2/transport/frame_goaway.cc + src/core/ext/transport/chttp2/transport/frame_ping.cc + src/core/ext/transport/chttp2/transport/frame_rst_stream.cc + src/core/ext/transport/chttp2/transport/frame_settings.cc + src/core/ext/transport/chttp2/transport/frame_window_update.cc + src/core/ext/transport/chttp2/transport/hpack_encoder.cc + src/core/ext/transport/chttp2/transport/hpack_parser.cc + src/core/ext/transport/chttp2/transport/hpack_table.cc + src/core/ext/transport/chttp2/transport/http2_settings.cc + src/core/ext/transport/chttp2/transport/huffsyms.cc + src/core/ext/transport/chttp2/transport/incoming_metadata.cc + src/core/ext/transport/chttp2/transport/parsing.cc + src/core/ext/transport/chttp2/transport/stream_lists.cc + src/core/ext/transport/chttp2/transport/stream_map.cc + src/core/ext/transport/chttp2/transport/varint.cc + src/core/ext/transport/chttp2/transport/writing.cc + src/core/ext/transport/inproc/inproc_plugin.cc + src/core/ext/transport/inproc/inproc_transport.cc + src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c + src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c + src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c + src/core/ext/upb-generated/validate/validate.upb.c + src/core/lib/address_utils/parse_address.cc + src/core/lib/address_utils/sockaddr_utils.cc + src/core/lib/avl/avl.cc + src/core/lib/backoff/backoff.cc + src/core/lib/channel/channel_args.cc + src/core/lib/channel/channel_stack.cc + src/core/lib/channel/channel_stack_builder.cc + src/core/lib/channel/channel_trace.cc + src/core/lib/channel/channelz.cc + src/core/lib/channel/channelz_registry.cc + src/core/lib/channel/connected_channel.cc + src/core/lib/channel/handshaker.cc + src/core/lib/channel/handshaker_registry.cc + src/core/lib/channel/status_util.cc + src/core/lib/compression/compression.cc + src/core/lib/compression/compression_args.cc + src/core/lib/compression/compression_internal.cc + src/core/lib/compression/message_compress.cc + src/core/lib/compression/stream_compression.cc + src/core/lib/compression/stream_compression_gzip.cc + src/core/lib/compression/stream_compression_identity.cc + src/core/lib/debug/stats.cc + src/core/lib/debug/stats_data.cc + src/core/lib/debug/trace.cc + src/core/lib/event_engine/slice_allocator.cc + src/core/lib/event_engine/sockaddr.cc + src/core/lib/http/format_request.cc + src/core/lib/http/httpcli.cc + src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc + src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc + src/core/lib/iomgr/combiner.cc + src/core/lib/iomgr/dualstack_socket_posix.cc + src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.cc + src/core/lib/iomgr/endpoint_pair_posix.cc + src/core/lib/iomgr/endpoint_pair_uv.cc + src/core/lib/iomgr/endpoint_pair_windows.cc + src/core/lib/iomgr/error.cc + src/core/lib/iomgr/error_cfstream.cc + src/core/lib/iomgr/ev_apple.cc + src/core/lib/iomgr/ev_epoll1_linux.cc + src/core/lib/iomgr/ev_epollex_linux.cc + src/core/lib/iomgr/ev_poll_posix.cc + src/core/lib/iomgr/ev_posix.cc + src/core/lib/iomgr/ev_windows.cc + src/core/lib/iomgr/exec_ctx.cc + src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc + src/core/lib/iomgr/executor/threadpool.cc + src/core/lib/iomgr/fork_posix.cc + src/core/lib/iomgr/fork_windows.cc + src/core/lib/iomgr/gethostname_fallback.cc + src/core/lib/iomgr/gethostname_host_name_max.cc + src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc + src/core/lib/iomgr/internal_errqueue.cc + src/core/lib/iomgr/iocp_windows.cc + src/core/lib/iomgr/iomgr.cc + src/core/lib/iomgr/iomgr_custom.cc + src/core/lib/iomgr/iomgr_internal.cc + src/core/lib/iomgr/iomgr_posix.cc + src/core/lib/iomgr/iomgr_posix_cfstream.cc + src/core/lib/iomgr/iomgr_uv.cc + src/core/lib/iomgr/iomgr_windows.cc + src/core/lib/iomgr/is_epollexclusive_available.cc + src/core/lib/iomgr/load_file.cc + src/core/lib/iomgr/lockfree_event.cc + src/core/lib/iomgr/polling_entity.cc + src/core/lib/iomgr/pollset.cc + src/core/lib/iomgr/pollset_custom.cc + src/core/lib/iomgr/pollset_set.cc + src/core/lib/iomgr/pollset_set_custom.cc + src/core/lib/iomgr/pollset_set_windows.cc + src/core/lib/iomgr/pollset_uv.cc + src/core/lib/iomgr/pollset_windows.cc + src/core/lib/iomgr/resolve_address.cc + src/core/lib/iomgr/resolve_address_custom.cc + src/core/lib/iomgr/resolve_address_posix.cc + src/core/lib/iomgr/resolve_address_windows.cc + src/core/lib/iomgr/resource_quota.cc + src/core/lib/iomgr/socket_factory_posix.cc + src/core/lib/iomgr/socket_mutator.cc + src/core/lib/iomgr/socket_utils_common_posix.cc + src/core/lib/iomgr/socket_utils_linux.cc + src/core/lib/iomgr/socket_utils_posix.cc + src/core/lib/iomgr/socket_utils_uv.cc + src/core/lib/iomgr/socket_utils_windows.cc + src/core/lib/iomgr/socket_windows.cc + src/core/lib/iomgr/tcp_client.cc + src/core/lib/iomgr/tcp_client_cfstream.cc + src/core/lib/iomgr/tcp_client_custom.cc + src/core/lib/iomgr/tcp_client_posix.cc + src/core/lib/iomgr/tcp_client_windows.cc + src/core/lib/iomgr/tcp_custom.cc + src/core/lib/iomgr/tcp_posix.cc + src/core/lib/iomgr/tcp_server.cc + src/core/lib/iomgr/tcp_server_custom.cc + src/core/lib/iomgr/tcp_server_posix.cc + src/core/lib/iomgr/tcp_server_utils_posix_common.cc + src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc + src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc + src/core/lib/iomgr/tcp_server_windows.cc + src/core/lib/iomgr/tcp_uv.cc + src/core/lib/iomgr/tcp_windows.cc + src/core/lib/iomgr/time_averaged_stats.cc + src/core/lib/iomgr/timer.cc + src/core/lib/iomgr/timer_custom.cc + src/core/lib/iomgr/timer_generic.cc + src/core/lib/iomgr/timer_heap.cc + src/core/lib/iomgr/timer_manager.cc + src/core/lib/iomgr/timer_uv.cc + src/core/lib/iomgr/udp_server.cc + src/core/lib/iomgr/unix_sockets_posix.cc + src/core/lib/iomgr/unix_sockets_posix_noop.cc + src/core/lib/iomgr/wakeup_fd_eventfd.cc + src/core/lib/iomgr/wakeup_fd_nospecial.cc + src/core/lib/iomgr/wakeup_fd_pipe.cc + src/core/lib/iomgr/wakeup_fd_posix.cc + src/core/lib/iomgr/work_serializer.cc + src/core/lib/json/json_reader.cc + src/core/lib/json/json_util.cc + src/core/lib/json/json_writer.cc + src/core/lib/slice/b64.cc + src/core/lib/slice/percent_encoding.cc + src/core/lib/slice/slice.cc + src/core/lib/slice/slice_buffer.cc + src/core/lib/slice/slice_intern.cc + src/core/lib/slice/slice_string_helpers.cc + src/core/lib/surface/api_trace.cc + src/core/lib/surface/byte_buffer.cc + src/core/lib/surface/byte_buffer_reader.cc + src/core/lib/surface/call.cc + src/core/lib/surface/call_details.cc + src/core/lib/surface/call_log_batch.cc + src/core/lib/surface/channel.cc + src/core/lib/surface/channel_init.cc + src/core/lib/surface/channel_ping.cc + src/core/lib/surface/channel_stack_type.cc + src/core/lib/surface/completion_queue.cc + src/core/lib/surface/completion_queue_factory.cc + src/core/lib/surface/event_string.cc + src/core/lib/surface/init.cc + src/core/lib/surface/init_unsecure.cc + src/core/lib/surface/lame_client.cc + src/core/lib/surface/metadata_array.cc + src/core/lib/surface/server.cc + src/core/lib/surface/validate_metadata.cc + src/core/lib/surface/version.cc + src/core/lib/transport/authority_override.cc + src/core/lib/transport/bdp_estimator.cc + src/core/lib/transport/byte_stream.cc + src/core/lib/transport/connectivity_state.cc + src/core/lib/transport/error_utils.cc + src/core/lib/transport/metadata.cc + src/core/lib/transport/metadata_batch.cc + src/core/lib/transport/pid_controller.cc + src/core/lib/transport/static_metadata.cc + src/core/lib/transport/status_conversion.cc + src/core/lib/transport/status_metadata.cc + src/core/lib/transport/timeout_encoding.cc + src/core/lib/transport/transport.cc + src/core/lib/transport/transport_op_string.cc + src/core/lib/uri/uri_parser.cc + src/core/plugin_registry/grpc_unsecure_plugin_registry.cc +) + +set_target_properties(grpc_unsecure PROPERTIES + VERSION ${gRPC_CORE_VERSION} + SOVERSION ${gRPC_CORE_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc_unsecure PROPERTIES COMPILE_PDB_NAME "grpc_unsecure" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_unsecure.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc_unsecure + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) +target_link_libraries(grpc_unsecure + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_ZLIB_LIBRARIES} + ${_gRPC_CARES_LIBRARIES} + ${_gRPC_ADDRESS_SORTING_LIBRARIES} + ${_gRPC_RE2_LIBRARIES} + ${_gRPC_UPB_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flat_hash_map + absl::inlined_vector + absl::statusor + gpr + address_sorting +) +if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(grpc_unsecure "-framework CoreFoundation") +endif() + +foreach(_hdr + include/grpc/byte_buffer.h + include/grpc/byte_buffer_reader.h + include/grpc/census.h + include/grpc/compression.h + include/grpc/event_engine/channel_args.h + include/grpc/event_engine/event_engine.h + include/grpc/event_engine/port.h + include/grpc/event_engine/slice_allocator.h + include/grpc/fork.h + include/grpc/grpc.h + include/grpc/grpc_posix.h + include/grpc/grpc_security_constants.h + include/grpc/load_reporting.h + include/grpc/slice.h + include/grpc/slice_buffer.h + include/grpc/status.h + include/grpc/support/workaround_list.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if(gRPC_INSTALL) + install(TARGETS grpc_unsecure EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +if(gRPC_BUILD_TESTS) + +if(gRPC_BUILD_CODEGEN) +add_library(benchmark_helpers + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_mock.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/microbenchmarks/helpers.cc +) + +set_target_properties(benchmark_helpers PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(benchmark_helpers PROPERTIES COMPILE_PDB_NAME "benchmark_helpers" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/benchmark_helpers.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(benchmark_helpers + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(benchmark_helpers + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_unsecure + grpc_test_util_unsecure + grpc++_test_config +) + +endif() + +endif() + +add_library(grpc++ + src/cpp/client/channel_cc.cc + src/cpp/client/client_callback.cc + src/cpp/client/client_context.cc + src/cpp/client/client_interceptor.cc + src/cpp/client/create_channel.cc + src/cpp/client/create_channel_internal.cc + src/cpp/client/create_channel_posix.cc + src/cpp/client/credentials_cc.cc + src/cpp/client/insecure_credentials.cc + src/cpp/client/secure_credentials.cc + src/cpp/client/xds_credentials.cc + src/cpp/codegen/codegen_init.cc + src/cpp/common/alarm.cc + src/cpp/common/auth_property_iterator.cc + src/cpp/common/channel_arguments.cc + src/cpp/common/channel_filter.cc + src/cpp/common/completion_queue_cc.cc + src/cpp/common/core_codegen.cc + src/cpp/common/resource_quota_cc.cc + src/cpp/common/rpc_method.cc + src/cpp/common/secure_auth_context.cc + src/cpp/common/secure_channel_arguments.cc + src/cpp/common/secure_create_auth_context.cc + src/cpp/common/tls_certificate_provider.cc + src/cpp/common/tls_credentials_options.cc + src/cpp/common/tls_credentials_options_util.cc + src/cpp/common/validate_service_config.cc + src/cpp/common/version_cc.cc + src/cpp/server/async_generic_service.cc + src/cpp/server/channel_argument_option.cc + src/cpp/server/create_default_thread_pool.cc + src/cpp/server/dynamic_thread_pool.cc + src/cpp/server/external_connection_acceptor_impl.cc + src/cpp/server/health/default_health_check_service.cc + src/cpp/server/health/health_check_service.cc + src/cpp/server/health/health_check_service_server_builder_option.cc + src/cpp/server/insecure_server_credentials.cc + src/cpp/server/secure_server_credentials.cc + src/cpp/server/server_builder.cc + src/cpp/server/server_callback.cc + src/cpp/server/server_cc.cc + src/cpp/server/server_context.cc + src/cpp/server/server_credentials.cc + src/cpp/server/server_posix.cc + src/cpp/server/xds_server_credentials.cc + src/cpp/thread_manager/thread_manager.cc + src/cpp/util/byte_buffer_cc.cc + src/cpp/util/status.cc + src/cpp/util/string_ref.cc + src/cpp/util/time_cc.cc + src/cpp/sgx/sgx_ra_tls_credentials.cc + src/cpp/sgx/sgx_ra_tls_options.cc + src/cpp/sgx/sgx_ra_tls_utils.cc +) + +set_target_properties(grpc++ PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc++ PROPERTIES COMPILE_PDB_NAME "grpc++" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc++ + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpc++ + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc +) + +foreach(_hdr + include/grpc++/alarm.h + include/grpc++/channel.h + include/grpc++/client_context.h + include/grpc++/completion_queue.h + include/grpc++/create_channel.h + include/grpc++/create_channel_posix.h + include/grpc++/ext/health_check_service_server_builder_option.h + include/grpc++/generic/async_generic_service.h + include/grpc++/generic/generic_stub.h + include/grpc++/grpc++.h + include/grpc++/health_check_service_interface.h + include/grpc++/impl/call.h + include/grpc++/impl/channel_argument_option.h + include/grpc++/impl/client_unary_call.h + include/grpc++/impl/codegen/async_stream.h + include/grpc++/impl/codegen/async_unary_call.h + include/grpc++/impl/codegen/byte_buffer.h + include/grpc++/impl/codegen/call.h + include/grpc++/impl/codegen/call_hook.h + include/grpc++/impl/codegen/channel_interface.h + include/grpc++/impl/codegen/client_context.h + include/grpc++/impl/codegen/client_unary_call.h + include/grpc++/impl/codegen/completion_queue.h + include/grpc++/impl/codegen/completion_queue_tag.h + include/grpc++/impl/codegen/config.h + include/grpc++/impl/codegen/config_protobuf.h + include/grpc++/impl/codegen/core_codegen.h + include/grpc++/impl/codegen/core_codegen_interface.h + include/grpc++/impl/codegen/create_auth_context.h + include/grpc++/impl/codegen/grpc_library.h + include/grpc++/impl/codegen/metadata_map.h + include/grpc++/impl/codegen/method_handler_impl.h + include/grpc++/impl/codegen/proto_utils.h + include/grpc++/impl/codegen/rpc_method.h + include/grpc++/impl/codegen/rpc_service_method.h + include/grpc++/impl/codegen/security/auth_context.h + include/grpc++/impl/codegen/serialization_traits.h + include/grpc++/impl/codegen/server_context.h + include/grpc++/impl/codegen/server_interface.h + include/grpc++/impl/codegen/service_type.h + include/grpc++/impl/codegen/slice.h + include/grpc++/impl/codegen/status.h + include/grpc++/impl/codegen/status_code_enum.h + include/grpc++/impl/codegen/string_ref.h + include/grpc++/impl/codegen/stub_options.h + include/grpc++/impl/codegen/sync_stream.h + include/grpc++/impl/codegen/time.h + include/grpc++/impl/grpc_library.h + include/grpc++/impl/method_handler_impl.h + include/grpc++/impl/rpc_method.h + include/grpc++/impl/rpc_service_method.h + include/grpc++/impl/serialization_traits.h + include/grpc++/impl/server_builder_option.h + include/grpc++/impl/server_builder_plugin.h + include/grpc++/impl/server_initializer.h + include/grpc++/impl/service_type.h + include/grpc++/resource_quota.h + include/grpc++/security/auth_context.h + include/grpc++/security/auth_metadata_processor.h + include/grpc++/security/credentials.h + include/grpc++/security/server_credentials.h + include/grpc++/server.h + include/grpc++/server_builder.h + include/grpc++/server_context.h + include/grpc++/server_posix.h + include/grpc++/support/async_stream.h + include/grpc++/support/async_unary_call.h + include/grpc++/support/byte_buffer.h + include/grpc++/support/channel_arguments.h + include/grpc++/support/config.h + include/grpc++/support/slice.h + include/grpc++/support/status.h + include/grpc++/support/status_code_enum.h + include/grpc++/support/string_ref.h + include/grpc++/support/stub_options.h + include/grpc++/support/sync_stream.h + include/grpc++/support/time.h + include/grpcpp/alarm.h + include/grpcpp/channel.h + include/grpcpp/client_context.h + include/grpcpp/completion_queue.h + include/grpcpp/create_channel.h + include/grpcpp/create_channel_posix.h + include/grpcpp/ext/health_check_service_server_builder_option.h + include/grpcpp/generic/async_generic_service.h + include/grpcpp/generic/generic_stub.h + include/grpcpp/grpcpp.h + include/grpcpp/health_check_service_interface.h + include/grpcpp/impl/call.h + include/grpcpp/impl/channel_argument_option.h + include/grpcpp/impl/client_unary_call.h + include/grpcpp/impl/codegen/async_generic_service.h + include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/byte_buffer.h + include/grpcpp/impl/codegen/call.h + include/grpcpp/impl/codegen/call_hook.h + include/grpcpp/impl/codegen/call_op_set.h + include/grpcpp/impl/codegen/call_op_set_interface.h + include/grpcpp/impl/codegen/callback_common.h + include/grpcpp/impl/codegen/channel_interface.h + include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h + include/grpcpp/impl/codegen/client_unary_call.h + include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_tag.h + include/grpcpp/impl/codegen/config.h + include/grpcpp/impl/codegen/config_protobuf.h + include/grpcpp/impl/codegen/core_codegen.h + include/grpcpp/impl/codegen/core_codegen_interface.h + include/grpcpp/impl/codegen/create_auth_context.h + include/grpcpp/impl/codegen/delegating_channel.h + include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/intercepted_channel.h + include/grpcpp/impl/codegen/interceptor.h + include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h + include/grpcpp/impl/codegen/metadata_map.h + include/grpcpp/impl/codegen/method_handler.h + include/grpcpp/impl/codegen/method_handler_impl.h + include/grpcpp/impl/codegen/proto_buffer_reader.h + include/grpcpp/impl/codegen/proto_buffer_writer.h + include/grpcpp/impl/codegen/proto_utils.h + include/grpcpp/impl/codegen/rpc_method.h + include/grpcpp/impl/codegen/rpc_service_method.h + include/grpcpp/impl/codegen/security/auth_context.h + include/grpcpp/impl/codegen/serialization_traits.h + include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_handlers.h + include/grpcpp/impl/codegen/server_context.h + include/grpcpp/impl/codegen/server_interceptor.h + include/grpcpp/impl/codegen/server_interface.h + include/grpcpp/impl/codegen/service_type.h + include/grpcpp/impl/codegen/slice.h + include/grpcpp/impl/codegen/status.h + include/grpcpp/impl/codegen/status_code_enum.h + include/grpcpp/impl/codegen/string_ref.h + include/grpcpp/impl/codegen/stub_options.h + include/grpcpp/impl/codegen/sync.h + include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/time.h + include/grpcpp/impl/grpc_library.h + include/grpcpp/impl/method_handler_impl.h + include/grpcpp/impl/rpc_method.h + include/grpcpp/impl/rpc_service_method.h + include/grpcpp/impl/serialization_traits.h + include/grpcpp/impl/server_builder_option.h + include/grpcpp/impl/server_builder_plugin.h + include/grpcpp/impl/server_initializer.h + include/grpcpp/impl/service_type.h + include/grpcpp/resource_quota.h + include/grpcpp/security/auth_context.h + include/grpcpp/security/auth_metadata_processor.h + include/grpcpp/security/credentials.h + include/grpcpp/security/server_credentials.h + include/grpcpp/security/tls_certificate_provider.h + include/grpcpp/security/sgx/sgx_ra_tls.h + include/grpcpp/security/sgx/sgx_ra_tls_options.h + include/grpcpp/server.h + include/grpcpp/server_builder.h + include/grpcpp/server_context.h + include/grpcpp/server_posix.h + include/grpcpp/support/async_stream.h + include/grpcpp/support/async_unary_call.h + include/grpcpp/support/byte_buffer.h + include/grpcpp/support/channel_arguments.h + include/grpcpp/support/client_callback.h + include/grpcpp/support/client_interceptor.h + include/grpcpp/support/config.h + include/grpcpp/support/interceptor.h + include/grpcpp/support/message_allocator.h + include/grpcpp/support/method_handler.h + include/grpcpp/support/proto_buffer_reader.h + include/grpcpp/support/proto_buffer_writer.h + include/grpcpp/support/server_callback.h + include/grpcpp/support/server_interceptor.h + include/grpcpp/support/slice.h + include/grpcpp/support/status.h + include/grpcpp/support/status_code_enum.h + include/grpcpp/support/string_ref.h + include/grpcpp/support/stub_options.h + include/grpcpp/support/sync_stream.h + include/grpcpp/support/time.h + include/grpcpp/support/validate_service_config.h + include/grpcpp/xds_server_builder.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if(gRPC_INSTALL) + install(TARGETS grpc++ EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + + +add_library(grpc++_alts + src/cpp/common/alts_context.cc + src/cpp/common/alts_util.cc +) + +set_target_properties(grpc++_alts PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc++_alts PROPERTIES COMPILE_PDB_NAME "grpc++_alts" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_alts.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc++_alts + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpc++_alts + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ +) + +foreach(_hdr + include/grpcpp/security/alts_context.h + include/grpcpp/security/alts_util.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if(gRPC_INSTALL) + install(TARGETS grpc++_alts EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + + +add_library(grpc++_error_details + src/cpp/util/error_details.cc +) + +set_target_properties(grpc++_error_details PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc++_error_details PROPERTIES COMPILE_PDB_NAME "grpc++_error_details" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_error_details.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc++_error_details + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpc++_error_details + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ +) + +foreach(_hdr + include/grpc++/support/error_details.h + include/grpcpp/support/error_details.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if(gRPC_INSTALL) + install(TARGETS grpc++_error_details EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + + +if(gRPC_BUILD_CODEGEN) +add_library(grpc++_reflection + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h + src/cpp/ext/proto_server_reflection.cc + src/cpp/ext/proto_server_reflection_plugin.cc +) + +set_target_properties(grpc++_reflection PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc++_reflection PROPERTIES COMPILE_PDB_NAME "grpc++_reflection" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_reflection.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc++_reflection + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpc++_reflection + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ +) + +foreach(_hdr + include/grpc++/ext/proto_server_reflection_plugin.h + include/grpcpp/ext/proto_server_reflection_plugin.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() +endif() + +if(gRPC_BUILD_CODEGEN) + +if(gRPC_INSTALL) + install(TARGETS grpc++_reflection EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +endif() +if(gRPC_BUILD_TESTS) + +add_library(grpc++_test + src/cpp/client/channel_test_peer.cc +) + +set_target_properties(grpc++_test PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc++_test PROPERTIES COMPILE_PDB_NAME "grpc++_test" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_test.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc++_test + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpc++_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ +) + +foreach(_hdr + include/grpc++/test/mock_stream.h + include/grpc++/test/server_context_test_spouse.h + include/grpcpp/test/channel_test_peer.h + include/grpcpp/test/default_reactor_test_peer.h + include/grpcpp/test/mock_stream.h + include/grpcpp/test/server_context_test_spouse.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + +endif() +if(gRPC_BUILD_TESTS) + +add_library(grpc++_test_config + test/cpp/util/test_config_cc.cc +) + +set_target_properties(grpc++_test_config PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc++_test_config PROPERTIES COMPILE_PDB_NAME "grpc++_test_config" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_test_config.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc++_test_config + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpc++_test_config + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags_parse + gpr +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_library(grpc++_test_util + test/core/end2end/data/client_certs.cc + test/core/end2end/data/server1_cert.cc + test/core/end2end/data/server1_key.cc + test/core/end2end/data/test_root_cert.cc + test/cpp/util/byte_buffer_proto_helper.cc + test/cpp/util/create_test_channel.cc + test/cpp/util/string_ref_helper.cc + test/cpp/util/subprocess.cc + test/cpp/util/test_credentials_provider.cc +) + +set_target_properties(grpc++_test_util PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc++_test_util PROPERTIES COMPILE_PDB_NAME "grpc++_test_util" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_test_util.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc++_test_util + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpc++_test_util + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc++ + grpc_test_util +) + + +endif() + +add_library(grpc++_unsecure + src/cpp/client/channel_cc.cc + src/cpp/client/client_callback.cc + src/cpp/client/client_context.cc + src/cpp/client/client_interceptor.cc + src/cpp/client/create_channel.cc + src/cpp/client/create_channel_internal.cc + src/cpp/client/create_channel_posix.cc + src/cpp/client/credentials_cc.cc + src/cpp/client/insecure_credentials.cc + src/cpp/codegen/codegen_init.cc + src/cpp/common/alarm.cc + src/cpp/common/channel_arguments.cc + src/cpp/common/channel_filter.cc + src/cpp/common/completion_queue_cc.cc + src/cpp/common/core_codegen.cc + src/cpp/common/insecure_create_auth_context.cc + src/cpp/common/resource_quota_cc.cc + src/cpp/common/rpc_method.cc + src/cpp/common/validate_service_config.cc + src/cpp/common/version_cc.cc + src/cpp/server/async_generic_service.cc + src/cpp/server/channel_argument_option.cc + src/cpp/server/create_default_thread_pool.cc + src/cpp/server/dynamic_thread_pool.cc + src/cpp/server/external_connection_acceptor_impl.cc + src/cpp/server/health/default_health_check_service.cc + src/cpp/server/health/health_check_service.cc + src/cpp/server/health/health_check_service_server_builder_option.cc + src/cpp/server/insecure_server_credentials.cc + src/cpp/server/server_builder.cc + src/cpp/server/server_callback.cc + src/cpp/server/server_cc.cc + src/cpp/server/server_context.cc + src/cpp/server/server_credentials.cc + src/cpp/server/server_posix.cc + src/cpp/thread_manager/thread_manager.cc + src/cpp/util/byte_buffer_cc.cc + src/cpp/util/status.cc + src/cpp/util/string_ref.cc + src/cpp/util/time_cc.cc +) + +set_target_properties(grpc++_unsecure PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc++_unsecure PROPERTIES COMPILE_PDB_NAME "grpc++_unsecure" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_unsecure.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc++_unsecure + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpc++_unsecure + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_unsecure +) + +foreach(_hdr + include/grpc++/alarm.h + include/grpc++/channel.h + include/grpc++/client_context.h + include/grpc++/completion_queue.h + include/grpc++/create_channel.h + include/grpc++/create_channel_posix.h + include/grpc++/ext/health_check_service_server_builder_option.h + include/grpc++/generic/async_generic_service.h + include/grpc++/generic/generic_stub.h + include/grpc++/grpc++.h + include/grpc++/health_check_service_interface.h + include/grpc++/impl/call.h + include/grpc++/impl/channel_argument_option.h + include/grpc++/impl/client_unary_call.h + include/grpc++/impl/codegen/async_stream.h + include/grpc++/impl/codegen/async_unary_call.h + include/grpc++/impl/codegen/byte_buffer.h + include/grpc++/impl/codegen/call.h + include/grpc++/impl/codegen/call_hook.h + include/grpc++/impl/codegen/channel_interface.h + include/grpc++/impl/codegen/client_context.h + include/grpc++/impl/codegen/client_unary_call.h + include/grpc++/impl/codegen/completion_queue.h + include/grpc++/impl/codegen/completion_queue_tag.h + include/grpc++/impl/codegen/config.h + include/grpc++/impl/codegen/config_protobuf.h + include/grpc++/impl/codegen/core_codegen.h + include/grpc++/impl/codegen/core_codegen_interface.h + include/grpc++/impl/codegen/create_auth_context.h + include/grpc++/impl/codegen/grpc_library.h + include/grpc++/impl/codegen/metadata_map.h + include/grpc++/impl/codegen/method_handler_impl.h + include/grpc++/impl/codegen/proto_utils.h + include/grpc++/impl/codegen/rpc_method.h + include/grpc++/impl/codegen/rpc_service_method.h + include/grpc++/impl/codegen/security/auth_context.h + include/grpc++/impl/codegen/serialization_traits.h + include/grpc++/impl/codegen/server_context.h + include/grpc++/impl/codegen/server_interface.h + include/grpc++/impl/codegen/service_type.h + include/grpc++/impl/codegen/slice.h + include/grpc++/impl/codegen/status.h + include/grpc++/impl/codegen/status_code_enum.h + include/grpc++/impl/codegen/string_ref.h + include/grpc++/impl/codegen/stub_options.h + include/grpc++/impl/codegen/sync_stream.h + include/grpc++/impl/codegen/time.h + include/grpc++/impl/grpc_library.h + include/grpc++/impl/method_handler_impl.h + include/grpc++/impl/rpc_method.h + include/grpc++/impl/rpc_service_method.h + include/grpc++/impl/serialization_traits.h + include/grpc++/impl/server_builder_option.h + include/grpc++/impl/server_builder_plugin.h + include/grpc++/impl/server_initializer.h + include/grpc++/impl/service_type.h + include/grpc++/resource_quota.h + include/grpc++/security/auth_context.h + include/grpc++/security/auth_metadata_processor.h + include/grpc++/security/credentials.h + include/grpc++/security/server_credentials.h + include/grpc++/server.h + include/grpc++/server_builder.h + include/grpc++/server_context.h + include/grpc++/server_posix.h + include/grpc++/support/async_stream.h + include/grpc++/support/async_unary_call.h + include/grpc++/support/byte_buffer.h + include/grpc++/support/channel_arguments.h + include/grpc++/support/config.h + include/grpc++/support/slice.h + include/grpc++/support/status.h + include/grpc++/support/status_code_enum.h + include/grpc++/support/string_ref.h + include/grpc++/support/stub_options.h + include/grpc++/support/sync_stream.h + include/grpc++/support/time.h + include/grpcpp/alarm.h + include/grpcpp/channel.h + include/grpcpp/client_context.h + include/grpcpp/completion_queue.h + include/grpcpp/create_channel.h + include/grpcpp/create_channel_posix.h + include/grpcpp/ext/health_check_service_server_builder_option.h + include/grpcpp/generic/async_generic_service.h + include/grpcpp/generic/generic_stub.h + include/grpcpp/grpcpp.h + include/grpcpp/health_check_service_interface.h + include/grpcpp/impl/call.h + include/grpcpp/impl/channel_argument_option.h + include/grpcpp/impl/client_unary_call.h + include/grpcpp/impl/codegen/async_generic_service.h + include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/byte_buffer.h + include/grpcpp/impl/codegen/call.h + include/grpcpp/impl/codegen/call_hook.h + include/grpcpp/impl/codegen/call_op_set.h + include/grpcpp/impl/codegen/call_op_set_interface.h + include/grpcpp/impl/codegen/callback_common.h + include/grpcpp/impl/codegen/channel_interface.h + include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h + include/grpcpp/impl/codegen/client_unary_call.h + include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_tag.h + include/grpcpp/impl/codegen/config.h + include/grpcpp/impl/codegen/config_protobuf.h + include/grpcpp/impl/codegen/core_codegen.h + include/grpcpp/impl/codegen/core_codegen_interface.h + include/grpcpp/impl/codegen/create_auth_context.h + include/grpcpp/impl/codegen/delegating_channel.h + include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/intercepted_channel.h + include/grpcpp/impl/codegen/interceptor.h + include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h + include/grpcpp/impl/codegen/metadata_map.h + include/grpcpp/impl/codegen/method_handler.h + include/grpcpp/impl/codegen/method_handler_impl.h + include/grpcpp/impl/codegen/proto_buffer_reader.h + include/grpcpp/impl/codegen/proto_buffer_writer.h + include/grpcpp/impl/codegen/proto_utils.h + include/grpcpp/impl/codegen/rpc_method.h + include/grpcpp/impl/codegen/rpc_service_method.h + include/grpcpp/impl/codegen/security/auth_context.h + include/grpcpp/impl/codegen/serialization_traits.h + include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_handlers.h + include/grpcpp/impl/codegen/server_context.h + include/grpcpp/impl/codegen/server_interceptor.h + include/grpcpp/impl/codegen/server_interface.h + include/grpcpp/impl/codegen/service_type.h + include/grpcpp/impl/codegen/slice.h + include/grpcpp/impl/codegen/status.h + include/grpcpp/impl/codegen/status_code_enum.h + include/grpcpp/impl/codegen/string_ref.h + include/grpcpp/impl/codegen/stub_options.h + include/grpcpp/impl/codegen/sync.h + include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/time.h + include/grpcpp/impl/grpc_library.h + include/grpcpp/impl/method_handler_impl.h + include/grpcpp/impl/rpc_method.h + include/grpcpp/impl/rpc_service_method.h + include/grpcpp/impl/serialization_traits.h + include/grpcpp/impl/server_builder_option.h + include/grpcpp/impl/server_builder_plugin.h + include/grpcpp/impl/server_initializer.h + include/grpcpp/impl/service_type.h + include/grpcpp/resource_quota.h + include/grpcpp/security/auth_context.h + include/grpcpp/security/auth_metadata_processor.h + include/grpcpp/security/credentials.h + include/grpcpp/security/server_credentials.h + include/grpcpp/security/tls_certificate_provider.h + include/grpcpp/security/tls_credentials_options.h + include/grpcpp/security/sgx/sgx_ra_tls.h + include/grpcpp/security/sgx/sgx_ra_tls_options.h + include/grpcpp/server.h + include/grpcpp/server_builder.h + include/grpcpp/server_context.h + include/grpcpp/server_posix.h + include/grpcpp/support/async_stream.h + include/grpcpp/support/async_unary_call.h + include/grpcpp/support/byte_buffer.h + include/grpcpp/support/channel_arguments.h + include/grpcpp/support/client_callback.h + include/grpcpp/support/client_interceptor.h + include/grpcpp/support/config.h + include/grpcpp/support/interceptor.h + include/grpcpp/support/message_allocator.h + include/grpcpp/support/method_handler.h + include/grpcpp/support/proto_buffer_reader.h + include/grpcpp/support/proto_buffer_writer.h + include/grpcpp/support/server_callback.h + include/grpcpp/support/server_interceptor.h + include/grpcpp/support/slice.h + include/grpcpp/support/status.h + include/grpcpp/support/status_code_enum.h + include/grpcpp/support/string_ref.h + include/grpcpp/support/stub_options.h + include/grpcpp/support/sync_stream.h + include/grpcpp/support/time.h + include/grpcpp/support/validate_service_config.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if(gRPC_INSTALL) + install(TARGETS grpc++_unsecure EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + + +add_library(grpc_plugin_support + src/compiler/cpp_generator.cc + src/compiler/csharp_generator.cc + src/compiler/node_generator.cc + src/compiler/objective_c_generator.cc + src/compiler/php_generator.cc + src/compiler/python_generator.cc + src/compiler/ruby_generator.cc +) + +set_target_properties(grpc_plugin_support PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpc_plugin_support PROPERTIES COMPILE_PDB_NAME "grpc_plugin_support" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc_plugin_support.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpc_plugin_support + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpc_plugin_support + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} +) + +foreach(_hdr + include/grpc++/impl/codegen/config_protobuf.h + include/grpcpp/impl/codegen/config_protobuf.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if(gRPC_INSTALL) + install(TARGETS grpc_plugin_support EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + + +# grpcpp_channelz doesn't build with protobuf-lite +# See https://github.com/grpc/grpc/issues/19473 +if(gRPC_BUILD_CODEGEN AND NOT gRPC_USE_PROTO_LITE) +add_library(grpcpp_channelz + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.h + src/cpp/server/channelz/channelz_service.cc + src/cpp/server/channelz/channelz_service_plugin.cc +) + +set_target_properties(grpcpp_channelz PROPERTIES + VERSION ${gRPC_CPP_VERSION} + SOVERSION ${gRPC_CPP_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(grpcpp_channelz PROPERTIES COMPILE_PDB_NAME "grpcpp_channelz" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpcpp_channelz.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(grpcpp_channelz + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(grpcpp_channelz + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ +) + +foreach(_hdr + include/grpcpp/ext/channelz_service_plugin.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() +endif() + +if(gRPC_BUILD_CODEGEN) + +# grpcpp_channelz doesn't build with protobuf-lite, so no install required +# See https://github.com/grpc/grpc/issues/22826 +if(gRPC_INSTALL AND NOT gRPC_USE_PROTO_LITE) + install(TARGETS grpcpp_channelz EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +endif() + +add_library(upb + third_party/upb/upb/decode_fast.c + third_party/upb/upb/decode.c + third_party/upb/upb/def.c + third_party/upb/upb/encode.c + third_party/upb/upb/msg.c + third_party/upb/upb/reflection.c + third_party/upb/upb/table.c + third_party/upb/upb/text_encode.c + third_party/upb/upb/upb.c + src/core/ext/upb-generated/google/protobuf/descriptor.upb.c + src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c +) + +set_target_properties(upb PROPERTIES + VERSION ${gRPC_CORE_VERSION} + SOVERSION ${gRPC_CORE_SOVERSION} +) + +if(WIN32 AND MSVC) + set_target_properties(upb PROPERTIES COMPILE_PDB_NAME "upb" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if(gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/upb.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +target_include_directories(upb + PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) +target_link_libraries(upb + ${_gRPC_ALLTARGETS_LIBRARIES} +) + + + +if(gRPC_INSTALL) + install(TARGETS upb EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + + + +add_executable(check_epollexclusive + test/build/check_epollexclusive.c +) + +target_include_directories(check_epollexclusive + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(check_epollexclusive + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc + gpr +) + + + +add_executable(gen_hpack_tables + tools/codegen/core/gen_hpack_tables.cc +) + +target_include_directories(gen_hpack_tables + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(gen_hpack_tables + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc + gpr +) + + + +add_executable(gen_legal_metadata_characters + tools/codegen/core/gen_legal_metadata_characters.cc +) + +target_include_directories(gen_legal_metadata_characters + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(gen_legal_metadata_characters + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} +) + + + +add_executable(gen_percent_encoding_tables + tools/codegen/core/gen_percent_encoding_tables.cc +) + +target_include_directories(gen_percent_encoding_tables + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(gen_percent_encoding_tables + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} +) + + +if(gRPC_BUILD_TESTS) + +add_executable(algorithm_test + test/core/compression/algorithm_test.cc +) + +target_include_directories(algorithm_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(algorithm_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alloc_test + test/core/gpr/alloc_test.cc +) + +target_include_directories(alloc_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alloc_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alpn_test + test/core/transport/chttp2/alpn_test.cc +) + +target_include_directories(alpn_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alpn_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_counter_test + test/core/tsi/alts/crypt/gsec_test_util.cc + test/core/tsi/alts/frame_protector/alts_counter_test.cc +) + +target_include_directories(alts_counter_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_counter_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_crypt_test + test/core/tsi/alts/crypt/aes_gcm_test.cc + test/core/tsi/alts/crypt/gsec_test_util.cc +) + +target_include_directories(alts_crypt_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_crypt_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_crypter_test + test/core/tsi/alts/crypt/gsec_test_util.cc + test/core/tsi/alts/frame_protector/alts_crypter_test.cc +) + +target_include_directories(alts_crypter_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_crypter_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_frame_protector_test + test/core/tsi/alts/crypt/gsec_test_util.cc + test/core/tsi/alts/frame_protector/alts_frame_protector_test.cc + test/core/tsi/transport_security_test_lib.cc +) + +target_include_directories(alts_frame_protector_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_frame_protector_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_grpc_record_protocol_test + test/core/tsi/alts/crypt/gsec_test_util.cc + test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc +) + +target_include_directories(alts_grpc_record_protocol_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_grpc_record_protocol_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_handshaker_client_test + test/core/tsi/alts/handshaker/alts_handshaker_client_test.cc + test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc +) + +target_include_directories(alts_handshaker_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_handshaker_client_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_iovec_record_protocol_test + test/core/tsi/alts/crypt/gsec_test_util.cc + test/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol_test.cc +) + +target_include_directories(alts_iovec_record_protocol_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_iovec_record_protocol_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_security_connector_test + test/core/security/alts_security_connector_test.cc +) + +target_include_directories(alts_security_connector_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_security_connector_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_tsi_handshaker_test + test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc + test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc +) + +target_include_directories(alts_tsi_handshaker_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_tsi_handshaker_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_tsi_utils_test + test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc + test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc +) + +target_include_directories(alts_tsi_utils_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_tsi_utils_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_zero_copy_grpc_protector_test + test/core/tsi/alts/crypt/gsec_test_util.cc + test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc +) + +target_include_directories(alts_zero_copy_grpc_protector_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(alts_zero_copy_grpc_protector_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(arena_test + test/core/gpr/arena_test.cc +) + +target_include_directories(arena_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(arena_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(auth_context_test + test/core/security/auth_context_test.cc +) + +target_include_directories(auth_context_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(auth_context_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(avl_test + test/core/avl/avl_test.cc +) + +target_include_directories(avl_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(avl_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(b64_test + test/core/slice/b64_test.cc +) + +target_include_directories(b64_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(b64_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(bad_server_response_test + test/core/end2end/bad_server_response_test.cc + test/core/end2end/cq_verifier.cc +) + +target_include_directories(bad_server_response_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(bad_server_response_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(bad_ssl_alpn_test + test/core/bad_ssl/bad_ssl_test.cc + test/core/end2end/cq_verifier.cc + ) + + target_include_directories(bad_ssl_alpn_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(bad_ssl_alpn_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(bad_ssl_cert_test + test/core/bad_ssl/bad_ssl_test.cc + test/core/end2end/cq_verifier.cc + ) + + target_include_directories(bad_ssl_cert_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(bad_ssl_cert_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(bin_decoder_test + test/core/transport/chttp2/bin_decoder_test.cc +) + +target_include_directories(bin_decoder_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(bin_decoder_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(bin_encoder_test + test/core/transport/chttp2/bin_encoder_test.cc +) + +target_include_directories(bin_encoder_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(bin_encoder_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(buffer_list_test + test/core/iomgr/buffer_list_test.cc +) + +target_include_directories(buffer_list_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(buffer_list_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(channel_args_test + test/core/channel/channel_args_test.cc +) + +target_include_directories(channel_args_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(channel_args_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(channel_create_test + test/core/surface/channel_create_test.cc +) + +target_include_directories(channel_create_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(channel_create_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(channel_stack_builder_test + test/core/channel/channel_stack_builder_test.cc +) + +target_include_directories(channel_stack_builder_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(channel_stack_builder_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(channel_stack_test + test/core/channel/channel_stack_test.cc +) + +target_include_directories(channel_stack_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(channel_stack_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(check_gcp_environment_linux_test + test/core/security/check_gcp_environment_linux_test.cc +) + +target_include_directories(check_gcp_environment_linux_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(check_gcp_environment_linux_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(check_gcp_environment_windows_test + test/core/security/check_gcp_environment_windows_test.cc +) + +target_include_directories(check_gcp_environment_windows_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(check_gcp_environment_windows_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(client_ssl_test + test/core/handshake/client_ssl.cc + ) + + target_include_directories(client_ssl_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(client_ssl_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(cmdline_test + test/core/util/cmdline_test.cc +) + +target_include_directories(cmdline_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(cmdline_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(combiner_test + test/core/iomgr/combiner_test.cc + ) + + target_include_directories(combiner_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(combiner_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(completion_queue_threading_test + test/core/surface/completion_queue_threading_test.cc +) + +target_include_directories(completion_queue_threading_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(completion_queue_threading_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(compression_test + test/core/compression/compression_test.cc +) + +target_include_directories(compression_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(compression_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(concurrent_connectivity_test + test/core/surface/concurrent_connectivity_test.cc +) + +target_include_directories(concurrent_connectivity_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(concurrent_connectivity_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(connection_refused_test + test/core/end2end/connection_refused_test.cc + test/core/end2end/cq_verifier.cc +) + +target_include_directories(connection_refused_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(connection_refused_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(cpu_test + test/core/gpr/cpu_test.cc +) + +target_include_directories(cpu_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(cpu_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(dns_resolver_connectivity_using_ares_test + test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +) + +target_include_directories(dns_resolver_connectivity_using_ares_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(dns_resolver_connectivity_using_ares_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(dns_resolver_connectivity_using_native_test + test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +) + +target_include_directories(dns_resolver_connectivity_using_native_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(dns_resolver_connectivity_using_native_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(dns_resolver_cooldown_test + test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +) + +target_include_directories(dns_resolver_cooldown_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(dns_resolver_cooldown_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(dns_resolver_test + test/core/client_channel/resolvers/dns_resolver_test.cc +) + +target_include_directories(dns_resolver_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(dns_resolver_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(dualstack_socket_test + test/core/end2end/cq_verifier.cc + test/core/end2end/dualstack_socket_test.cc + ) + + target_include_directories(dualstack_socket_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(dualstack_socket_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(endpoint_pair_test + test/core/iomgr/endpoint_pair_test.cc + test/core/iomgr/endpoint_tests.cc +) + +target_include_directories(endpoint_pair_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(endpoint_pair_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(env_test + test/core/gpr/env_test.cc +) + +target_include_directories(env_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(env_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(error_test + test/core/iomgr/endpoint_tests.cc + test/core/iomgr/error_test.cc +) + +target_include_directories(error_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(error_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(ev_epollex_linux_test + test/core/iomgr/ev_epollex_linux_test.cc + ) + + target_include_directories(ev_epollex_linux_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(ev_epollex_linux_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(fake_resolver_test + test/core/client_channel/resolvers/fake_resolver_test.cc +) + +target_include_directories(fake_resolver_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(fake_resolver_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(fake_transport_security_test + test/core/tsi/fake_transport_security_test.cc + test/core/tsi/transport_security_test_lib.cc +) + +target_include_directories(fake_transport_security_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(fake_transport_security_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(fd_conservation_posix_test + test/core/iomgr/fd_conservation_posix_test.cc + ) + + target_include_directories(fd_conservation_posix_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(fd_conservation_posix_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(fd_posix_test + test/core/iomgr/fd_posix_test.cc + ) + + target_include_directories(fd_posix_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(fd_posix_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(fling_stream_test + test/core/end2end/data/client_certs.cc + test/core/end2end/data/server1_cert.cc + test/core/end2end/data/server1_key.cc + test/core/end2end/data/test_root_cert.cc + test/core/fling/fling_stream_test.cc + ) + + target_include_directories(fling_stream_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(fling_stream_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(fling_test + test/core/end2end/data/client_certs.cc + test/core/end2end/data/server1_cert.cc + test/core/end2end/data/server1_key.cc + test/core/end2end/data/test_root_cert.cc + test/core/fling/fling_test.cc + ) + + target_include_directories(fling_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(fling_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(fork_test + test/core/gprpp/fork_test.cc + ) + + target_include_directories(fork_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(fork_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(format_request_test + test/core/end2end/data/client_certs.cc + test/core/end2end/data/server1_cert.cc + test/core/end2end/data/server1_key.cc + test/core/end2end/data/test_root_cert.cc + test/core/http/format_request_test.cc +) + +target_include_directories(format_request_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(format_request_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(frame_handler_test + test/core/tsi/alts/crypt/gsec_test_util.cc + test/core/tsi/alts/frame_protector/frame_handler_test.cc +) + +target_include_directories(frame_handler_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(frame_handler_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(goaway_server_test + test/core/end2end/cq_verifier.cc + test/core/end2end/goaway_server_test.cc +) + +target_include_directories(goaway_server_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(goaway_server_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(grpc_alts_credentials_options_test + test/core/security/grpc_alts_credentials_options_test.cc +) + +target_include_directories(grpc_alts_credentials_options_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(grpc_alts_credentials_options_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(grpc_byte_buffer_reader_test + test/core/surface/byte_buffer_reader_test.cc +) + +target_include_directories(grpc_byte_buffer_reader_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(grpc_byte_buffer_reader_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(grpc_completion_queue_test + test/core/surface/completion_queue_test.cc +) + +target_include_directories(grpc_completion_queue_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(grpc_completion_queue_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(grpc_ipv6_loopback_available_test + test/core/iomgr/grpc_ipv6_loopback_available_test.cc +) + +target_include_directories(grpc_ipv6_loopback_available_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(grpc_ipv6_loopback_available_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(handshake_server_with_readahead_handshaker_test + test/core/handshake/readahead_handshaker_server_ssl.cc + test/core/handshake/server_ssl_common.cc + ) + + target_include_directories(handshake_server_with_readahead_handshaker_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(handshake_server_with_readahead_handshaker_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(handshake_verify_peer_options_test + test/core/handshake/verify_peer_options.cc + ) + + target_include_directories(handshake_verify_peer_options_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(handshake_verify_peer_options_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(histogram_test + test/core/util/histogram_test.cc +) + +target_include_directories(histogram_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(histogram_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(host_port_test + test/core/gprpp/host_port_test.cc +) + +target_include_directories(host_port_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(host_port_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(hpack_encoder_test + test/core/transport/chttp2/hpack_encoder_test.cc +) + +target_include_directories(hpack_encoder_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(hpack_encoder_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(hpack_parser_test + test/core/transport/chttp2/hpack_parser_test.cc +) + +target_include_directories(hpack_parser_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(hpack_parser_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(hpack_table_test + test/core/transport/chttp2/hpack_table_test.cc +) + +target_include_directories(hpack_table_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(hpack_table_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(httpcli_test + test/core/end2end/data/client_certs.cc + test/core/end2end/data/server1_cert.cc + test/core/end2end/data/server1_key.cc + test/core/end2end/data/test_root_cert.cc + test/core/http/httpcli_test.cc + ) + + target_include_directories(httpcli_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(httpcli_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(httpscli_test + test/core/end2end/data/client_certs.cc + test/core/end2end/data/server1_cert.cc + test/core/end2end/data/server1_key.cc + test/core/end2end/data/test_root_cert.cc + test/core/http/httpscli_test.cc + ) + + target_include_directories(httpscli_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(httpscli_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(inproc_callback_test + test/core/end2end/inproc_callback_test.cc +) + +target_include_directories(inproc_callback_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(inproc_callback_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(invalid_call_argument_test + test/core/end2end/cq_verifier.cc + test/core/end2end/invalid_call_argument_test.cc +) + +target_include_directories(invalid_call_argument_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(invalid_call_argument_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(json_token_test + test/core/security/json_token_test.cc +) + +target_include_directories(json_token_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(json_token_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(jwt_verifier_test + test/core/security/jwt_verifier_test.cc +) + +target_include_directories(jwt_verifier_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(jwt_verifier_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(lame_client_test + test/core/end2end/cq_verifier.cc + test/core/surface/lame_client_test.cc +) + +target_include_directories(lame_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(lame_client_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(load_file_test + test/core/iomgr/load_file_test.cc +) + +target_include_directories(load_file_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(load_file_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(manual_constructor_test + test/core/gprpp/manual_constructor_test.cc +) + +target_include_directories(manual_constructor_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(manual_constructor_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(message_compress_test + test/core/compression/message_compress_test.cc +) + +target_include_directories(message_compress_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(message_compress_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(metadata_test + test/core/transport/metadata_test.cc +) + +target_include_directories(metadata_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(metadata_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(minimal_stack_is_minimal_test + test/core/channel/minimal_stack_is_minimal_test.cc +) + +target_include_directories(minimal_stack_is_minimal_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(minimal_stack_is_minimal_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(mpmcqueue_test + test/core/iomgr/mpmcqueue_test.cc +) + +target_include_directories(mpmcqueue_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(mpmcqueue_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(mpscq_test + test/core/gprpp/mpscq_test.cc + ) + + target_include_directories(mpscq_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(mpscq_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(multiple_server_queues_test + test/core/end2end/cq_verifier.cc + test/core/end2end/multiple_server_queues_test.cc +) + +target_include_directories(multiple_server_queues_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(multiple_server_queues_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(murmur_hash_test + test/core/gpr/murmur_hash_test.cc +) + +target_include_directories(murmur_hash_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(murmur_hash_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(no_server_test + test/core/end2end/cq_verifier.cc + test/core/end2end/no_server_test.cc +) + +target_include_directories(no_server_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(no_server_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(num_external_connectivity_watchers_test + test/core/surface/num_external_connectivity_watchers_test.cc +) + +target_include_directories(num_external_connectivity_watchers_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(num_external_connectivity_watchers_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(parse_address_test + test/core/address_utils/parse_address_test.cc +) + +target_include_directories(parse_address_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(parse_address_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(parse_address_with_named_scope_id_test + test/core/address_utils/parse_address_with_named_scope_id_test.cc + ) + + target_include_directories(parse_address_with_named_scope_id_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(parse_address_with_named_scope_id_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(parser_test + test/core/end2end/data/client_certs.cc + test/core/end2end/data/server1_cert.cc + test/core/end2end/data/server1_key.cc + test/core/end2end/data/test_root_cert.cc + test/core/http/parser_test.cc +) + +target_include_directories(parser_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(parser_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(percent_encoding_test + test/core/slice/percent_encoding_test.cc +) + +target_include_directories(percent_encoding_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(percent_encoding_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(public_headers_must_be_c89 + test/core/surface/public_headers_must_be_c89.c +) + +target_include_directories(public_headers_must_be_c89 + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(public_headers_must_be_c89 + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(resolve_address_using_ares_resolver_posix_test + test/core/iomgr/resolve_address_posix_test.cc + ) + + target_include_directories(resolve_address_using_ares_resolver_posix_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(resolve_address_using_ares_resolver_posix_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(resolve_address_using_ares_resolver_test + test/core/iomgr/resolve_address_test.cc +) + +target_include_directories(resolve_address_using_ares_resolver_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(resolve_address_using_ares_resolver_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(resolve_address_using_native_resolver_posix_test + test/core/iomgr/resolve_address_posix_test.cc + ) + + target_include_directories(resolve_address_using_native_resolver_posix_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(resolve_address_using_native_resolver_posix_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(resolve_address_using_native_resolver_test + test/core/iomgr/resolve_address_test.cc +) + +target_include_directories(resolve_address_using_native_resolver_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(resolve_address_using_native_resolver_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(resource_quota_test + test/core/iomgr/resource_quota_test.cc +) + +target_include_directories(resource_quota_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(resource_quota_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(secure_channel_create_test + test/core/surface/secure_channel_create_test.cc +) + +target_include_directories(secure_channel_create_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(secure_channel_create_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(secure_endpoint_test + test/core/iomgr/endpoint_tests.cc + test/core/security/secure_endpoint_test.cc +) + +target_include_directories(secure_endpoint_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(secure_endpoint_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(security_connector_test + test/core/security/security_connector_test.cc +) + +target_include_directories(security_connector_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(security_connector_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(sequential_connectivity_test + test/core/surface/sequential_connectivity_test.cc +) + +target_include_directories(sequential_connectivity_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(sequential_connectivity_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(server_ssl_test + test/core/handshake/server_ssl.cc + test/core/handshake/server_ssl_common.cc + ) + + target_include_directories(server_ssl_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(server_ssl_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(server_test + test/core/surface/server_test.cc +) + +target_include_directories(server_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(server_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(slice_buffer_test + test/core/slice/slice_buffer_test.cc +) + +target_include_directories(slice_buffer_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(slice_buffer_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(slice_string_helpers_test + test/core/slice/slice_string_helpers_test.cc +) + +target_include_directories(slice_string_helpers_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(slice_string_helpers_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(sockaddr_resolver_test + test/core/client_channel/resolvers/sockaddr_resolver_test.cc +) + +target_include_directories(sockaddr_resolver_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(sockaddr_resolver_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(socket_utils_test + test/core/iomgr/socket_utils_test.cc + ) + + target_include_directories(socket_utils_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(socket_utils_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(spinlock_test + test/core/gpr/spinlock_test.cc +) + +target_include_directories(spinlock_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(spinlock_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(ssl_credentials_test + test/core/security/ssl_credentials_test.cc +) + +target_include_directories(ssl_credentials_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(ssl_credentials_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(ssl_transport_security_test + test/core/tsi/ssl_transport_security_test.cc + test/core/tsi/transport_security_test_lib.cc + ) + + target_include_directories(ssl_transport_security_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(ssl_transport_security_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(status_conversion_test + test/core/transport/status_conversion_test.cc +) + +target_include_directories(status_conversion_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(status_conversion_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(stream_compression_test + test/core/compression/stream_compression_test.cc +) + +target_include_directories(stream_compression_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(stream_compression_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(stream_map_test + test/core/transport/chttp2/stream_map_test.cc +) + +target_include_directories(stream_map_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(stream_map_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(stream_owned_slice_test + test/core/transport/stream_owned_slice_test.cc +) + +target_include_directories(stream_owned_slice_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(stream_owned_slice_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(string_test + test/core/gpr/string_test.cc +) + +target_include_directories(string_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(string_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(sync_test + test/core/gpr/sync_test.cc +) + +target_include_directories(sync_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(sync_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(tcp_client_posix_test + test/core/iomgr/tcp_client_posix_test.cc + ) + + target_include_directories(tcp_client_posix_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(tcp_client_posix_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(tcp_posix_test + test/core/iomgr/endpoint_tests.cc + test/core/iomgr/tcp_posix_test.cc + ) + + target_include_directories(tcp_posix_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(tcp_posix_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(tcp_server_posix_test + test/core/iomgr/tcp_server_posix_test.cc + ) + + target_include_directories(tcp_server_posix_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(tcp_server_posix_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(test_core_gpr_time_test + test/core/gpr/time_test.cc +) + +target_include_directories(test_core_gpr_time_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(test_core_gpr_time_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(test_core_security_credentials_test + test/core/security/credentials_test.cc +) + +target_include_directories(test_core_security_credentials_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(test_core_security_credentials_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(test_core_slice_slice_test + test/core/slice/slice_test.cc +) + +target_include_directories(test_core_slice_slice_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(test_core_slice_slice_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(thd_test + test/core/gprpp/thd_test.cc +) + +target_include_directories(thd_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(thd_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(threadpool_test + test/core/iomgr/threadpool_test.cc +) + +target_include_directories(threadpool_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(threadpool_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(time_averaged_stats_test + test/core/iomgr/time_averaged_stats_test.cc +) + +target_include_directories(time_averaged_stats_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(time_averaged_stats_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(timeout_encoding_test + test/core/transport/timeout_encoding_test.cc +) + +target_include_directories(timeout_encoding_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(timeout_encoding_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(timer_heap_test + test/core/iomgr/timer_heap_test.cc +) + +target_include_directories(timer_heap_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(timer_heap_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(timer_list_test + test/core/iomgr/timer_list_test.cc +) + +target_include_directories(timer_list_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(timer_list_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(tls_test + test/core/gpr/tls_test.cc +) + +target_include_directories(tls_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(tls_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(transport_security_common_api_test + test/core/tsi/alts/handshaker/transport_security_common_api_test.cc +) + +target_include_directories(transport_security_common_api_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(transport_security_common_api_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(transport_security_test + test/core/tsi/transport_security_test.cc +) + +target_include_directories(transport_security_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(transport_security_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(udp_server_test + test/core/iomgr/udp_server_test.cc + ) + + target_include_directories(udp_server_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ) + + target_link_libraries(udp_server_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(useful_test + test/core/gpr/useful_test.cc +) + +target_include_directories(useful_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(useful_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(varint_test + test/core/transport/chttp2/varint_test.cc +) + +target_include_directories(varint_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} +) + +target_link_libraries(varint_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(address_sorting_test + test/cpp/naming/address_sorting_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(address_sorting_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(address_sorting_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config + grpc++_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(address_sorting_test_unsecure + test/cpp/naming/address_sorting_test.cc + test/cpp/util/byte_buffer_proto_helper.cc + test/cpp/util/string_ref_helper.cc + test/cpp/util/subprocess.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(address_sorting_test_unsecure + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(address_sorting_test_unsecure + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_unsecure + grpc_test_util_unsecure + grpc++_test_config + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(admin_services_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.h + src/cpp/server/admin/admin_services.cc + src/cpp/server/csds/csds.cc + test/cpp/end2end/admin_services_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(admin_services_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(admin_services_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_reflection + grpcpp_channelz + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(alarm_test + test/cpp/common/alarm_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(alarm_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(alarm_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_unsecure + grpc_test_util_unsecure + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(alts_concurrent_connectivity_test + ${_gRPC_PROTO_GENS_DIR}/test/core/tsi/alts/fake_handshaker/handshaker.pb.cc + ${_gRPC_PROTO_GENS_DIR}/test/core/tsi/alts/fake_handshaker/handshaker.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/test/core/tsi/alts/fake_handshaker/handshaker.pb.h + ${_gRPC_PROTO_GENS_DIR}/test/core/tsi/alts/fake_handshaker/handshaker.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/test/core/tsi/alts/fake_handshaker/transport_security_common.pb.cc + ${_gRPC_PROTO_GENS_DIR}/test/core/tsi/alts/fake_handshaker/transport_security_common.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/test/core/tsi/alts/fake_handshaker/transport_security_common.pb.h + ${_gRPC_PROTO_GENS_DIR}/test/core/tsi/alts/fake_handshaker/transport_security_common.grpc.pb.h + test/core/end2end/cq_verifier.cc + test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc + test/core/tsi/alts/handshaker/alts_concurrent_connectivity_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(alts_concurrent_connectivity_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(alts_concurrent_connectivity_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_util_test + test/cpp/common/alts_util_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(alts_util_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(alts_util_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_alts + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(async_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/async_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(async_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(async_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(auth_property_iterator_test + test/cpp/common/auth_property_iterator_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(auth_property_iterator_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(auth_property_iterator_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(authorization_matchers_test + src/core/lib/security/authorization/evaluate_args.cc + src/core/lib/security/authorization/grpc_authorization_engine.cc + src/core/lib/security/authorization/matchers.cc + src/core/lib/security/authorization/rbac_policy.cc + test/core/security/authorization_matchers_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(authorization_matchers_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(authorization_matchers_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(aws_request_signer_test + test/core/security/aws_request_signer_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(aws_request_signer_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(aws_request_signer_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(backoff_test + test/core/backoff/backoff_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(backoff_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(backoff_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(bad_streaming_id_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/bad_streaming_id.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(bad_streaming_id_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(bad_streaming_id_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(badreq_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/badreq.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(badreq_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(badreq_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(bdp_estimator_test + test/core/transport/bdp_estimator_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bdp_estimator_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bdp_estimator_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_alarm + test/cpp/microbenchmarks/bm_alarm.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_alarm + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_alarm + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_arena + test/cpp/microbenchmarks/bm_arena.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_arena + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_arena + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_byte_buffer + test/cpp/microbenchmarks/bm_byte_buffer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_byte_buffer + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_byte_buffer + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_call_create + test/cpp/microbenchmarks/bm_call_create.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_call_create + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_call_create + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_callback_streaming_ping_pong + test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc + test/cpp/microbenchmarks/callback_test_service.cc + test/cpp/util/byte_buffer_proto_helper.cc + test/cpp/util/string_ref_helper.cc + test/cpp/util/subprocess.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_callback_streaming_ping_pong + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_callback_streaming_ping_pong + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_callback_unary_ping_pong + test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc + test/cpp/microbenchmarks/callback_test_service.cc + test/cpp/util/byte_buffer_proto_helper.cc + test/cpp/util/string_ref_helper.cc + test/cpp/util/subprocess.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_callback_unary_ping_pong + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_callback_unary_ping_pong + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_channel + test/cpp/microbenchmarks/bm_channel.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_channel + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_channel + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_chttp2_hpack + test/cpp/microbenchmarks/bm_chttp2_hpack.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_chttp2_hpack + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_chttp2_hpack + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_chttp2_transport + test/cpp/microbenchmarks/bm_chttp2_transport.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_chttp2_transport + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_chttp2_transport + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_closure + test/cpp/microbenchmarks/bm_closure.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_closure + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_closure + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_cq + test/cpp/microbenchmarks/bm_cq.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_cq + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_cq + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_cq_multiple_threads + test/cpp/microbenchmarks/bm_cq_multiple_threads.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_cq_multiple_threads + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_cq_multiple_threads + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_error + test/cpp/microbenchmarks/bm_error.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_error + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_error + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_fullstack_streaming_ping_pong + test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_fullstack_streaming_ping_pong + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_fullstack_streaming_ping_pong + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_fullstack_streaming_pump + test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_fullstack_streaming_pump + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_fullstack_streaming_pump + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_fullstack_trickle + test/cpp/microbenchmarks/bm_fullstack_trickle.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_fullstack_trickle + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_fullstack_trickle + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_fullstack_unary_ping_pong + test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_fullstack_unary_ping_pong + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_fullstack_unary_ping_pong + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_metadata + test/cpp/microbenchmarks/bm_metadata.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_metadata + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_metadata + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_pollset + test/cpp/microbenchmarks/bm_pollset.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_pollset + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_pollset + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_threadpool + test/cpp/microbenchmarks/bm_threadpool.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_threadpool + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_threadpool + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) + + add_executable(bm_timer + test/cpp/microbenchmarks/bm_timer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(bm_timer + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(bm_timer + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + benchmark_helpers + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(byte_buffer_test + test/cpp/util/byte_buffer_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(byte_buffer_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(byte_buffer_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(byte_stream_test + test/core/transport/byte_stream_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(byte_stream_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(byte_stream_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(cancel_ares_query_test + test/core/end2end/cq_verifier.cc + test/cpp/naming/cancel_ares_query_test.cc + test/cpp/naming/dns_test_util.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(cancel_ares_query_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(cancel_ares_query_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(cel_authorization_engine_test + src/core/lib/security/authorization/cel_authorization_engine.cc + src/core/lib/security/authorization/evaluate_args.cc + src/core/lib/security/authorization/grpc_authorization_engine.cc + src/core/lib/security/authorization/matchers.cc + src/core/lib/security/authorization/rbac_policy.cc + test/core/security/cel_authorization_engine_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(cel_authorization_engine_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(cel_authorization_engine_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flat_hash_set + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(certificate_provider_registry_test + test/core/client_channel/certificate_provider_registry_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(certificate_provider_registry_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(certificate_provider_registry_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(certificate_provider_store_test + test/core/xds/certificate_provider_store_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(certificate_provider_store_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(certificate_provider_store_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(cfstream_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/cfstream_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(cfstream_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(cfstream_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(channel_arguments_test + test/cpp/common/channel_arguments_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(channel_arguments_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(channel_arguments_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(channel_filter_test + test/cpp/common/channel_filter_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(channel_filter_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(channel_filter_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(channel_trace_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.h + test/core/channel/channel_trace_test.cc + test/cpp/util/channel_trace_proto_helper.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(channel_trace_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(channel_trace_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(channelz_registry_test + test/core/channel/channelz_registry_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(channelz_registry_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(channelz_registry_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(channelz_service_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/channelz_service_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(channelz_service_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(channelz_service_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpcpp_channelz + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(channelz_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.h + test/core/channel/channelz_test.cc + test/cpp/util/channel_trace_proto_helper.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(channelz_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(channelz_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(cli_call_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/util/cli_call.cc + test/cpp/util/cli_call_test.cc + test/cpp/util/cli_credentials.cc + test/cpp/util/grpc_tool.cc + test/cpp/util/proto_file_parser.cc + test/cpp/util/proto_reflection_descriptor_database.cc + test/cpp/util/service_describer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(cli_call_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(cli_call_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(client_callback_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/client_callback_end2end_test.cc + test/cpp/end2end/interceptors_util.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(client_callback_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(client_callback_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(client_channel_stress_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/client/client_channel_stress_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(client_channel_stress_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(client_channel_stress_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(client_interceptors_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/client_interceptors_end2end_test.cc + test/cpp/end2end/interceptors_util.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(client_interceptors_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(client_interceptors_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(client_lb_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/orca_load_report_for_test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/orca_load_report_for_test.grpc.pb.h + test/core/util/test_lb_policies.cc + test/cpp/end2end/client_lb_end2end_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(client_lb_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(client_lb_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(codegen_test_full + test/cpp/codegen/codegen_test_full.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(codegen_test_full + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(codegen_test_full + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(codegen_test_minimal + test/cpp/codegen/codegen_test_minimal.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(codegen_test_minimal + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(codegen_test_minimal + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(connection_prefix_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/connection_prefix.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(connection_prefix_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(connection_prefix_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(connectivity_state_test + test/core/transport/connectivity_state_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(connectivity_state_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(connectivity_state_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(context_allocator_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/context_allocator_end2end_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(context_allocator_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(context_allocator_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(context_list_test + test/core/transport/chttp2/context_list_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(context_list_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(context_list_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(delegating_channel_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/delegating_channel_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(delegating_channel_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(delegating_channel_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(destroy_grpclb_channel_with_active_connect_stress_test + test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(destroy_grpclb_channel_with_active_connect_stress_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(destroy_grpclb_channel_with_active_connect_stress_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(dual_ref_counted_test + test/core/gprpp/dual_ref_counted_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(dual_ref_counted_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(dual_ref_counted_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(duplicate_header_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/duplicate_header.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(duplicate_header_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(duplicate_header_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/end2end_test.cc + test/cpp/end2end/interceptors_util.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(error_details_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + test/cpp/util/error_details_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(error_details_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(error_details_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_error_details + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(error_utils_test + test/core/transport/error_utils_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(error_utils_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(error_utils_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(evaluate_args_test + src/core/lib/security/authorization/evaluate_args.cc + src/core/lib/security/authorization/grpc_authorization_engine.cc + src/core/lib/security/authorization/matchers.cc + src/core/lib/security/authorization/rbac_policy.cc + test/core/security/evaluate_args_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(evaluate_args_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(evaluate_args_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(examine_stack_test + test/core/gprpp/examine_stack_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(examine_stack_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(examine_stack_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(exception_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/exception_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(exception_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(exception_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(file_watcher_certificate_provider_factory_test + test/core/xds/file_watcher_certificate_provider_factory_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(file_watcher_certificate_provider_factory_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(file_watcher_certificate_provider_factory_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(filter_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/filter_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(filter_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(filter_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(flaky_network_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/flaky_network_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(flaky_network_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(flaky_network_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(generic_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/generic_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(generic_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(generic_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(global_config_env_test + test/core/gprpp/global_config_env_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(global_config_env_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(global_config_env_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(global_config_test + test/core/gprpp/global_config_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(global_config_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(global_config_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(google_mesh_ca_certificate_provider_factory_test + src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc + test/core/xds/google_mesh_ca_certificate_provider_factory_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(google_mesh_ca_certificate_provider_factory_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(google_mesh_ca_certificate_provider_factory_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(grpc_authorization_engine_test + src/core/lib/security/authorization/evaluate_args.cc + src/core/lib/security/authorization/grpc_authorization_engine.cc + src/core/lib/security/authorization/matchers.cc + src/core/lib/security/authorization/rbac_policy.cc + test/core/security/grpc_authorization_engine_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(grpc_authorization_engine_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_authorization_engine_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(grpc_cli + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h + test/cpp/util/cli_call.cc + test/cpp/util/cli_credentials.cc + test/cpp/util/grpc_cli.cc + test/cpp/util/grpc_tool.cc + test/cpp/util/proto_file_parser.cc + test/cpp/util/proto_reflection_descriptor_database.cc + test/cpp/util/service_describer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(grpc_cli + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_cli + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc++ + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_CODEGEN AND gRPC_BUILD_GRPC_CPP_PLUGIN) + +add_executable(grpc_cpp_plugin + src/compiler/cpp_plugin.cc +) + +target_include_directories(grpc_cpp_plugin + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_cpp_plugin + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_plugin_support +) + + + +if(gRPC_INSTALL) + install(TARGETS grpc_cpp_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +endif() +if(gRPC_BUILD_CODEGEN AND gRPC_BUILD_GRPC_CSHARP_PLUGIN) + +add_executable(grpc_csharp_plugin + src/compiler/csharp_plugin.cc +) + +target_include_directories(grpc_csharp_plugin + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_csharp_plugin + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_plugin_support +) + + + +if(gRPC_INSTALL) + install(TARGETS grpc_csharp_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +endif() +if(gRPC_BUILD_CODEGEN AND gRPC_BUILD_GRPC_NODE_PLUGIN) + +add_executable(grpc_node_plugin + src/compiler/node_plugin.cc +) + +target_include_directories(grpc_node_plugin + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_node_plugin + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_plugin_support +) + + + +if(gRPC_INSTALL) + install(TARGETS grpc_node_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +endif() +if(gRPC_BUILD_CODEGEN AND gRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN) + +add_executable(grpc_objective_c_plugin + src/compiler/objective_c_plugin.cc +) + +target_include_directories(grpc_objective_c_plugin + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_objective_c_plugin + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_plugin_support +) + + + +if(gRPC_INSTALL) + install(TARGETS grpc_objective_c_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +endif() +if(gRPC_BUILD_CODEGEN AND gRPC_BUILD_GRPC_PHP_PLUGIN) + +add_executable(grpc_php_plugin + src/compiler/php_plugin.cc +) + +target_include_directories(grpc_php_plugin + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_php_plugin + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_plugin_support +) + + + +if(gRPC_INSTALL) + install(TARGETS grpc_php_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +endif() +if(gRPC_BUILD_CODEGEN AND gRPC_BUILD_GRPC_PYTHON_PLUGIN) + +add_executable(grpc_python_plugin + src/compiler/python_plugin.cc +) + +target_include_directories(grpc_python_plugin + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_python_plugin + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_plugin_support +) + + + +if(gRPC_INSTALL) + install(TARGETS grpc_python_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +endif() +if(gRPC_BUILD_CODEGEN AND gRPC_BUILD_GRPC_RUBY_PLUGIN) + +add_executable(grpc_ruby_plugin + src/compiler/ruby_plugin.cc +) + +target_include_directories(grpc_ruby_plugin + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_ruby_plugin + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_plugin_support +) + + + +if(gRPC_INSTALL) + install(TARGETS grpc_ruby_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} + LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR} + ) +endif() + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(grpc_tls_certificate_distributor_test + test/core/security/grpc_tls_certificate_distributor_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(grpc_tls_certificate_distributor_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_tls_certificate_distributor_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(grpc_tls_certificate_provider_test + test/core/security/grpc_tls_certificate_provider_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(grpc_tls_certificate_provider_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_tls_certificate_provider_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(grpc_tls_credentials_options_test + test/core/security/grpc_tls_credentials_options_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(grpc_tls_credentials_options_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_tls_credentials_options_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(grpc_tool_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/util/cli_call.cc + test/cpp/util/cli_credentials.cc + test/cpp/util/grpc_tool.cc + test/cpp/util/grpc_tool_test.cc + test/cpp/util/proto_file_parser.cc + test/cpp/util/proto_reflection_descriptor_database.cc + test/cpp/util/service_describer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(grpc_tool_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(grpc_tool_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_reflection + grpc++_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(grpclb_api_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h + test/cpp/grpclb/grpclb_api_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(grpclb_api_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpclb_api_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(grpclb_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/grpclb_end2end_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(grpclb_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(grpclb_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(h2_ssl_session_reuse_test + test/core/end2end/h2_ssl_session_reuse_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(h2_ssl_session_reuse_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(h2_ssl_session_reuse_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(head_of_line_blocking_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/head_of_line_blocking.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(head_of_line_blocking_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(head_of_line_blocking_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(headers_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/headers.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(headers_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(headers_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(health_service_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/health_service_end2end_test.cc + test/cpp/end2end/test_health_check_service_impl.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(health_service_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(health_service_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(http2_client + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h + test/cpp/interop/http2_client.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(http2_client + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(http2_client + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(hybrid_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/hybrid_end2end_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(hybrid_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(hybrid_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(init_test + test/core/surface/init_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(init_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(init_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(initial_settings_frame_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/initial_settings_frame.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(initial_settings_frame_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(initial_settings_frame_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(insecure_security_connector_test + test/core/security/insecure_security_connector_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(insecure_security_connector_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(insecure_security_connector_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(interop_client + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h + test/core/security/oauth2_utils.cc + test/cpp/interop/client.cc + test/cpp/interop/client_helper.cc + test/cpp/interop/interop_client.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(interop_client + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(interop_client + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(interop_server + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h + test/cpp/interop/interop_server.cc + test/cpp/interop/interop_server_bootstrap.cc + test/cpp/interop/server_helper.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(interop_server + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(interop_server + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(interop_test + test/cpp/interop/interop_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(interop_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(interop_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config + grpc++_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(json_test + test/core/json/json_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(json_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(json_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(large_metadata_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/large_metadata.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(large_metadata_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(large_metadata_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(lb_get_cpu_stats_test + src/cpp/server/load_reporter/get_cpu_stats_linux.cc + src/cpp/server/load_reporter/get_cpu_stats_macos.cc + src/cpp/server/load_reporter/get_cpu_stats_unsupported.cc + src/cpp/server/load_reporter/get_cpu_stats_windows.cc + test/cpp/server/load_reporter/get_cpu_stats_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(lb_get_cpu_stats_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(lb_get_cpu_stats_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(lb_load_data_store_test + src/cpp/server/load_reporter/load_data_store.cc + test/cpp/server/load_reporter/load_data_store_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(lb_load_data_store_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(lb_load_data_store_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(linux_system_roots_test + test/core/security/linux_system_roots_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(linux_system_roots_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(linux_system_roots_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(log_test + test/core/gpr/log_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(log_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(log_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(matchers_test + test/core/security/matchers_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(matchers_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(matchers_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(message_allocator_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/message_allocator_end2end_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(message_allocator_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(message_allocator_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(mock_stream_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/test/mock_stream_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(mock_stream_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(mock_stream_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(mock_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/mock_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(mock_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(mock_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(nonblocking_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/nonblocking_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(nonblocking_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(nonblocking_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(noop-benchmark + test/cpp/microbenchmarks/noop-benchmark.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(noop-benchmark + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(noop-benchmark + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + ${_gRPC_BENCHMARK_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(orphanable_test + test/core/gprpp/orphanable_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(orphanable_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(orphanable_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(out_of_bounds_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/out_of_bounds.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(out_of_bounds_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(out_of_bounds_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(pid_controller_test + test/core/transport/pid_controller_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(pid_controller_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(pid_controller_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(port_sharing_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/port_sharing_end2end_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(port_sharing_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(port_sharing_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(proto_server_reflection_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/proto_server_reflection_test.cc + test/cpp/end2end/test_service_impl.cc + test/cpp/util/proto_reflection_descriptor_database.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(proto_server_reflection_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(proto_server_reflection_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_reflection + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(proto_utils_test + test/cpp/codegen/proto_utils_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(proto_utils_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(proto_utils_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(qps_json_driver + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/core/stats.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/core/stats.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/core/stats.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/core/stats.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.h + src/cpp/util/core_stats.cc + test/cpp/qps/benchmark_config.cc + test/cpp/qps/client_async.cc + test/cpp/qps/client_callback.cc + test/cpp/qps/client_sync.cc + test/cpp/qps/driver.cc + test/cpp/qps/parse_json.cc + test/cpp/qps/qps_json_driver.cc + test/cpp/qps/qps_server_builder.cc + test/cpp/qps/qps_worker.cc + test/cpp/qps/report.cc + test/cpp/qps/server_async.cc + test/cpp/qps/server_callback.cc + test/cpp/qps/server_sync.cc + test/cpp/qps/usage_timer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(qps_json_driver + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(qps_json_driver + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(qps_worker + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/core/stats.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/core/stats.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/core/stats.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/core/stats.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/benchmark_service.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/control.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/payloads.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/stats.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/worker_service.grpc.pb.h + src/cpp/util/core_stats.cc + test/cpp/qps/client_async.cc + test/cpp/qps/client_callback.cc + test/cpp/qps/client_sync.cc + test/cpp/qps/qps_server_builder.cc + test/cpp/qps/qps_worker.cc + test/cpp/qps/server_async.cc + test/cpp/qps/server_callback.cc + test/cpp/qps/server_sync.cc + test/cpp/qps/usage_timer.cc + test/cpp/qps/worker.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(qps_worker + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(qps_worker + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(raw_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/raw_end2end_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(raw_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(raw_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(rbac_translator_test + src/core/lib/security/authorization/evaluate_args.cc + src/core/lib/security/authorization/grpc_authorization_engine.cc + src/core/lib/security/authorization/matchers.cc + src/core/lib/security/authorization/rbac_policy.cc + src/core/lib/security/authorization/rbac_translator.cc + test/core/security/rbac_translator_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(rbac_translator_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(rbac_translator_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(ref_counted_ptr_test + test/core/gprpp/ref_counted_ptr_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(ref_counted_ptr_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(ref_counted_ptr_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(ref_counted_test + test/core/gprpp/ref_counted_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(ref_counted_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(ref_counted_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(remove_stream_from_stalled_lists_test + test/core/transport/chttp2/remove_stream_from_stalled_lists_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(remove_stream_from_stalled_lists_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(remove_stream_from_stalled_lists_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(retry_throttle_test + test/core/client_channel/retry_throttle_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(retry_throttle_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(retry_throttle_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(secure_auth_context_test + test/cpp/common/secure_auth_context_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(secure_auth_context_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(secure_auth_context_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(server_builder_plugin_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/server_builder_plugin_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(server_builder_plugin_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(server_builder_plugin_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(server_builder_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/server/server_builder_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(server_builder_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(server_builder_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_unsecure + grpc_test_util_unsecure + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(server_builder_with_socket_mutator_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/server/server_builder_with_socket_mutator_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(server_builder_with_socket_mutator_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(server_builder_with_socket_mutator_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_unsecure + grpc_test_util_unsecure + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(server_chttp2_test + test/core/surface/server_chttp2_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(server_chttp2_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(server_chttp2_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(server_context_test_spouse_test + test/cpp/test/server_context_test_spouse_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(server_context_test_spouse_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(server_context_test_spouse_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(server_early_return_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/server_early_return_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(server_early_return_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(server_early_return_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(server_interceptors_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/interceptors_util.cc + test/cpp/end2end/server_interceptors_end2end_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(server_interceptors_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(server_interceptors_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(server_registered_method_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/server_registered_method.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(server_registered_method_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(server_registered_method_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(server_request_call_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/server/server_request_call_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(server_request_call_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(server_request_call_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_unsecure + grpc_test_util_unsecure + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(service_config_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/service_config_end2end_test.cc + test/cpp/end2end/test_service_impl.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(service_config_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(service_config_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(service_config_test + test/core/client_channel/service_config_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(service_config_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(service_config_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(settings_timeout_test + test/core/transport/chttp2/settings_timeout_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(settings_timeout_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(settings_timeout_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(shutdown_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/shutdown_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(shutdown_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(shutdown_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(simple_request_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/simple_request.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(simple_request_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(simple_request_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(sockaddr_utils_test + test/core/address_utils/sockaddr_utils_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(sockaddr_utils_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(sockaddr_utils_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(stack_tracer_test + test/core/util/stack_tracer_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(stack_tracer_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(stack_tracer_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(stat_test + test/core/gprpp/stat_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(stat_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(stat_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(static_metadata_test + test/core/transport/static_metadata_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(static_metadata_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(static_metadata_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(stats_test + test/core/debug/stats_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(stats_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(stats_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(status_helper_test + test/core/gprpp/status_helper_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(status_helper_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(status_helper_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(status_metadata_test + test/core/transport/status_metadata_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(status_metadata_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(status_metadata_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(status_util_test + test/core/channel/status_util_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(status_util_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(status_util_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(stranded_event_test + test/core/end2end/cq_verifier.cc + test/core/iomgr/stranded_event_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(stranded_event_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(stranded_event_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(streaming_throughput_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/streaming_throughput_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(streaming_throughput_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(streaming_throughput_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(string_ref_test + test/cpp/util/string_ref_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(string_ref_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(string_ref_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(test_cpp_client_credentials_test + test/cpp/client/credentials_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(test_cpp_client_credentials_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(test_cpp_client_credentials_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(test_cpp_server_credentials_test + test/cpp/server/credentials_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(test_cpp_server_credentials_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(test_cpp_server_credentials_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(test_cpp_util_slice_test + test/cpp/util/slice_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(test_cpp_util_slice_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(test_cpp_util_slice_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(test_cpp_util_time_test + test/cpp/util/time_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(test_cpp_util_time_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(test_cpp_util_time_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(thread_manager_test + test/cpp/thread_manager/thread_manager_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(thread_manager_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(thread_manager_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(thread_stress_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/thread_stress_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(thread_stress_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(thread_stress_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(time_jump_test + test/cpp/common/time_jump_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(time_jump_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(time_jump_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(time_util_test + test/core/gprpp/time_util_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(time_util_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(time_util_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(timer_test + test/cpp/common/timer_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(timer_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(timer_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++ + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(tls_security_connector_test + test/core/security/tls_security_connector_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(tls_security_connector_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(tls_security_connector_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(too_many_pings_test + test/core/end2end/cq_verifier.cc + test/core/transport/chttp2/too_many_pings_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(too_many_pings_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(too_many_pings_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(unknown_frame_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/unknown_frame.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(unknown_frame_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(unknown_frame_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(uri_parser_test + test/core/uri/uri_parser_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(uri_parser_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(uri_parser_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(window_overflow_bad_client_test + test/core/bad_client/bad_client.cc + test/core/bad_client/tests/window_overflow.cc + test/core/end2end/cq_verifier.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(window_overflow_bad_client_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(window_overflow_bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(work_serializer_test + test/core/iomgr/work_serializer_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(work_serializer_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(work_serializer_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(writes_per_rpc_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/core/util/cmdline.cc + test/core/util/fuzzer_util.cc + test/core/util/grpc_profiler.cc + test/core/util/histogram.cc + test/core/util/memory_counters.cc + test/core/util/mock_endpoint.cc + test/core/util/parse_hexstring.cc + test/core/util/passthru_endpoint.cc + test/core/util/port.cc + test/core/util/port_isolated_runtime_environment.cc + test/core/util/port_server_client.cc + test/core/util/reconnect_server.cc + test/core/util/resolve_localhost_ip46.cc + test/core/util/slice_splitter.cc + test/core/util/stack_tracer.cc + test/core/util/subprocess_posix.cc + test/core/util/subprocess_windows.cc + test/core/util/test_config.cc + test/core/util/test_tcp_server.cc + test/core/util/tracer_util.cc + test/core/util/trickle_endpoint.cc + test/cpp/performance/writes_per_rpc_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(writes_per_rpc_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(writes_per_rpc_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::failure_signal_handler + absl::stacktrace + absl::symbolize + grpc++ + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(xds_bootstrap_test + test/core/xds/xds_bootstrap_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(xds_bootstrap_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(xds_bootstrap_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(xds_certificate_provider_test + test/core/xds/xds_certificate_provider_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(xds_certificate_provider_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(xds_certificate_provider_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(xds_credentials_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/test_service_impl.cc + test/cpp/end2end/xds_credentials_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(xds_credentials_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(xds_credentials_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(xds_credentials_test + test/core/security/xds_credentials_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(xds_credentials_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(xds_credentials_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util +) + + +endif() +if(gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + + add_executable(xds_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/ads_for_test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/ads_for_test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/ads_for_test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/ads_for_test.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/cds_for_test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/cds_for_test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/cds_for_test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/cds_for_test.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/eds_for_test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/eds_for_test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lds_rds_for_test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lds_rds_for_test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lds_rds_for_test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lds_rds_for_test.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lrs_for_test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lrs_for_test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ads.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ads.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ads.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ads.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/aggregate_cluster.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/aggregate_cluster.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/aggregate_cluster.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/aggregate_cluster.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/discovery.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/discovery.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/listener.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/listener.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/listener.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/listener.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/load_report.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/load_report.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/lrs.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/lrs.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/lrs.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/lrs.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/protocol.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/range.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/range.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/range.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/range.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/regex.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.grpc.pb.h + src/cpp/server/csds/csds.cc + test/cpp/end2end/test_service_impl.cc + test/cpp/end2end/xds_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc + ) + + target_include_directories(xds_end2end_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} + ) + + target_link_libraries(xds_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + ) + + +endif() +endif() +if(gRPC_BUILD_TESTS) + +add_executable(xds_interop_client + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.h + src/cpp/server/admin/admin_services.cc + src/cpp/server/csds/csds.cc + test/cpp/interop/xds_interop_client.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(xds_interop_client + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(xds_interop_client + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc++_reflection + grpcpp_channelz + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(xds_interop_server + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_dump.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/csds.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.h + src/cpp/server/admin/admin_services.cc + src/cpp/server/csds/csds.cc + test/cpp/end2end/test_health_check_service_impl.cc + test/cpp/interop/xds_interop_server.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(xds_interop_server + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(xds_interop_server + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc++_reflection + grpcpp_channelz + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(alts_credentials_fuzzer_one_entry + test/core/security/alts_credentials_fuzzer.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(alts_credentials_fuzzer_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(alts_credentials_fuzzer_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(client_fuzzer_one_entry + test/core/end2end/fuzzers/client_fuzzer.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(client_fuzzer_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(client_fuzzer_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(hpack_parser_fuzzer_test_one_entry + test/core/transport/chttp2/hpack_parser_fuzzer_test.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(hpack_parser_fuzzer_test_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(hpack_parser_fuzzer_test_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(http_request_fuzzer_test_one_entry + test/core/http/request_fuzzer.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(http_request_fuzzer_test_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(http_request_fuzzer_test_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(http_response_fuzzer_test_one_entry + test/core/http/response_fuzzer.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(http_response_fuzzer_test_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(http_response_fuzzer_test_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(json_fuzzer_test_one_entry + test/core/json/fuzzer.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(json_fuzzer_test_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(json_fuzzer_test_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(nanopb_fuzzer_response_test_one_entry + test/core/nanopb/fuzzer_response.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(nanopb_fuzzer_response_test_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(nanopb_fuzzer_response_test_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(nanopb_fuzzer_serverlist_test_one_entry + test/core/nanopb/fuzzer_serverlist.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(nanopb_fuzzer_serverlist_test_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(nanopb_fuzzer_serverlist_test_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(percent_decode_fuzzer_one_entry + test/core/slice/percent_decode_fuzzer.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(percent_decode_fuzzer_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(percent_decode_fuzzer_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(percent_encode_fuzzer_one_entry + test/core/slice/percent_encode_fuzzer.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(percent_encode_fuzzer_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(percent_encode_fuzzer_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(server_fuzzer_one_entry + test/core/end2end/fuzzers/server_fuzzer.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(server_fuzzer_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(server_fuzzer_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(ssl_server_fuzzer_one_entry + test/core/security/ssl_server_fuzzer.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(ssl_server_fuzzer_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(ssl_server_fuzzer_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() +if(gRPC_BUILD_TESTS) + +add_executable(uri_fuzzer_test_one_entry + test/core/uri/uri_fuzzer_test.cc + test/core/util/one_corpus_entry_fuzzer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(uri_fuzzer_test_one_entry + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(uri_fuzzer_test_one_entry + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::flags + grpc_test_util + grpc++_test_config +) + + +endif() + + + + + + + +if(gRPC_INSTALL) + install(EXPORT gRPCTargets + DESTINATION ${gRPC_INSTALL_CMAKEDIR} + NAMESPACE gRPC:: + ) +endif() + +include(CMakePackageConfigHelpers) + +configure_file(cmake/gRPCConfig.cmake.in + gRPCConfig.cmake @ONLY) +write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/gRPCConfigVersion.cmake + VERSION ${gRPC_CPP_VERSION} + COMPATIBILITY AnyNewerVersion) +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/gRPCConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/gRPCConfigVersion.cmake + DESTINATION ${gRPC_INSTALL_CMAKEDIR} +) +install(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/Findc-ares.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/Findre2.cmake + DESTINATION ${gRPC_INSTALL_CMAKEDIR}/modules +) + +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/etc/roots.pem + DESTINATION ${gRPC_INSTALL_SHAREDIR}) + +# Function to generate pkg-config files. +function(generate_pkgconfig name description version requires + libs libs_private output_filename) + set(PC_NAME "${name}") + set(PC_DESCRIPTION "${description}") + set(PC_VERSION "${version}") + set(PC_REQUIRES "${requires}") + set(PC_LIB "${libs}") + set(PC_LIBS_PRIVATE "${libs_private}") + set(output_filepath "${grpc_BINARY_DIR}/libs/opt/pkgconfig/${output_filename}") + configure_file( + "${grpc_SOURCE_DIR}/cmake/pkg-config-template.pc.in" + "${output_filepath}" + @ONLY) + install(FILES "${output_filepath}" + DESTINATION "lib/pkgconfig/") +endfunction() + +# gpr .pc file +generate_pkgconfig( + "gpr" + "gRPC platform support library" + "${gRPC_CORE_VERSION}" + "absl_base absl_memory absl_optional absl_status absl_str_format absl_strings absl_synchronization absl_time" + "-lgpr" + "" + "gpr.pc") + +# grpc .pc file +generate_pkgconfig( + "gRPC" + "high performance general RPC framework" + "${gRPC_CORE_VERSION}" + "gpr openssl absl_base absl_bind_front absl_flat_hash_map absl_inlined_vector absl_memory absl_optional absl_status absl_statusor absl_str_format absl_strings absl_synchronization absl_time" + "-lgrpc -laddress_sorting -lre2 -lupb -lcares -lz" + "" + "grpc.pc") + +# grpc_unsecure .pc file +generate_pkgconfig( + "gRPC unsecure" + "high performance general RPC framework without SSL" + "${gRPC_CORE_VERSION}" + "gpr absl_base absl_flat_hash_map absl_inlined_vector absl_memory absl_optional absl_status absl_statusor absl_str_format absl_strings absl_synchronization absl_time" + "-lgrpc_unsecure" + "" + "grpc_unsecure.pc") + +# grpc++ .pc file +generate_pkgconfig( + "gRPC++" + "C++ wrapper for gRPC" + "${gRPC_CPP_VERSION}" + "grpc absl_base absl_bind_front absl_flat_hash_map absl_inlined_vector absl_memory absl_optional absl_status absl_statusor absl_str_format absl_strings absl_synchronization absl_time" + "-lgrpc++" + "" + "grpc++.pc") + +# grpc++_unsecure .pc file +generate_pkgconfig( + "gRPC++ unsecure" + "C++ wrapper for gRPC without SSL" + "${gRPC_CPP_VERSION}" + "grpc_unsecure absl_base absl_flat_hash_map absl_inlined_vector absl_memory absl_optional absl_status absl_statusor absl_str_format absl_strings absl_synchronization absl_time" + "-lgrpc++_unsecure" + "" + "grpc++_unsecure.pc") diff --git a/sgx/grpc/examples/cpp/helloworld/getopt.hpp b/sgx/grpc/v1.38.1/examples/cpp/getopt.hpp similarity index 100% rename from sgx/grpc/examples/cpp/helloworld/getopt.hpp rename to sgx/grpc/v1.38.1/examples/cpp/getopt.hpp diff --git a/sgx/grpc/v1.38.1/examples/cpp/helloworld/README.md b/sgx/grpc/v1.38.1/examples/cpp/helloworld/README.md new file mode 100644 index 000000000..4b3d8307e --- /dev/null +++ b/sgx/grpc/v1.38.1/examples/cpp/helloworld/README.md @@ -0,0 +1,15 @@ +# gRPC + +This directory contains the Makefile and the template manifest for the most +recent version of gRPC (as of this writing, version 3.18.0). This was tested +on a machine with SGX v1 and Ubuntu 18.04. + +The Makefile and the template manifest contain extensive comments and are made +self-explanatory. Please review them to gain understanding of Gramine-SGX +and requirements for applications running under Gramine-SGX. + +# Quick Start + +``` +./build.sh +``` diff --git a/sgx/grpc/examples/cpp/helloworld/build.sh b/sgx/grpc/v1.38.1/examples/cpp/helloworld/build.sh similarity index 52% rename from sgx/grpc/examples/cpp/helloworld/build.sh rename to sgx/grpc/v1.38.1/examples/cpp/helloworld/build.sh index 7a30cf429..b77858bea 100755 --- a/sgx/grpc/examples/cpp/helloworld/build.sh +++ b/sgx/grpc/v1.38.1/examples/cpp/helloworld/build.sh @@ -1,14 +1,9 @@ -set -e +set -ex -export BUILD_TYPE=Debug - -export MBEDTLS_PATH=${GRAPHENEDIR}/Examples/ra-tls-mbedtls +export BUILD_TYPE=Release export HELLO_PATH=${GRPC_PATH}/examples/cpp/helloworld -# Build ra-tls-mbedtls -if [ ! -d "${MBEDTLS_PATH}/mbedtls" ]; then - ${MBEDTLS_PATH}/build_install.sh -fi +${GRPC_PATH}/build_cpp.sh # build c++ example cd ${HELLO_PATH} diff --git a/sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_async_client.cc b/sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_async_client.cc new file mode 100644 index 000000000..0637337e6 --- /dev/null +++ b/sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_async_client.cc @@ -0,0 +1,141 @@ +/* + * + * Copyright 2015 gRPC 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. + * + */ + +#include +#include +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +#include "../getopt.hpp" + +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +struct argparser { + bool ssl; + const char* config; + std::string server_address; + argparser() { + server_address = getarg("localhost:50051", "-t", "--target"); + ssl = getarg(true, "-ssl", "--ssl"); + config = getarg("dynamic_config.json", "-cfg", "--config"); + }; +}; + +class GreeterClient { + public: + explicit GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + grpc::ClientContext context; + + // The producer-consumer queue we use to communicate asynchronously with the + // gRPC runtime. + grpc::CompletionQueue cq; + + // Storage for the status of the RPC upon completion. + grpc::Status status; + + // stub_->PrepareAsyncSayHello() creates an RPC object, returning + // an instance to store in "call" but does not actually start the RPC + // Because we are using the asynchronous API, we need to hold on to + // the "call" instance in order to get updates on the ongoing RPC. + std::unique_ptr > rpc( + stub_->PrepareAsyncSayHello(&context, request, &cq)); + + // StartCall initiates the RPC call + rpc->StartCall(); + + // Request that, upon completion of the RPC, "reply" be updated with the + // server's response; "status" with the indication of whether the operation + // was successful. Tag the request with the integer 1. + rpc->Finish(&reply, &status, (void*)1); + void* got_tag; + bool ok = false; + // Block until the next result is available in the completion queue "cq". + // The return value of Next should always be checked. This return value + // tells us whether there is any kind of event or the cq_ is shutting down. + GPR_ASSERT(cq.Next(&got_tag, &ok)); + + // Verify that the result from "cq" corresponds, by its tag, our previous + // request. + GPR_ASSERT(got_tag == (void*)1); + // ... and that the request was completed successfully. Note that "ok" + // corresponds solely to the request for updates introduced by Finish(). + GPR_ASSERT(ok); + + // Act upon the status of the actual RPC. + if (status.ok()) { + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + // Out of the passed in Channel comes the stub, stored here, our view of the + // server's exposed services. + std::unique_ptr stub_; +}; + +void run_client() { + argparser args; + + std::shared_ptr channel = nullptr; + if (args.ssl) { + auto cred = grpc::sgx::TlsCredentials(args.config); + channel = std::move(grpc::CreateChannel(args.server_address, cred)); + // channel = std::move(grpc::sgx::CreateSecureChannel(args.server_address, cred)); + } else { + auto cred = grpc::InsecureChannelCredentials(); + channel = std::move(grpc::CreateChannel(args.server_address, cred)); + } + + GreeterClient greeter(channel); + + std::string user_a = greeter.SayHello("a"); + std::string user_b = greeter.SayHello("b"); + + std::cout << "Greeter received: " << user_a << ", " << user_b << std::endl; +} + +int main(int argc, char** argv) { + run_client(); + + return 0; +} diff --git a/sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_async_server.cc b/sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_async_server.cc new file mode 100644 index 000000000..765197ff0 --- /dev/null +++ b/sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_async_server.cc @@ -0,0 +1,181 @@ +/* + * + * Copyright 2015 gRPC 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. + * + */ + +#include +#include +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +#include "../getopt.hpp" + +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +struct argparser { + bool ssl; + const char* config; + std::string server_address; + argparser() { + server_address = getarg("0.0.0.0:50051", "-host", "--host"); + ssl = getarg(true, "-ssl", "--ssl"); + config = getarg("dynamic_config.json", "-cfg", "--config"); + }; +}; + +class ServerImpl final { + public: + ~ServerImpl() { + server_->Shutdown(); + // Always shutdown the completion queue after the server. + cq_->Shutdown(); + } + + // There is no shutdown handling in this code. + void Run() { + std::string server_address("0.0.0.0:50051"); + + argparser args; + grpc::ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + std::shared_ptr creds = nullptr; + if (args.ssl) { + creds = std::move(grpc::sgx::TlsServerCredentials(args.config)); + } else { + creds = std::move(grpc::InsecureServerCredentials()); + } + builder.AddListeningPort(server_address, creds); + // Register "service_" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *asynchronous* service. + builder.RegisterService(&service_); + // Get hold of the completion queue used for the asynchronous communication + // with the gRPC runtime. + cq_ = builder.AddCompletionQueue(); + // Finally assemble the server. + server_ = builder.BuildAndStart(); + std::cout << "Server listening on " << server_address << std::endl; + + // Proceed to the server's main loop. + HandleRpcs(); + } + + private: + // Class encompasing the state and logic needed to serve a request. + class CallData { + public: + // Take in the "service" instance (in this case representing an asynchronous + // server) and the completion queue "cq" used for asynchronous communication + // with the gRPC runtime. + CallData(Greeter::AsyncService* service, grpc::ServerCompletionQueue* cq) + : service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) { + // Invoke the serving logic right away. + Proceed(); + } + + void Proceed() { + if (status_ == CREATE) { + // Make this instance progress to the PROCESS state. + status_ = PROCESS; + + // As part of the initial CREATE state, we *request* that the system + // start processing SayHello requests. In this request, "this" acts are + // the tag uniquely identifying the request (so that different CallData + // instances can serve different requests concurrently), in this case + // the memory address of this CallData instance. + service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_, + this); + } else if (status_ == PROCESS) { + // Spawn a new CallData instance to serve new clients while we process + // the one for this CallData. The instance will deallocate itself as + // part of its FINISH state. + new CallData(service_, cq_); + + // The actual processing. + std::string prefix("Hello "); + reply_.set_message(prefix + request_.name()); + + // And we are done! Let the gRPC runtime know we've finished, using the + // memory address of this instance as the uniquely identifying tag for + // the event. + status_ = FINISH; + responder_.Finish(reply_, grpc::Status::OK, this); + } else { + GPR_ASSERT(status_ == FINISH); + // Once in the FINISH state, deallocate ourselves (CallData). + delete this; + } + } + + private: + // The means of communication with the gRPC runtime for an asynchronous + // server. + Greeter::AsyncService* service_; + // The producer-consumer queue where for asynchronous server notifications. + grpc::ServerCompletionQueue* cq_; + // Context for the rpc, allowing to tweak aspects of it such as the use + // of compression, authentication, as well as to send metadata back to the + // client. + grpc::ServerContext ctx_; + + // What we get from the client. + HelloRequest request_; + // What we send back to the client. + HelloReply reply_; + + // The means to get back to the client. + grpc::ServerAsyncResponseWriter responder_; + + // Let's implement a tiny state machine with the following states. + enum CallStatus { CREATE, PROCESS, FINISH }; + CallStatus status_; // The current serving state. + }; + + // This can be run in multiple threads if needed. + void HandleRpcs() { + // Spawn a new CallData instance to serve new clients. + new CallData(&service_, cq_.get()); + void* tag; // uniquely identifies a request. + bool ok; + while (true) { + // Block waiting to read the next event from the completion queue. The + // event is uniquely identified by its tag, which in this case is the + // memory address of a CallData instance. + // The return value of Next should always be checked. This return value + // tells us whether there is any kind of event or cq_ is shutting down. + GPR_ASSERT(cq_->Next(&tag, &ok)); + GPR_ASSERT(ok); + static_cast(tag)->Proceed(); + } + } + + std::unique_ptr cq_; + Greeter::AsyncService service_; + std::unique_ptr server_; +}; + +int main(int argc, char** argv) { + ServerImpl server; + server.Run(); + + return 0; +} diff --git a/sgx/grpc/examples/cpp/helloworld/greeter_client.cc b/sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_client.cc similarity index 54% rename from sgx/grpc/examples/cpp/helloworld/greeter_client.cc rename to sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_client.cc index b1d23bfb8..8e966e98f 100644 --- a/sgx/grpc/examples/cpp/helloworld/greeter_client.cc +++ b/sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_client.cc @@ -16,11 +16,8 @@ * */ -#include -#include -#include - #include +#include #ifdef BAZEL_BUILD #include "examples/protos/helloworld.grpc.pb.h" @@ -28,36 +25,26 @@ #include "helloworld.grpc.pb.h" #endif -#include "getopt.hpp" -#include "grpc_sgx_ra_tls.h" +#include "../getopt.hpp" -using grpc::Channel; -using grpc::ClientContext; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; using helloworld::Greeter; +using helloworld::HelloReply; +using helloworld::HelloRequest; struct argparser { - bool ssl; - std::string server_address; - const char * mr_enclave; - const char * mr_signer; - const char * isv_prod_id; - const char * isv_svn; - argparser() { - server_address = getarg("localhost:50051", "-t", "--target"); - ssl = getarg(true, "-ssl", "--ssl"); - mr_enclave = getarg("0", "-mre", "--mrenclave"); - mr_signer = getarg("0", "-mrs", "--mrsigner"); - isv_prod_id = getarg("0", "-id", "--isv_prod_id"); - isv_svn = getarg("0", "-svn", "--isv_svn"); - }; + bool ssl; + const char* config; + std::string server_address; + argparser() { + server_address = getarg("localhost:50051", "-t", "--target"); + ssl = getarg(true, "-ssl", "--ssl"); + config = getarg("dynamic_config.json", "-cfg", "--config"); + }; }; class GreeterClient { public: - GreeterClient(std::shared_ptr channel) + GreeterClient(std::shared_ptr channel) : stub_(Greeter::NewStub(channel)) {} // Assembles the client's payload, sends it and presents the response back @@ -72,10 +59,10 @@ class GreeterClient { // Context for the client. It could be used to convey extra information to // the server and/or tweak certain RPC behaviors. - ClientContext context; + grpc::ClientContext context; // The actual RPC. - Status status = stub_->SayHello(&context, request, &reply); + grpc::Status status = stub_->SayHello(&context, request, &reply); // Act upon its status. if (status.ok()) { @@ -91,25 +78,29 @@ class GreeterClient { std::unique_ptr stub_; }; -int main(int argc, char** argv) { - // Instantiate the client. It requires a channel, out of which the actual RPCs - // are created. This channel models a connection to an endpoint (in this case, - // localhost at port 50051). We indicate that the channel isn't authenticated - // (use of InsecureChannelCredentials()). +void run_client() { argparser args; + std::shared_ptr channel = nullptr; if (args.ssl) { - auto cred = grpc::sgx::TlsCredentials(args.mr_enclave, args.mr_signer, args.isv_prod_id, args.isv_svn); - channel = std::move(grpc::sgx::CreateSecureChannel(args.server_address, cred)); + auto cred = grpc::sgx::TlsCredentials(args.config); + channel = std::move(grpc::CreateChannel(args.server_address, cred)); + // channel = std::move(grpc::sgx::CreateSecureChannel(args.server_address, cred)); } else { - auto cred = grpc::InsecureChannelCredentials(); - channel = std::move(grpc::CreateChannel(args.server_address, cred)); + auto cred = grpc::InsecureChannelCredentials(); + channel = std::move(grpc::CreateChannel(args.server_address, cred)); } GreeterClient greeter(channel); - std::string user("world"); - std::string reply = greeter.SayHello(user); - std::cout << "Greeter received: " << reply << std::endl; + + std::string user_a = greeter.SayHello("a"); + std::string user_b = greeter.SayHello("b"); + + std::cout << "Greeter received: " << user_a << ", "<< user_b << std::endl; +}; + +int main(int argc, char** argv) { + run_client(); return 0; } diff --git a/sgx/grpc/examples/cpp/helloworld/greeter_server.cc b/sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_server.cc similarity index 69% rename from sgx/grpc/examples/cpp/helloworld/greeter_server.cc rename to sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_server.cc index 46ec6b363..32f9d5beb 100644 --- a/sgx/grpc/examples/cpp/helloworld/greeter_server.cc +++ b/sgx/grpc/v1.38.1/examples/cpp/helloworld/greeter_server.cc @@ -16,12 +16,9 @@ * */ -#include -#include -#include - #include -#include +#include +#include #ifdef BAZEL_BUILD #include "examples/protos/helloworld.grpc.pb.h" @@ -29,58 +26,60 @@ #include "helloworld.grpc.pb.h" #endif -#include "getopt.hpp" -#include "grpc_sgx_ra_tls.h" +#include "../getopt.hpp" -using grpc::Server; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::Status; -using helloworld::HelloRequest; -using helloworld::HelloReply; using helloworld::Greeter; +using helloworld::HelloReply; +using helloworld::HelloRequest; struct argparser { - bool ssl; - std::string server_address; - argparser() { - ssl = getarg(true, "-ssl", "--ssl"); - server_address = getarg("0.0.0.0:50051", "-host", "--host"); - }; + bool ssl; + const char* config; + std::string server_address; + argparser() { + server_address = getarg("0.0.0.0:50051", "-host", "--host"); + ssl = getarg(true, "-ssl", "--ssl"); + config = getarg("dynamic_config.json", "-cfg", "--config"); + }; }; - // Logic and data behind the server's behavior. class GreeterServiceImpl final : public Greeter::Service { - Status SayHello(ServerContext* context, const HelloRequest* request, - HelloReply* reply) override { + grpc::Status SayHello( + grpc::ServerContext* context, const HelloRequest* request, HelloReply* reply) override { std::string prefix("Hello "); reply->set_message(prefix + request->name()); - return Status::OK; + return grpc::Status::OK; } }; void RunServer() { argparser args; + GreeterServiceImpl service; - ServerBuilder builder; - // Listen on the given address without any authentication mechanism. + grpc::EnableDefaultHealthCheckService(true); + grpc::reflection::InitProtoReflectionServerBuilderPlugin(); + + grpc::ServerBuilder builder; std::shared_ptr creds = nullptr; + if (args.ssl) { - creds = std::move(grpc::sgx::TlsServerCredentials()); + creds = std::move(grpc::sgx::TlsServerCredentials(args.config)); } else { creds = std::move(grpc::InsecureServerCredentials()); } - + GPR_ASSERT(creds.get() != nullptr); + + // Listen on the given address. builder.AddListeningPort(args.server_address, creds); + // Register "service" as the instance through which we'll communicate with // clients. In this case it corresponds to an *synchronous* service. builder.RegisterService(&service); - std::cout << "BuildAndStart" << std::endl; // Finally assemble the server. - std::unique_ptr server(builder.BuildAndStart()); + std::unique_ptr server(builder.BuildAndStart()); std::cout << "SSL enable: " << args.ssl << ", Server listening on " << args.server_address << std::endl; // Wait for the server to shutdown. Note that some other thread must be diff --git a/sgx/grpc/v1.38.1/examples/cpp/keyvaluestore/build.sh b/sgx/grpc/v1.38.1/examples/cpp/keyvaluestore/build.sh new file mode 100755 index 000000000..f00423dbd --- /dev/null +++ b/sgx/grpc/v1.38.1/examples/cpp/keyvaluestore/build.sh @@ -0,0 +1,14 @@ +set -ex + +export BUILD_TYPE=Release +export HELLO_PATH=${GRPC_PATH}/examples/cpp/keyvaluestore + +${GRPC_PATH}/build_cpp.sh + +# build c++ example +cd ${HELLO_PATH} +mkdir -p build +cd build +cmake -D CMAKE_PREFIX_PATH=${INSTALL_PREFIX} -D CMAKE_BUILD_TYPE=${BUILD_TYPE} .. +make -j `nproc` +cd - diff --git a/sgx/grpc/v1.38.1/examples/cpp/keyvaluestore/client.cc b/sgx/grpc/v1.38.1/examples/cpp/keyvaluestore/client.cc new file mode 100644 index 000000000..d4b103800 --- /dev/null +++ b/sgx/grpc/v1.38.1/examples/cpp/keyvaluestore/client.cc @@ -0,0 +1,113 @@ +/* + * + * Copyright 2018 gRPC 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. + * + */ + +#include +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +#include "caching_interceptor.h" +#include "../getopt.hpp" + +using keyvaluestore::KeyValueStore; +using keyvaluestore::Request; +using keyvaluestore::Response; + +struct argparser { + bool ssl; + const char* config; + std::string server_address; + argparser() { + server_address = getarg("localhost:50051", "-t", "--target"); + ssl = getarg(true, "-ssl", "--ssl"); + config = getarg("dynamic_config.json", "-cfg", "--config"); + }; +}; + +class KeyValueStoreClient { + public: + KeyValueStoreClient(std::shared_ptr channel) + : stub_(KeyValueStore::NewStub(channel)) {} + + // Requests each key in the vector and displays the key and its corresponding + // value as a pair + void GetValues(const std::vector& keys) { + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + grpc::ClientContext context; + auto stream = stub_->GetValues(&context); + for (const auto& key : keys) { + // Key we are sending to the server. + Request request; + request.set_key(key); + stream->Write(request); + + // Get the value for the sent key + Response response; + stream->Read(&response); + std::cout << key << " : " << response.value() << "\n"; + } + stream->WritesDone(); + grpc::Status status = stream->Finish(); + if (!status.ok()) { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + std::cout << "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +void run_client() { + argparser args; + + std::vector< + std::unique_ptr> + interceptor_creators; + interceptor_creators.push_back(std::unique_ptr( + new CachingInterceptorFactory())); + + std::shared_ptr cred = nullptr; + if (args.ssl) { + cred = grpc::sgx::TlsCredentials(args.config); + } else { + cred = grpc::InsecureChannelCredentials(); + } + grpc::ChannelArguments c_args; + std::shared_ptr channel = + std::move(grpc::experimental::CreateCustomChannelWithInterceptors( + args.server_address, cred, c_args, std::move(interceptor_creators))); + + KeyValueStoreClient client(channel); + + std::vector keys = {"key1", "key2", "key3", "key4", + "key5", "key1", "key2", "key4"}; + client.GetValues(keys); +} + +int main(int argc, char** argv) { + run_client(); + + return 0; +} diff --git a/sgx/grpc/v1.38.1/examples/cpp/keyvaluestore/server.cc b/sgx/grpc/v1.38.1/examples/cpp/keyvaluestore/server.cc new file mode 100644 index 000000000..5d4ca3291 --- /dev/null +++ b/sgx/grpc/v1.38.1/examples/cpp/keyvaluestore/server.cc @@ -0,0 +1,109 @@ +/* + * + * Copyright 2018 gRPC 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. + * + */ + +#include +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +#include "../getopt.hpp" + +using keyvaluestore::KeyValueStore; +using keyvaluestore::Request; +using keyvaluestore::Response; + +struct argparser { + bool ssl; + const char* config; + std::string server_address; + argparser() { + server_address = getarg("0.0.0.0:50051", "-host", "--host"); + ssl = getarg(true, "-ssl", "--ssl"); + config = getarg("dynamic_config.json", "-cfg", "--config"); + }; +}; + +struct kv_pair { + const char* key; + const char* value; +}; + +static const kv_pair kvs_map[] = { + {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}, + {"key4", "value4"}, {"key5", "value5"}, +}; + +const char* get_value_from_map(const char* key) { + for (size_t i = 0; i < sizeof(kvs_map) / sizeof(kv_pair); ++i) { + if (strcmp(key, kvs_map[i].key) == 0) { + return kvs_map[i].value; + } + } + return ""; +} + +// Logic and data behind the server's behavior. +class KeyValueStoreServiceImpl final : public KeyValueStore::Service { + grpc::Status GetValues(grpc::ServerContext* context, + grpc::ServerReaderWriter* stream) override { + Request request; + while (stream->Read(&request)) { + Response response; + response.set_value(get_value_from_map(request.key().c_str())); + stream->Write(response); + } + return grpc::Status::OK; + } +}; + +void RunServer() { + argparser args; + + KeyValueStoreServiceImpl service; + + grpc::ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + std::shared_ptr creds = nullptr; + if (args.ssl) { + creds = std::move(grpc::sgx::TlsServerCredentials(args.config)); + } else { + creds = std::move(grpc::InsecureServerCredentials()); + } + + builder.AddListeningPort(args.server_address, creds); + // Register "service" as the instance through which we'll communicate with + // clients. In this case, it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << args.server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} diff --git a/sgx/grpc/v1.38.1/examples/dynamic_config.json b/sgx/grpc/v1.38.1/examples/dynamic_config.json new file mode 100644 index 000000000..c6e8128fc --- /dev/null +++ b/sgx/grpc/v1.38.1/examples/dynamic_config.json @@ -0,0 +1,10 @@ +{ + "verify_in_enclave" : "on", + "verify_mr_enclave" : "on", + "verify_mr_signer" : "on", + "verify_isv_prod_id" : "on", + "verify_isv_svn" : "on", + "sgx_mrs": [ + ], + "other" : [] +} diff --git a/sgx/grpc/v1.38.1/examples/python/helloworld/build.sh b/sgx/grpc/v1.38.1/examples/python/helloworld/build.sh new file mode 100755 index 000000000..48ad2a72a --- /dev/null +++ b/sgx/grpc/v1.38.1/examples/python/helloworld/build.sh @@ -0,0 +1,8 @@ +set -ex + +${GRPC_PATH}/build_python.sh + +pip3 uninstall -y grpcio +pip3 install ${GRPC_PATH}/dist/*.whl + +python3 -u -c "import grpc" diff --git a/sgx/grpc/v1.38.1/examples/python/helloworld/greeter_client.py b/sgx/grpc/v1.38.1/examples/python/helloworld/greeter_client.py new file mode 100644 index 000000000..603ef1b6d --- /dev/null +++ b/sgx/grpc/v1.38.1/examples/python/helloworld/greeter_client.py @@ -0,0 +1,76 @@ +# Copyright 2015 gRPC 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. +"""The Python implementation of the GRPC helloworld.Greeter client.""" + +from __future__ import print_function +import logging +import argparse + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + + +def run(args): + # NOTE(gRPC Python Team): .close() is possible on a channel and should be + # used in circumstances in which the with statement does not fit the needs + # of the code. + + if args.ssl: + credentials = grpc.sgxratls_channel_credentials(config_json=args.config) + channel = grpc.secure_channel(args.target, credentials) + else: + channel = grpc.insecure_channel(args.target) + + stub = helloworld_pb2_grpc.GreeterStub(channel) + user_a = stub.SayHello(helloworld_pb2.HelloRequest(name='a')) + user_b = stub.SayHello(helloworld_pb2.HelloRequest(name='b')) + print("Greeter client received: ", user_a.message, user_b.message) + + channel.close() + + +def command_arguments(): + parser = argparse.ArgumentParser(description='GRPC client.') + parser.add_argument( + '-t', + '--target', + type=str, + required=False, + default='localhost:50051', + help='The server socket address.' + ) + parser.add_argument( + '-ssl', + '--ssl', + type=int, + required=False, + default=True, + help='Enable secure sockets layer' + ) + parser.add_argument( + '-cfg', + '--config', + type=str, + required=False, + default='dynamic_config.json', + help='The path of dynamic config json' + ) + return parser.parse_args() + +if __name__ == '__main__': + args = command_arguments() + logging.basicConfig() + run(args) diff --git a/sgx/grpc/v1.38.1/examples/python/helloworld/greeter_server.py b/sgx/grpc/v1.38.1/examples/python/helloworld/greeter_server.py new file mode 100644 index 000000000..3e58d2ff2 --- /dev/null +++ b/sgx/grpc/v1.38.1/examples/python/helloworld/greeter_server.py @@ -0,0 +1,76 @@ +# Copyright 2015 gRPC 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. +"""The Python implementation of the GRPC helloworld.Greeter server.""" + +from concurrent import futures +import logging +import argparse + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def SayHello(self, request, context): + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def serve(args): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) + + if args.ssl: + credentials = grpc.sgxratls_server_credentials(config_json=args.config) + server.add_secure_port(args.target, credentials) + else: + server.add_insecure_port(args.target) + server.start() + server.wait_for_termination() + + +def command_arguments(): + parser = argparse.ArgumentParser(description='GRPC client.') + parser.add_argument( + '-t', + '--target', + type=str, + required=False, + default='localhost:50051', + help='The server socket address.' + ) + parser.add_argument( + '-ssl', + '--ssl', + type=int, + required=False, + default=True, + help='Enable secure sockets layer' + ) + parser.add_argument( + '-cfg', + '--config', + type=str, + required=False, + default='dynamic_config.json', + help='The path of dynamic config json' + ) + return parser.parse_args() + +if __name__ == '__main__': + args = command_arguments() + logging.basicConfig() + serve(args) diff --git a/sgx/grpc/v1.38.1/include/grpcpp/security/sgx/sgx_ra_tls.h b/sgx/grpc/v1.38.1/include/grpcpp/security/sgx/sgx_ra_tls.h new file mode 100644 index 000000000..b81d204ec --- /dev/null +++ b/sgx/grpc/v1.38.1/include/grpcpp/security/sgx/sgx_ra_tls.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2019 gRPC 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. + * + */ + +#ifndef SGX_RA_TLS_H +#define SGX_RA_TLS_H + +#include + +#include +#include + +namespace grpc { +namespace sgx { + +struct sgx_config; + +void ra_tls_verify_init(sgx_config sgx_cfg); + +void ra_tls_verify_init(const char* sgx_cfg_json); + +int ra_tls_auth_check_schedule(void* /* config_user_data */, + grpc_tls_server_authorization_check_arg* arg); + +std::shared_ptr CreateSecureChannel( + string target_str, std::shared_ptr channel_creds); + +std::vector ra_tls_get_key_cert(); + +std::shared_ptr TlsCredentials(sgx_config sgx_cfg); + +std::shared_ptr TlsCredentials(const char* sgx_cfg_json); + +std::shared_ptr TlsServerCredentials(sgx_config sgx_cfg); + +std::shared_ptr TlsServerCredentials(const char* sgx_cfg_json); + +} // namespace sgx +} // namespace grpc + +#endif // SGX_RA_TLS_H diff --git a/sgx/grpc/v1.38.1/include/grpcpp/security/sgx/sgx_ra_tls_options.h b/sgx/grpc/v1.38.1/include/grpcpp/security/sgx/sgx_ra_tls_options.h new file mode 100644 index 000000000..24e5bb702 --- /dev/null +++ b/sgx/grpc/v1.38.1/include/grpcpp/security/sgx/sgx_ra_tls_options.h @@ -0,0 +1,67 @@ +/* + * + * Copyright 2019 gRPC 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. + * + */ + +#ifndef SGX_RA_TLS_OPTIONS_H +#define SGX_RA_TLS_OPTIONS_H + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace grpc { +namespace sgx { + +// Contains configurable options on the client side. +// Client side doesn't need to always use certificate provider. When the +// certificate provider is not set, we will use the root certificates stored +// in the system default locations, and assume client won't provide any +// identity certificates(single side TLS). +// It is used for experimental purposes for now and it is subject to change. +class CredentialsOptions final : public grpc::experimental::TlsCredentialsOptions { + public: + + explicit CredentialsOptions() : TlsCredentialsOptions() {} + + // Sets option to request the certificates from the client. + // The default is GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE. + void set_cert_request_type( + grpc_ssl_client_certificate_request_type cert_request_type); + + // Sets the option to verify the server. + // The default is GRPC_TLS_SERVER_VERIFICATION. + void set_verification_option( + grpc_tls_server_verification_option server_verification_option); + + // Sets the custom authorization config. + void set_authorization_check_config( + std::shared_ptr + authorization_check_config); + + private: +}; + +} // namespace sgx +} // namespace grpc + +#endif // SGX_RA_TLS_OPTIONS_H diff --git a/sgx/grpc/v1.38.1/setup.py b/sgx/grpc/v1.38.1/setup.py new file mode 100644 index 000000000..f1908de7c --- /dev/null +++ b/sgx/grpc/v1.38.1/setup.py @@ -0,0 +1,537 @@ +# Copyright 2015 gRPC 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. +"""A setup module for the GRPC Python package.""" + +# setuptools need to be imported before distutils. Otherwise it might lead to +# undesirable behaviors or errors. +import setuptools + +# Monkey Patch the unix compiler to accept ASM +# files used by boring SSL. +from distutils.unixccompiler import UnixCCompiler +UnixCCompiler.src_extensions.append('.S') +del UnixCCompiler + +from distutils import cygwinccompiler +from distutils import extension as _extension +from distutils import util +import os +import os.path +import pkg_resources +import platform +import re +import shlex +import shutil +import sys +import sysconfig + +from setuptools.command import egg_info + +import subprocess +from subprocess import PIPE + +# Redirect the manifest template from MANIFEST.in to PYTHON-MANIFEST.in. +egg_info.manifest_maker.template = 'PYTHON-MANIFEST.in' + +PY3 = sys.version_info.major == 3 +PYTHON_STEM = os.path.join('src', 'python', 'grpcio') +CORE_INCLUDE = ( + 'include', + '.', +) +ABSL_INCLUDE = (os.path.join('third_party', 'abseil-cpp'),) +ADDRESS_SORTING_INCLUDE = (os.path.join('third_party', 'address_sorting', + 'include'),) +CARES_INCLUDE = ( + os.path.join('third_party', 'cares'), + os.path.join('third_party', 'cares', 'cares'), +) +if 'darwin' in sys.platform: + CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_darwin'),) +if 'freebsd' in sys.platform: + CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_freebsd'),) +if 'linux' in sys.platform: + CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_linux'),) +if 'openbsd' in sys.platform: + CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_openbsd'),) +RE2_INCLUDE = (os.path.join('third_party', 're2'),) +SSL_INCLUDE = (os.path.join('third_party', 'boringssl-with-bazel', 'src', + 'include'),) +UPB_INCLUDE = (os.path.join('third_party', 'upb'),) +UPB_GRPC_GENERATED_INCLUDE = (os.path.join('src', 'core', 'ext', + 'upb-generated'),) +UPBDEFS_GRPC_GENERATED_INCLUDE = (os.path.join('src', 'core', 'ext', + 'upbdefs-generated'),) +XXHASH_INCLUDE = (os.path.join('third_party', 'xxhash'),) +ZLIB_INCLUDE = (os.path.join('third_party', 'zlib'),) +README = os.path.join(PYTHON_STEM, 'README.rst') + +# Ensure we're in the proper directory whether or not we're being used by pip. +os.chdir(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, os.path.abspath(PYTHON_STEM)) + +# Break import-style to ensure we can actually find our in-repo dependencies. +import _parallel_compile_patch +import _spawn_patch +import commands +import grpc_core_dependencies +import grpc_version + +_parallel_compile_patch.monkeypatch_compile_maybe() +_spawn_patch.monkeypatch_spawn() + +LICENSE = 'Apache License 2.0' + +CLASSIFIERS = [ + 'Development Status :: 5 - Production/Stable', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'License :: OSI Approved :: Apache Software License', +] + + +def _env_bool_value(env_name, default): + """Parses a bool option from an environment variable""" + return os.environ.get(env_name, default).upper() not in ['FALSE', '0', ''] + + +BUILD_WITH_SGX_RA_TLS = _env_bool_value('GRPC_BUILD_WITH_SGX_RA_TLS', + 'True') + +BUILD_WITH_BORING_SSL_ASM = _env_bool_value('GRPC_BUILD_WITH_BORING_SSL_ASM', + 'True') + +# Export this environment variable to override the platform variant that will +# be chosen for boringssl assembly optimizations. This option is useful when +# crosscompiling and the host platform as obtained by distutils.utils.get_platform() +# doesn't match the platform we are targetting. +# Example value: "linux-aarch64" +BUILD_OVERRIDE_BORING_SSL_ASM_PLATFORM = os.environ.get( + 'GRPC_BUILD_OVERRIDE_BORING_SSL_ASM_PLATFORM', '') + +# Environment variable to determine whether or not the Cython extension should +# *use* Cython or use the generated C files. Note that this requires the C files +# to have been generated by building first *with* Cython support. Even if this +# is set to false, if the script detects that the generated `.c` file isn't +# present, then it will still attempt to use Cython. +BUILD_WITH_CYTHON = _env_bool_value('GRPC_PYTHON_BUILD_WITH_CYTHON', 'False') + +# Export this variable to use the system installation of openssl. You need to +# have the header files installed (in /usr/include/openssl) and during +# runtime, the shared library must be installed +BUILD_WITH_SYSTEM_OPENSSL = _env_bool_value('GRPC_PYTHON_BUILD_SYSTEM_OPENSSL', + 'False') + +# Export this variable to use the system installation of zlib. You need to +# have the header files installed (in /usr/include/) and during +# runtime, the shared library must be installed +BUILD_WITH_SYSTEM_ZLIB = _env_bool_value('GRPC_PYTHON_BUILD_SYSTEM_ZLIB', + 'False') + +# Export this variable to use the system installation of cares. You need to +# have the header files installed (in /usr/include/) and during +# runtime, the shared library must be installed +BUILD_WITH_SYSTEM_CARES = _env_bool_value('GRPC_PYTHON_BUILD_SYSTEM_CARES', + 'False') + +# Export this variable to use the system installation of re2. You need to +# have the header files installed (in /usr/include/re2) and during +# runtime, the shared library must be installed +BUILD_WITH_SYSTEM_RE2 = _env_bool_value('GRPC_PYTHON_BUILD_SYSTEM_RE2', 'False') + +# Export this variable to force building the python extension with a statically linked libstdc++. +# At least on linux, this is normally not needed as we can build manylinux-compatible wheels on linux just fine +# without statically linking libstdc++ (which leads to a slight increase in the wheel size). +# This option is useful when crosscompiling wheels for aarch64 where +# it's difficult to ensure that the crosscompilation toolchain has a high-enough version +# of GCC (we require >4.9) but still uses old-enough libstdc++ symbols. +# TODO(jtattermusch): remove this workaround once issues with crosscompiler version are resolved. +BUILD_WITH_STATIC_LIBSTDCXX = _env_bool_value( + 'GRPC_PYTHON_BUILD_WITH_STATIC_LIBSTDCXX', 'False') + +# For local development use only: This skips building gRPC Core and its +# dependencies, including protobuf and boringssl. This allows "incremental" +# compilation by first building gRPC Core using make, then building only the +# Python/Cython layers here. +# +# Note that this requires libboringssl.a in the libs/{dbg,opt}/ directory, which +# may require configuring make to not use the system openssl implementation: +# +# make HAS_SYSTEM_OPENSSL_ALPN=0 +# +# TODO(ericgribkoff) Respect the BUILD_WITH_SYSTEM_* flags alongside this option +USE_PREBUILT_GRPC_CORE = _env_bool_value('GRPC_PYTHON_USE_PREBUILT_GRPC_CORE', + 'False') + +# If this environmental variable is set, GRPC will not try to be compatible with +# libc versions old than the one it was compiled against. +DISABLE_LIBC_COMPATIBILITY = _env_bool_value( + 'GRPC_PYTHON_DISABLE_LIBC_COMPATIBILITY', 'False') + +# Environment variable to determine whether or not to enable coverage analysis +# in Cython modules. +ENABLE_CYTHON_TRACING = _env_bool_value('GRPC_PYTHON_ENABLE_CYTHON_TRACING', + 'False') + +# Environment variable specifying whether or not there's interest in setting up +# documentation building. +ENABLE_DOCUMENTATION_BUILD = _env_bool_value( + 'GRPC_PYTHON_ENABLE_DOCUMENTATION_BUILD', 'False') + + +def check_linker_need_libatomic(): + """Test if linker on system needs libatomic.""" + code_test = (b'#include \n' + + b'int main() { return std::atomic{}; }') + cxx = os.environ.get('CXX', 'c++') + cpp_test = subprocess.Popen([cxx, '-x', 'c++', '-std=c++11', '-'], + stdin=PIPE, + stdout=PIPE, + stderr=PIPE) + cpp_test.communicate(input=code_test) + if cpp_test.returncode == 0: + return False + # Double-check to see if -latomic actually can solve the problem. + # https://github.com/grpc/grpc/issues/22491 + cpp_test = subprocess.Popen( + [cxx, '-x', 'c++', '-std=c++11', '-latomic', '-'], + stdin=PIPE, + stdout=PIPE, + stderr=PIPE) + cpp_test.communicate(input=code_test) + return cpp_test.returncode == 0 + + +# There are some situations (like on Windows) where CC, CFLAGS, and LDFLAGS are +# entirely ignored/dropped/forgotten by distutils and its Cygwin/MinGW support. +# We use these environment variables to thus get around that without locking +# ourselves in w.r.t. the multitude of operating systems this ought to build on. +# We can also use these variables as a way to inject environment-specific +# compiler/linker flags. We assume GCC-like compilers and/or MinGW as a +# reasonable default. +EXTRA_ENV_COMPILE_ARGS = os.environ.get('GRPC_PYTHON_CFLAGS', None) +EXTRA_ENV_LINK_ARGS = os.environ.get('GRPC_PYTHON_LDFLAGS', None) +if EXTRA_ENV_COMPILE_ARGS is None: + EXTRA_ENV_COMPILE_ARGS = ' -std=c++11' + if 'win32' in sys.platform: + if sys.version_info < (3, 5): + EXTRA_ENV_COMPILE_ARGS += ' -D_hypot=hypot' + # We use define flags here and don't directly add to DEFINE_MACROS below to + # ensure that the expert user/builder has a way of turning it off (via the + # envvars) without adding yet more GRPC-specific envvars. + # See https://sourceforge.net/p/mingw-w64/bugs/363/ + if '32' in platform.architecture()[0]: + EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime32 -D_timeb=__timeb32 -D_ftime_s=_ftime32_s' + else: + EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64' + else: + # We need to statically link the C++ Runtime, only the C runtime is + # available dynamically + EXTRA_ENV_COMPILE_ARGS += ' /MT' + elif "linux" in sys.platform: + EXTRA_ENV_COMPILE_ARGS += ' -std=gnu99 -fvisibility=hidden -fno-wrapv -fno-exceptions' + elif "darwin" in sys.platform: + EXTRA_ENV_COMPILE_ARGS += ' -stdlib=libc++ -fvisibility=hidden -fno-wrapv -fno-exceptions' + +if EXTRA_ENV_LINK_ARGS is None: + EXTRA_ENV_LINK_ARGS = '' + if "linux" in sys.platform or "darwin" in sys.platform: + EXTRA_ENV_LINK_ARGS += ' -lpthread' + if check_linker_need_libatomic(): + EXTRA_ENV_LINK_ARGS += ' -latomic' + elif "win32" in sys.platform and sys.version_info < (3, 5): + msvcr = cygwinccompiler.get_msvcr()[0] + EXTRA_ENV_LINK_ARGS += ( + ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr}' + ' -static -lshlwapi'.format(msvcr=msvcr)) + if "linux" in sys.platform: + EXTRA_ENV_LINK_ARGS += ' -Wl,-wrap,memcpy -static-libgcc' + +if BUILD_WITH_SGX_RA_TLS: + EXTRA_ENV_LINK_ARGS += ' -lmbedx509_gramine -lmbedcrypto_gramine -lcjson -lcjson_utils' + +EXTRA_COMPILE_ARGS = shlex.split(EXTRA_ENV_COMPILE_ARGS) +EXTRA_LINK_ARGS = shlex.split(EXTRA_ENV_LINK_ARGS) + +if BUILD_WITH_STATIC_LIBSTDCXX: + EXTRA_LINK_ARGS.append('-static-libstdc++') + +CYTHON_EXTENSION_PACKAGE_NAMES = () + +CYTHON_EXTENSION_MODULE_NAMES = ('grpc._cython.cygrpc',) + +CYTHON_HELPER_C_FILES = () + +CORE_C_FILES = tuple(grpc_core_dependencies.CORE_SOURCE_FILES) + +if "win32" in sys.platform: + CORE_C_FILES = filter(lambda x: 'third_party/cares' not in x, CORE_C_FILES) + +if BUILD_WITH_SYSTEM_OPENSSL: + CORE_C_FILES = filter(lambda x: 'third_party/boringssl' not in x, + CORE_C_FILES) + CORE_C_FILES = filter(lambda x: 'src/boringssl' not in x, CORE_C_FILES) + SSL_INCLUDE = (os.path.join('/usr', 'include', 'openssl'),) + +if BUILD_WITH_SYSTEM_ZLIB: + CORE_C_FILES = filter(lambda x: 'third_party/zlib' not in x, CORE_C_FILES) + ZLIB_INCLUDE = (os.path.join('/usr', 'include'),) + +if BUILD_WITH_SYSTEM_CARES: + CORE_C_FILES = filter(lambda x: 'third_party/cares' not in x, CORE_C_FILES) + CARES_INCLUDE = (os.path.join('/usr', 'include'),) + +if BUILD_WITH_SYSTEM_RE2: + CORE_C_FILES = filter(lambda x: 'third_party/re2' not in x, CORE_C_FILES) + RE2_INCLUDE = (os.path.join('/usr', 'include', 're2'),) + +EXTENSION_INCLUDE_DIRECTORIES = ((PYTHON_STEM,) + CORE_INCLUDE + ABSL_INCLUDE + + ADDRESS_SORTING_INCLUDE + CARES_INCLUDE + + RE2_INCLUDE + SSL_INCLUDE + UPB_INCLUDE + + UPB_GRPC_GENERATED_INCLUDE + + UPBDEFS_GRPC_GENERATED_INCLUDE + + XXHASH_INCLUDE + ZLIB_INCLUDE) + +EXTENSION_LIBRARIES = () +if "linux" in sys.platform: + EXTENSION_LIBRARIES += ('rt',) +if not "win32" in sys.platform: + EXTENSION_LIBRARIES += ('m',) +if "win32" in sys.platform: + EXTENSION_LIBRARIES += ( + 'advapi32', + 'ws2_32', + 'dbghelp', + ) +if BUILD_WITH_SYSTEM_OPENSSL: + EXTENSION_LIBRARIES += ( + 'ssl', + 'crypto', + ) +if BUILD_WITH_SYSTEM_ZLIB: + EXTENSION_LIBRARIES += ('z',) +if BUILD_WITH_SYSTEM_CARES: + EXTENSION_LIBRARIES += ('cares',) +if BUILD_WITH_SYSTEM_RE2: + EXTENSION_LIBRARIES += ('re2',) +if BUILD_WITH_SGX_RA_TLS: + EXTENSION_LIBRARIES += ('grpc++',) + +DEFINE_MACROS = (('_WIN32_WINNT', 0x600),) +asm_files = [] + +asm_key = '' +if BUILD_WITH_BORING_SSL_ASM and not BUILD_WITH_SYSTEM_OPENSSL: + boringssl_asm_platform = BUILD_OVERRIDE_BORING_SSL_ASM_PLATFORM if BUILD_OVERRIDE_BORING_SSL_ASM_PLATFORM else util.get_platform( + ) + LINUX_X86_64 = 'linux-x86_64' + LINUX_ARM = 'linux-arm' + LINUX_AARCH64 = 'linux-aarch64' + if LINUX_X86_64 == boringssl_asm_platform: + asm_key = 'crypto_linux_x86_64' + elif LINUX_ARM == boringssl_asm_platform: + asm_key = 'crypto_linux_arm' + elif LINUX_AARCH64 == boringssl_asm_platform: + asm_key = 'crypto_linux_aarch64' + elif "mac" in boringssl_asm_platform and "x86_64" in boringssl_asm_platform: + asm_key = 'crypto_mac_x86_64' + else: + print("ASM Builds for BoringSSL currently not supported on:", + boringssl_asm_platform) +if asm_key: + asm_files = grpc_core_dependencies.ASM_SOURCE_FILES[asm_key] +else: + DEFINE_MACROS += (('OPENSSL_NO_ASM', 1),) + +if not DISABLE_LIBC_COMPATIBILITY: + DEFINE_MACROS += (('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),) + +if "win32" in sys.platform: + # TODO(zyc): Re-enable c-ares on x64 and x86 windows after fixing the + # ares_library_init compilation issue + DEFINE_MACROS += ( + ('WIN32_LEAN_AND_MEAN', 1), + ('CARES_STATICLIB', 1), + ('GRPC_ARES', 0), + ('NTDDI_VERSION', 0x06000000), + ('NOMINMAX', 1), + ) + if '64bit' in platform.architecture()[0]: + DEFINE_MACROS += (('MS_WIN64', 1),) + elif sys.version_info >= (3, 5): + # For some reason, this is needed to get access to inet_pton/inet_ntop + # on msvc, but only for 32 bits + DEFINE_MACROS += (('NTDDI_VERSION', 0x06000000),) +else: + DEFINE_MACROS += ( + ('HAVE_CONFIG_H', 1), + ('GRPC_ENABLE_FORK_SUPPORT', 1), + ) + +LDFLAGS = tuple(EXTRA_LINK_ARGS) +CFLAGS = tuple(EXTRA_COMPILE_ARGS) +if "linux" in sys.platform or "darwin" in sys.platform: + pymodinit_type = 'PyObject*' if PY3 else 'void' + pymodinit = 'extern "C" __attribute__((visibility ("default"))) {}'.format( + pymodinit_type) + DEFINE_MACROS += (('PyMODINIT_FUNC', pymodinit),) + DEFINE_MACROS += (('GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK', 1),) + +# By default, Python3 distutils enforces compatibility of +# c plugins (.so files) with the OSX version Python was built with. +# We need OSX 10.10, the oldest which supports C++ thread_local. +# Python 3.9: Mac OS Big Sur sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') returns int (11) +if 'darwin' in sys.platform: + mac_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + if mac_target: + mac_target = pkg_resources.parse_version(str(mac_target)) + if mac_target < pkg_resources.parse_version('10.10.0'): + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.10' + os.environ['_PYTHON_HOST_PLATFORM'] = re.sub( + r'macosx-[0-9]+\.[0-9]+-(.+)', r'macosx-10.10-\1', + util.get_platform()) + + +def cython_extensions_and_necessity(): + cython_module_files = [ + os.path.join(PYTHON_STEM, + name.replace('.', '/') + '.pyx') + for name in CYTHON_EXTENSION_MODULE_NAMES + ] + config = os.environ.get('CONFIG', 'opt') + prefix = 'libs/' + config + '/' + if USE_PREBUILT_GRPC_CORE: + extra_objects = [ + prefix + 'libares.a', prefix + 'libboringssl.a', + prefix + 'libgpr.a', prefix + 'libgrpc.a' + ] + core_c_files = [] + else: + core_c_files = list(CORE_C_FILES) + extra_objects = [] + + extensions = [ + _extension.Extension( + name=module_name, + sources=([module_file] + list(CYTHON_HELPER_C_FILES) + + core_c_files + asm_files), + include_dirs=list(EXTENSION_INCLUDE_DIRECTORIES), + libraries=list(EXTENSION_LIBRARIES), + define_macros=list(DEFINE_MACROS), + extra_objects=extra_objects, + extra_compile_args=list(CFLAGS), + extra_link_args=list(LDFLAGS), + language='c++', + ) for (module_name, module_file + ) in zip(list(CYTHON_EXTENSION_MODULE_NAMES), cython_module_files) + ] + need_cython = BUILD_WITH_CYTHON + if not BUILD_WITH_CYTHON: + need_cython = need_cython or not commands.check_and_update_cythonization( + extensions) + # TODO: the strategy for conditional compiling and exposing the aio Cython + # dependencies will be revisited by https://github.com/grpc/grpc/issues/19728 + return commands.try_cythonize(extensions, + linetracing=ENABLE_CYTHON_TRACING, + mandatory=BUILD_WITH_CYTHON), need_cython + + +CYTHON_EXTENSION_MODULES, need_cython = cython_extensions_and_necessity() + +PACKAGE_DIRECTORIES = { + '': PYTHON_STEM, +} + +INSTALL_REQUIRES = ( + "six>=1.5.2", + "futures>=2.2.0; python_version<'3.2'", + "enum34>=1.0.4; python_version<'3.4'", +) +EXTRAS_REQUIRES = { + 'protobuf': 'grpcio-tools>={version}'.format(version=grpc_version.VERSION), +} + +SETUP_REQUIRES = INSTALL_REQUIRES + ( + 'Sphinx~=1.8.1', + 'six>=1.10', +) if ENABLE_DOCUMENTATION_BUILD else () + +try: + import Cython +except ImportError: + if BUILD_WITH_CYTHON: + sys.stderr.write( + "You requested a Cython build via GRPC_PYTHON_BUILD_WITH_CYTHON, " + "but do not have Cython installed. We won't stop you from using " + "other commands, but the extension files will fail to build.\n") + elif need_cython: + sys.stderr.write( + 'We could not find Cython. Setup may take 10-20 minutes.\n') + SETUP_REQUIRES += ('cython>=0.23',) + +COMMAND_CLASS = { + 'doc': commands.SphinxDocumentation, + 'build_project_metadata': commands.BuildProjectMetadata, + 'build_py': commands.BuildPy, + 'build_ext': commands.BuildExt, + 'gather': commands.Gather, + 'clean': commands.Clean, +} + +# Ensure that package data is copied over before any commands have been run: +credentials_dir = os.path.join(PYTHON_STEM, 'grpc', '_cython', '_credentials') +try: + os.mkdir(credentials_dir) +except OSError: + pass +shutil.copyfile(os.path.join('etc', 'roots.pem'), + os.path.join(credentials_dir, 'roots.pem')) + +PACKAGE_DATA = { + # Binaries that may or may not be present in the final installation, but are + # mentioned here for completeness. + 'grpc._cython': [ + '_credentials/roots.pem', + '_windows/grpc_c.32.python', + '_windows/grpc_c.64.python', + ], +} +PACKAGES = setuptools.find_packages(PYTHON_STEM) + +setuptools.setup( + name='grpcio', + version=grpc_version.VERSION, + description='HTTP/2-based RPC framework', + author='The gRPC Authors', + author_email='grpc-io@googlegroups.com', + url='https://grpc.io', + license=LICENSE, + classifiers=CLASSIFIERS, + long_description=open(README).read(), + ext_modules=CYTHON_EXTENSION_MODULES, + packages=list(PACKAGES), + package_dir=PACKAGE_DIRECTORIES, + package_data=PACKAGE_DATA, + install_requires=INSTALL_REQUIRES, + extras_require=EXTRAS_REQUIRES, + setup_requires=SETUP_REQUIRES, + cmdclass=COMMAND_CLASS, +) diff --git a/sgx/grpc/v1.38.1/src/core/lib/security/credentials/tls/tls_credentials.cc b/sgx/grpc/v1.38.1/src/core/lib/security/credentials/tls/tls_credentials.cc new file mode 100644 index 000000000..ab80b2255 --- /dev/null +++ b/sgx/grpc/v1.38.1/src/core/lib/security/credentials/tls/tls_credentials.cc @@ -0,0 +1,133 @@ +/* + * + * Copyright 2018 gRPC 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. + * + */ + +#include + +#include "src/core/lib/security/credentials/tls/tls_credentials.h" + +#include + +#include +#include +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/security/security_connector/tls/tls_security_connector.h" + +#define GRPC_CREDENTIALS_TYPE_TLS "Tls" + +namespace { + +bool CredentialOptionSanityCheck(const grpc_tls_credentials_options* options, + bool is_client) { + if (options == nullptr) { + gpr_log(GPR_ERROR, "TLS credentials options is nullptr."); + return false; + } + // TODO(ZhenLian): remove this when it is also supported on server side. + // if (!is_client && options->server_authorization_check_config() != nullptr) { + // gpr_log(GPR_INFO, + // "Server's credentials options should not contain server " + // "authorization check config."); + // } + if (options->server_verification_option() != GRPC_TLS_SERVER_VERIFICATION && + options->server_authorization_check_config() == nullptr) { + gpr_log(GPR_ERROR, + "Should provider custom verifications if bypassing default ones."); + return false; + } + return true; +} + +} // namespace + +TlsCredentials::TlsCredentials( + grpc_core::RefCountedPtr options) + : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_TLS), + options_(std::move(options)) {} + +TlsCredentials::~TlsCredentials() {} + +grpc_core::RefCountedPtr +TlsCredentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target_name, const grpc_channel_args* args, + grpc_channel_args** new_args) { + const char* overridden_target_name = nullptr; + tsi_ssl_session_cache* ssl_session_cache = nullptr; + for (size_t i = 0; args != nullptr && i < args->num_args; i++) { + grpc_arg* arg = &args->args[i]; + if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 && + arg->type == GRPC_ARG_STRING) { + overridden_target_name = arg->value.string; + } + if (strcmp(arg->key, GRPC_SSL_SESSION_CACHE_ARG) == 0 && + arg->type == GRPC_ARG_POINTER) { + ssl_session_cache = + static_cast(arg->value.pointer.p); + } + } + grpc_core::RefCountedPtr sc = + grpc_core::TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector( + this->Ref(), options_, std::move(call_creds), target_name, + overridden_target_name, ssl_session_cache); + if (sc == nullptr) { + return nullptr; + } + if (args != nullptr) { + grpc_arg new_arg = grpc_channel_arg_string_create( + const_cast(GRPC_ARG_HTTP2_SCHEME), const_cast("https")); + *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); + } + return sc; +} + +TlsServerCredentials::TlsServerCredentials( + grpc_core::RefCountedPtr options) + : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_TLS), + options_(std::move(options)) {} + +TlsServerCredentials::~TlsServerCredentials() {} + +grpc_core::RefCountedPtr +TlsServerCredentials::create_security_connector( + const grpc_channel_args* /* args */) { + return grpc_core::TlsServerSecurityConnector:: + CreateTlsServerSecurityConnector(this->Ref(), options_); +} + +/** -- Wrapper APIs declared in grpc_security.h -- **/ + +grpc_channel_credentials* grpc_tls_credentials_create( + grpc_tls_credentials_options* options) { + if (!CredentialOptionSanityCheck(options, true /* is_client */)) { + return nullptr; + } + return new TlsCredentials( + grpc_core::RefCountedPtr(options)); +} + +grpc_server_credentials* grpc_tls_server_credentials_create( + grpc_tls_credentials_options* options) { + if (!CredentialOptionSanityCheck(options, false /* is_client */)) { + return nullptr; + } + return new TlsServerCredentials( + grpc_core::RefCountedPtr(options)); +} diff --git a/sgx/grpc/v1.38.1/src/core/lib/security/security_connector/tls/tls_security_connector.cc b/sgx/grpc/v1.38.1/src/core/lib/security/security_connector/tls/tls_security_connector.cc new file mode 100644 index 000000000..db21ed0f4 --- /dev/null +++ b/sgx/grpc/v1.38.1/src/core/lib/security/security_connector/tls/tls_security_connector.cc @@ -0,0 +1,863 @@ +/* + * + * Copyright 2018 gRPC 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. + * + */ + +#include + +#include "src/core/lib/security/security_connector/tls/tls_security_connector.h" + +#include +#include + +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" + +#include +#include +#include +#include + +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/security/credentials/ssl/ssl_credentials.h" +#include "src/core/lib/security/credentials/tls/tls_credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" +#include "src/core/lib/security/transport/security_handshaker.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/transport/transport.h" +#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/tsi/transport_security.h" + +namespace grpc_core { + +namespace { + +tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair( + const PemKeyCertPairList& cert_pair_list) { + tsi_ssl_pem_key_cert_pair* tsi_pairs = nullptr; + size_t num_key_cert_pairs = cert_pair_list.size(); + if (num_key_cert_pairs > 0) { + GPR_ASSERT(cert_pair_list.data() != nullptr); + tsi_pairs = static_cast( + gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair))); + } + for (size_t i = 0; i < num_key_cert_pairs; i++) { + GPR_ASSERT(!cert_pair_list[i].private_key().empty()); + GPR_ASSERT(!cert_pair_list[i].cert_chain().empty()); + tsi_pairs[i].cert_chain = + gpr_strdup(cert_pair_list[i].cert_chain().c_str()); + tsi_pairs[i].private_key = + gpr_strdup(cert_pair_list[i].private_key().c_str()); + } + return tsi_pairs; +} + +} // namespace + +void gpr_check_free(void* p) { + if (p) { + gpr_free(p); + p = nullptr; + } +} + +// -------------------channel security connector------------------- +RefCountedPtr +TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector( + RefCountedPtr channel_creds, + RefCountedPtr options, + RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache) { + if (channel_creds == nullptr) { + gpr_log(GPR_ERROR, + "channel_creds is nullptr in " + "TlsChannelSecurityConnectorCreate()"); + return nullptr; + } + if (options == nullptr) { + gpr_log(GPR_ERROR, + "options is nullptr in " + "TlsChannelSecurityConnectorCreate()"); + return nullptr; + } + if (target_name == nullptr) { + gpr_log(GPR_ERROR, + "target_name is nullptr in " + "TlsChannelSecurityConnectorCreate()"); + return nullptr; + } + return MakeRefCounted( + std::move(channel_creds), std::move(options), + std::move(request_metadata_creds), target_name, overridden_target_name, + ssl_session_cache); +} + +TlsChannelSecurityConnector::TlsChannelSecurityConnector( + RefCountedPtr channel_creds, + RefCountedPtr options, + RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache) + : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME, + std::move(channel_creds), + std::move(request_metadata_creds)), + options_(std::move(options)), + overridden_target_name_( + overridden_target_name == nullptr ? "" : overridden_target_name), + ssl_session_cache_(ssl_session_cache) { + if (ssl_session_cache_ != nullptr) { + tsi_ssl_session_cache_ref(ssl_session_cache_); + } + check_arg_ = ServerAuthorizationCheckArgCreate(this); + absl::string_view host; + absl::string_view port; + SplitHostPort(target_name, &host, &port); + target_name_ = std::string(host); + // Create a watcher. + auto watcher_ptr = absl::make_unique(this); + certificate_watcher_ = watcher_ptr.get(); + // Register the watcher with the distributor. + grpc_tls_certificate_distributor* distributor = + options_->certificate_distributor(); + absl::optional watched_root_cert_name; + if (options_->watch_root_cert()) { + watched_root_cert_name = options_->root_cert_name(); + } + absl::optional watched_identity_cert_name; + if (options_->watch_identity_pair()) { + watched_identity_cert_name = options_->identity_cert_name(); + } + // We will use the root certs stored in system default locations if not + // watching root certs on the client side. We will handle this case + // differently here, because "watching a default roots without the identity + // certs" is a valid case(and hence we will need to call + // OnCertificatesChanged), but it requires nothing from the provider, and + // hence no need to register the watcher. + bool use_default_roots = !options_->watch_root_cert(); + if (use_default_roots && !options_->watch_identity_pair()) { + watcher_ptr->OnCertificatesChanged(absl::nullopt, absl::nullopt); + } else { + distributor->WatchTlsCertificates(std::move(watcher_ptr), + watched_root_cert_name, + watched_identity_cert_name); + } +} + +TlsChannelSecurityConnector::~TlsChannelSecurityConnector() { + if (ssl_session_cache_ != nullptr) { + tsi_ssl_session_cache_unref(ssl_session_cache_); + } + // Cancel all the watchers. + grpc_tls_certificate_distributor* distributor = + options_->certificate_distributor(); + if (distributor != nullptr) { + distributor->CancelTlsCertificatesWatch(certificate_watcher_); + } + if (client_handshaker_factory_ != nullptr) { + tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); + } + if (check_arg_ != nullptr) { + ServerAuthorizationCheckArgDestroy(check_arg_); + } +} + +void TlsChannelSecurityConnector::add_handshakers( + const grpc_channel_args* args, grpc_pollset_set* /*interested_parties*/, + HandshakeManager* handshake_mgr) { + MutexLock lock(&mu_); + if (client_handshaker_factory_ != nullptr) { + // Instantiate TSI handshaker. + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( + client_handshaker_factory_, + overridden_target_name_.empty() ? target_name_.c_str() + : overridden_target_name_.c_str(), + &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + handshake_mgr->Add(SecurityHandshakerCreate(tsi_hs, this, args)); + return; + } + // TODO(ZhenLian): Implement the logic(delegation to + // BlockOnInitialCredentialHandshaker) when certificates are not ready. + gpr_log(GPR_ERROR, "%s not supported yet.", + "Client BlockOnInitialCredentialHandshaker"); +} + +void TlsChannelSecurityConnector::check_peer( + tsi_peer peer, grpc_endpoint* /*ep*/, + RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + const char* target_name = overridden_target_name_.empty() + ? target_name_.c_str() + : overridden_target_name_.c_str(); + grpc_error_handle error = grpc_ssl_check_alpn(&peer); + if (error != GRPC_ERROR_NONE) { + ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error); + tsi_peer_destruct(&peer); + return; + } + *auth_context = + grpc_ssl_peer_to_auth_context(&peer, GRPC_TLS_TRANSPORT_SECURITY_TYPE); + if (options_->server_verification_option() == GRPC_TLS_SERVER_VERIFICATION) { + /* Do the default host name check if specifying the target name. */ + error = internal::TlsCheckHostName(target_name, &peer); + if (error != GRPC_ERROR_NONE) { + ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error); + tsi_peer_destruct(&peer); + return; + } + } + /* Do the custom server authorization check, if specified by the user. */ + const grpc_tls_server_authorization_check_config* config = + options_->server_authorization_check_config(); + /* If server authorization config is not null, use it to perform + * server authorization check. */ + if (config != nullptr) { + const tsi_peer_property* p = + tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); + if (p == nullptr) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing pem cert property."); + } else { + char* peer_pem = static_cast(gpr_zalloc(p->value.length + 1)); + memcpy(peer_pem, p->value.data, p->value.length); + GPR_ASSERT(check_arg_ != nullptr); + check_arg_->peer_cert = check_arg_->peer_cert == nullptr + ? gpr_strdup(peer_pem) + : check_arg_->peer_cert; + check_arg_->target_name = check_arg_->target_name == nullptr + ? gpr_strdup(target_name) + : check_arg_->target_name; + on_peer_checked_ = on_peer_checked; + gpr_check_free(peer_pem); + const tsi_peer_property* chain = tsi_peer_get_property_by_name( + &peer, TSI_X509_PEM_CERT_CHAIN_PROPERTY); + if (chain != nullptr) { + char* peer_pem_chain = + static_cast(gpr_zalloc(chain->value.length + 1)); + memcpy(peer_pem_chain, chain->value.data, chain->value.length); + check_arg_->peer_cert_full_chain = + check_arg_->peer_cert_full_chain == nullptr + ? gpr_strdup(peer_pem_chain) + : check_arg_->peer_cert_full_chain; + gpr_check_free(peer_pem_chain); + } + // TODO(zhenlian) - This should be cleaned up as part of the custom + // verification changes. Fill in the subject alternative names + std::vector subject_alternative_names; + for (size_t i = 0; i < peer.property_count; i++) { + const tsi_peer_property* prop = &peer.properties[i]; + if (strcmp(prop->name, + TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { + char* san = new char[prop->value.length + 1]; + memcpy(san, prop->value.data, prop->value.length); + san[prop->value.length] = '\0'; + subject_alternative_names.emplace_back(san); + } + } + if (check_arg_->subject_alternative_names != nullptr) { + for (size_t i = 0; i < check_arg_->subject_alternative_names_size; + ++i) { + delete[] check_arg_->subject_alternative_names[i]; + } + delete[] check_arg_->subject_alternative_names; + } + check_arg_->subject_alternative_names_size = + subject_alternative_names.size(); + if (subject_alternative_names.empty()) { + check_arg_->subject_alternative_names = nullptr; + } else { + check_arg_->subject_alternative_names = + new char*[check_arg_->subject_alternative_names_size]; + for (size_t i = 0; i < check_arg_->subject_alternative_names_size; + ++i) { + check_arg_->subject_alternative_names[i] = + subject_alternative_names[i]; + } + } + int callback_status = config->Schedule(check_arg_); + /* Server authorization check is handled asynchronously. */ + if (callback_status) { + tsi_peer_destruct(&peer); + return; + } + /* Server authorization check is handled synchronously. */ + error = ProcessServerAuthorizationCheckResult(check_arg_); + } + } + ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error); + tsi_peer_destruct(&peer); +} + +int TlsChannelSecurityConnector::cmp( + const grpc_security_connector* other_sc) const { + auto* other = reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) { + return c; + } + return grpc_ssl_cmp_target_name( + target_name_.c_str(), other->target_name_.c_str(), + overridden_target_name_.c_str(), other->overridden_target_name_.c_str()); +} + +bool TlsChannelSecurityConnector::check_call_host( + absl::string_view host, grpc_auth_context* auth_context, + grpc_closure* /*on_call_host_checked*/, grpc_error_handle* error) { + if (options_->server_verification_option() == + GRPC_TLS_SKIP_HOSTNAME_VERIFICATION || + options_->server_verification_option() == + GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION) { + return true; + } + return grpc_ssl_check_call_host(host, target_name_.c_str(), + overridden_target_name_.c_str(), auth_context, + error); +} + +void TlsChannelSecurityConnector::cancel_check_call_host( + grpc_closure* /*on_call_host_checked*/, grpc_error_handle error) { + GRPC_ERROR_UNREF(error); +} + +void TlsChannelSecurityConnector::TlsChannelCertificateWatcher:: + OnCertificatesChanged(absl::optional root_certs, + absl::optional key_cert_pairs) { + GPR_ASSERT(security_connector_ != nullptr); + MutexLock lock(&security_connector_->mu_); + if (root_certs.has_value()) { + security_connector_->pem_root_certs_ = root_certs; + } + if (key_cert_pairs.has_value()) { + security_connector_->pem_key_cert_pair_list_ = std::move(key_cert_pairs); + } + const bool root_ready = !security_connector_->options_->watch_root_cert() || + security_connector_->pem_root_certs_.has_value(); + const bool identity_ready = + !security_connector_->options_->watch_identity_pair() || + security_connector_->pem_key_cert_pair_list_.has_value(); + if (root_ready && identity_ready) { + if (security_connector_->UpdateHandshakerFactoryLocked() != + GRPC_SECURITY_OK) { + gpr_log(GPR_ERROR, "Update handshaker factory failed."); + } + } +} + +// TODO(ZhenLian): implement the logic to signal waiting handshakers once +// BlockOnInitialCredentialHandshaker is implemented. +void TlsChannelSecurityConnector::TlsChannelCertificateWatcher::OnError( + grpc_error_handle root_cert_error, grpc_error_handle identity_cert_error) { + if (root_cert_error != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, + "TlsChannelCertificateWatcher getting root_cert_error: %s", + grpc_error_std_string(root_cert_error).c_str()); + } + if (identity_cert_error != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, + "TlsChannelCertificateWatcher getting identity_cert_error: %s", + grpc_error_std_string(identity_cert_error).c_str()); + } + GRPC_ERROR_UNREF(root_cert_error); + GRPC_ERROR_UNREF(identity_cert_error); +} + +// TODO(ZhenLian): implement the logic to signal waiting handshakers once +// BlockOnInitialCredentialHandshaker is implemented. +grpc_security_status +TlsChannelSecurityConnector::UpdateHandshakerFactoryLocked() { + bool skip_server_certificate_verification = + options_->server_verification_option() == + GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION; + /* Free the client handshaker factory if exists. */ + if (client_handshaker_factory_ != nullptr) { + tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); + } + std::string pem_root_certs; + if (pem_root_certs_.has_value()) { + // TODO(ZhenLian): update the underlying TSI layer to use C++ types like + // std::string and absl::string_view to avoid making another copy here. + pem_root_certs = std::string(*pem_root_certs_); + } + tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = nullptr; + if (pem_key_cert_pair_list_.has_value()) { + pem_key_cert_pair = ConvertToTsiPemKeyCertPair(*pem_key_cert_pair_list_); + } + bool use_default_roots = !options_->watch_root_cert(); + grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init( + pem_key_cert_pair, + pem_root_certs.empty() || use_default_roots ? nullptr + : pem_root_certs.c_str(), + skip_server_certificate_verification, + grpc_get_tsi_tls_version(options_->min_tls_version()), + grpc_get_tsi_tls_version(options_->max_tls_version()), ssl_session_cache_, + &client_handshaker_factory_); + /* Free memory. */ + if (pem_key_cert_pair != nullptr) { + grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1); + } + return status; +} + +void TlsChannelSecurityConnector::ServerAuthorizationCheckDone( + grpc_tls_server_authorization_check_arg* arg) { + GPR_ASSERT(arg != nullptr); + ExecCtx exec_ctx; + grpc_error_handle error = ProcessServerAuthorizationCheckResult(arg); + TlsChannelSecurityConnector* connector = + static_cast(arg->cb_user_data); + ExecCtx::Run(DEBUG_LOCATION, connector->on_peer_checked_, error); +} + +grpc_error_handle +TlsChannelSecurityConnector::ProcessServerAuthorizationCheckResult( + grpc_tls_server_authorization_check_arg* arg) { + grpc_error_handle error = GRPC_ERROR_NONE; + /* Server authorization check is cancelled by caller. */ + if (arg->status == GRPC_STATUS_CANCELLED) { + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("Server authorization check is cancelled by the caller " + "with error: ", + arg->error_details->error_details()) + .c_str()); + } else if (arg->status == GRPC_STATUS_OK) { + /* Server authorization check completed successfully but returned check + * failure. */ + if (!arg->success) { + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("Server authorization check failed with error: ", + arg->error_details->error_details()) + .c_str()); + } + /* Server authorization check did not complete correctly. */ + } else { + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat( + "Server authorization check did not finish correctly with error: ", + arg->error_details->error_details()) + .c_str()); + } + return error; +} + +grpc_tls_server_authorization_check_arg* +TlsChannelSecurityConnector::ServerAuthorizationCheckArgCreate( + void* user_data) { + grpc_tls_server_authorization_check_arg* arg = + new grpc_tls_server_authorization_check_arg(); + arg->target_name = nullptr; + arg->peer_cert = nullptr; + arg->peer_cert_full_chain = nullptr; + arg->subject_alternative_names = nullptr; + arg->subject_alternative_names_size = 0; + arg->error_details = new grpc_tls_error_details(); + arg->cb = ServerAuthorizationCheckDone; + arg->cb_user_data = user_data; + arg->status = GRPC_STATUS_OK; + return arg; +} + +void TlsChannelSecurityConnector::ServerAuthorizationCheckArgDestroy( + grpc_tls_server_authorization_check_arg* arg) { + if (arg == nullptr) { + return; + } + gpr_check_free(const_cast(arg->target_name)); + gpr_check_free(const_cast(arg->peer_cert)); + gpr_check_free(const_cast(arg->peer_cert_full_chain)); + for (size_t i = 0; i < arg->subject_alternative_names_size; ++i) { + delete[] arg->subject_alternative_names[i]; + } + delete[] arg->subject_alternative_names; + delete arg->error_details; + if (arg->destroy_context != nullptr) { + arg->destroy_context(arg->context); + } + delete arg; + arg = nullptr; +} + +// -------------------server security connector------------------- +RefCountedPtr +TlsServerSecurityConnector::CreateTlsServerSecurityConnector( + RefCountedPtr server_creds, + RefCountedPtr options) { + if (server_creds == nullptr) { + gpr_log(GPR_ERROR, + "server_creds is nullptr in " + "TlsServerSecurityConnectorCreate()"); + return nullptr; + } + if (options == nullptr) { + gpr_log(GPR_ERROR, + "options is nullptr in " + "TlsServerSecurityConnectorCreate()"); + return nullptr; + } + return MakeRefCounted(std::move(server_creds), + std::move(options)); +} + +void TlsServerSecurityConnector::ClientAuthorizationCheckDone( + grpc_tls_server_authorization_check_arg* arg) { + GPR_ASSERT(arg != nullptr); + ExecCtx exec_ctx; + grpc_error_handle error = ProcessClientAuthorizationCheckResult(arg); + TlsServerSecurityConnector* connector = + static_cast(arg->cb_user_data); + ExecCtx::Run(DEBUG_LOCATION, connector->on_peer_checked_, error); +} + +grpc_error_handle +TlsServerSecurityConnector::ProcessClientAuthorizationCheckResult( + grpc_tls_server_authorization_check_arg* arg) { + grpc_error_handle error = GRPC_ERROR_NONE; + /* Client authorization check is cancelled by caller. */ + if (arg->status == GRPC_STATUS_CANCELLED) { + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("Client authorization check is cancelled by the caller " + "with error: ", + arg->error_details->error_details()) + .c_str()); + } else if (arg->status == GRPC_STATUS_OK) { + /* Client authorization check completed successfully but returned check + * failure. */ + if (!arg->success) { + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("Client authorization check failed with error: ", + arg->error_details->error_details()) + .c_str()); + } + /* Client authorization check did not complete correctly. */ + } else { + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat( + "Client authorization check did not finish correctly with error: ", + arg->error_details->error_details()) + .c_str()); + } + return error; +} + +grpc_tls_server_authorization_check_arg* +TlsServerSecurityConnector::ClientAuthorizationCheckArgCreate( + void* user_data) { + grpc_tls_server_authorization_check_arg* arg = + new grpc_tls_server_authorization_check_arg(); + arg->target_name = nullptr; + arg->peer_cert = nullptr; + arg->peer_cert_full_chain = nullptr; + arg->subject_alternative_names = nullptr; + arg->subject_alternative_names_size = 0; + arg->error_details = new grpc_tls_error_details(); + arg->cb = ClientAuthorizationCheckDone; + arg->cb_user_data = user_data; + arg->status = GRPC_STATUS_OK; + return arg; +} + +void TlsServerSecurityConnector::ClientAuthorizationCheckArgDestroy( + grpc_tls_server_authorization_check_arg* arg) { + if (arg == nullptr) { + return; + } + gpr_check_free(const_cast(arg->target_name)); + gpr_check_free(const_cast(arg->peer_cert)); + gpr_check_free(const_cast(arg->peer_cert_full_chain)); + for (size_t i = 0; i < arg->subject_alternative_names_size; ++i) { + delete[] arg->subject_alternative_names[i]; + } + delete[] arg->subject_alternative_names; + delete arg->error_details; + if (arg->destroy_context != nullptr) { + arg->destroy_context(arg->context); + } + delete arg; + arg = nullptr; +} + +TlsServerSecurityConnector::TlsServerSecurityConnector( + RefCountedPtr server_creds, + RefCountedPtr options) + : grpc_server_security_connector(GRPC_SSL_URL_SCHEME, + std::move(server_creds)), + options_(std::move(options)) { + check_arg_ = ClientAuthorizationCheckArgCreate(this); + // Create a watcher. + auto watcher_ptr = absl::make_unique(this); + certificate_watcher_ = watcher_ptr.get(); + // Register the watcher with the distributor. + grpc_tls_certificate_distributor* distributor = + options_->certificate_distributor(); + absl::optional watched_root_cert_name; + if (options_->watch_root_cert()) { + watched_root_cert_name = options_->root_cert_name(); + } + absl::optional watched_identity_cert_name; + if (options_->watch_identity_pair()) { + watched_identity_cert_name = options_->identity_cert_name(); + } + // Server side won't use default system roots at any time. + distributor->WatchTlsCertificates(std::move(watcher_ptr), + watched_root_cert_name, + watched_identity_cert_name); +} + +TlsServerSecurityConnector::~TlsServerSecurityConnector() { + // Cancel all the watchers. + grpc_tls_certificate_distributor* distributor = + options_->certificate_distributor(); + if (distributor != nullptr) { + distributor->CancelTlsCertificatesWatch(certificate_watcher_); + } + if (server_handshaker_factory_ != nullptr) { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } + if (check_arg_ != nullptr) { + ClientAuthorizationCheckArgDestroy(check_arg_); + } +} + +void TlsServerSecurityConnector::add_handshakers( + const grpc_channel_args* args, grpc_pollset_set* /*interested_parties*/, + HandshakeManager* handshake_mgr) { + MutexLock lock(&mu_); + if (server_handshaker_factory_ != nullptr) { + // Instantiate TSI handshaker. + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( + server_handshaker_factory_, &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + handshake_mgr->Add(SecurityHandshakerCreate(tsi_hs, this, args)); + return; + } + // TODO(ZhenLian): Implement the logic(delegation to + // BlockOnInitialCredentialHandshaker) when certificates are not ready. + gpr_log(GPR_ERROR, "%s not supported yet.", + "Server BlockOnInitialCredentialHandshaker"); +} + +void TlsServerSecurityConnector::check_peer( + tsi_peer peer, grpc_endpoint* /*ep*/, + RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + grpc_error_handle error = grpc_ssl_check_alpn(&peer); + if (error != GRPC_ERROR_NONE) { + ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error); + tsi_peer_destruct(&peer); + return; + } + *auth_context = + grpc_ssl_peer_to_auth_context(&peer, GRPC_TLS_TRANSPORT_SECURITY_TYPE); + if (options_->server_verification_option() == GRPC_TLS_SERVER_VERIFICATION) { + /* Do the default host name check if specifying the target name. */ + error = internal::TlsCheckHostName("", &peer); + if (error != GRPC_ERROR_NONE) { + ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error); + tsi_peer_destruct(&peer); + return; + } + } + /* Do the custom client authorization check, if specified by the user. */ + const grpc_tls_server_authorization_check_config* config = + options_->server_authorization_check_config(); + /* If client authorization config is not null, use it to perform + * client authorization check. */ + if (config != nullptr) { + const tsi_peer_property* p = + tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); + if (p == nullptr) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing pem cert property."); + } else { + char* peer_pem = static_cast(gpr_zalloc(p->value.length + 1)); + memcpy(peer_pem, p->value.data, p->value.length); + GPR_ASSERT(check_arg_ != nullptr); + check_arg_->peer_cert = gpr_strdup(peer_pem); + check_arg_->target_name = gpr_strdup(""); + on_peer_checked_ = on_peer_checked; + gpr_check_free(peer_pem); + const tsi_peer_property* chain = tsi_peer_get_property_by_name( + &peer, TSI_X509_PEM_CERT_CHAIN_PROPERTY); + if (chain != nullptr) { + char* peer_pem_chain = + static_cast(gpr_zalloc(chain->value.length + 1)); + memcpy(peer_pem_chain, chain->value.data, chain->value.length); + check_arg_->peer_cert_full_chain = + check_arg_->peer_cert_full_chain == nullptr + ? gpr_strdup(peer_pem_chain) + : check_arg_->peer_cert_full_chain; + gpr_check_free(peer_pem_chain); + } + // TODO(zhenlian) - This should be cleaned up as part of the custom + // verification changes. Fill in the subject alternative names + std::vector subject_alternative_names; + for (size_t i = 0; i < peer.property_count; i++) { + const tsi_peer_property* prop = &peer.properties[i]; + if (strcmp(prop->name, + TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { + char* san = new char[prop->value.length + 1]; + memcpy(san, prop->value.data, prop->value.length); + san[prop->value.length] = '\0'; + subject_alternative_names.emplace_back(san); + } + } + if (check_arg_->subject_alternative_names != nullptr) { + for (size_t i = 0; i < check_arg_->subject_alternative_names_size; + ++i) { + delete[] check_arg_->subject_alternative_names[i]; + } + delete[] check_arg_->subject_alternative_names; + } + check_arg_->subject_alternative_names_size = + subject_alternative_names.size(); + if (subject_alternative_names.empty()) { + check_arg_->subject_alternative_names = nullptr; + } else { + check_arg_->subject_alternative_names = + new char*[check_arg_->subject_alternative_names_size]; + for (size_t i = 0; i < check_arg_->subject_alternative_names_size; + ++i) { + check_arg_->subject_alternative_names[i] = + subject_alternative_names[i]; + } + } + int callback_status = config->Schedule(check_arg_); + /* Client authorization check is handled asynchronously. */ + if (callback_status) { + tsi_peer_destruct(&peer); + return; + } + /* Client authorization check is handled synchronously. */ + error = ProcessClientAuthorizationCheckResult(check_arg_); + } + } + ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error); + tsi_peer_destruct(&peer); +} + +int TlsServerSecurityConnector::cmp( + const grpc_security_connector* other) const { + return server_security_connector_cmp( + static_cast(other)); +} + +void TlsServerSecurityConnector::TlsServerCertificateWatcher:: + OnCertificatesChanged(absl::optional root_certs, + absl::optional key_cert_pairs) { + GPR_ASSERT(security_connector_ != nullptr); + MutexLock lock(&security_connector_->mu_); + if (root_certs.has_value()) { + security_connector_->pem_root_certs_ = root_certs; + } + if (key_cert_pairs.has_value()) { + security_connector_->pem_key_cert_pair_list_ = std::move(key_cert_pairs); + } + bool root_being_watched = security_connector_->options_->watch_root_cert(); + bool root_has_value = security_connector_->pem_root_certs_.has_value(); + bool identity_being_watched = + security_connector_->options_->watch_identity_pair(); + bool identity_has_value = + security_connector_->pem_key_cert_pair_list_.has_value(); + if ((root_being_watched && root_has_value && identity_being_watched && + identity_has_value) || + (root_being_watched && root_has_value && !identity_being_watched) || + (!root_being_watched && identity_being_watched && identity_has_value)) { + if (security_connector_->UpdateHandshakerFactoryLocked() != + GRPC_SECURITY_OK) { + gpr_log(GPR_ERROR, "Update handshaker factory failed."); + } + } +} + +// TODO(ZhenLian): implement the logic to signal waiting handshakers once +// BlockOnInitialCredentialHandshaker is implemented. +void TlsServerSecurityConnector::TlsServerCertificateWatcher::OnError( + grpc_error_handle root_cert_error, grpc_error_handle identity_cert_error) { + if (root_cert_error != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, + "TlsServerCertificateWatcher getting root_cert_error: %s", + grpc_error_std_string(root_cert_error).c_str()); + } + if (identity_cert_error != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, + "TlsServerCertificateWatcher getting identity_cert_error: %s", + grpc_error_std_string(identity_cert_error).c_str()); + } + GRPC_ERROR_UNREF(root_cert_error); + GRPC_ERROR_UNREF(identity_cert_error); +} + +// TODO(ZhenLian): implement the logic to signal waiting handshakers once +// BlockOnInitialCredentialHandshaker is implemented. +grpc_security_status +TlsServerSecurityConnector::UpdateHandshakerFactoryLocked() { + /* Free the server handshaker factory if exists. */ + if (server_handshaker_factory_ != nullptr) { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } + // The identity certs on the server side shouldn't be empty. + GPR_ASSERT(pem_key_cert_pair_list_.has_value()); + GPR_ASSERT(!(*pem_key_cert_pair_list_).empty()); + std::string pem_root_certs; + if (pem_root_certs_.has_value()) { + // TODO(ZhenLian): update the underlying TSI layer to use C++ types like + // std::string and absl::string_view to avoid making another copy here. + pem_root_certs = std::string(*pem_root_certs_); + } + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr; + pem_key_cert_pairs = ConvertToTsiPemKeyCertPair(*pem_key_cert_pair_list_); + size_t num_key_cert_pairs = (*pem_key_cert_pair_list_).size(); + grpc_security_status status = grpc_ssl_tsi_server_handshaker_factory_init( + pem_key_cert_pairs, num_key_cert_pairs, + pem_root_certs.empty() ? nullptr : pem_root_certs.c_str(), + options_->cert_request_type(), + grpc_get_tsi_tls_version(options_->min_tls_version()), + grpc_get_tsi_tls_version(options_->max_tls_version()), + &server_handshaker_factory_); + /* Free memory. */ + grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pairs, + num_key_cert_pairs); + return status; +} + +namespace internal { + +grpc_error_handle TlsCheckHostName(const char* peer_name, + const tsi_peer* peer) { + /* Check the peer name if specified. */ + if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { + return GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("Peer name ", peer_name, " is not in peer certificate") + .c_str()); + } + return GRPC_ERROR_NONE; +} + +} // namespace internal + +} // namespace grpc_core diff --git a/sgx/grpc/v1.38.1/src/core/lib/security/security_connector/tls/tls_security_connector.h b/sgx/grpc/v1.38.1/src/core/lib/security/security_connector/tls/tls_security_connector.h new file mode 100644 index 000000000..cd830b9b7 --- /dev/null +++ b/sgx/grpc/v1.38.1/src/core/lib/security/security_connector/tls/tls_security_connector.h @@ -0,0 +1,267 @@ +/* + * + * Copyright 2018 gRPC 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. + * + */ + +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_TLS_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_TLS_SECURITY_CONNECTOR_H + +#include + +#include "src/core/lib/gprpp/sync.h" +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h" +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" + +#define GRPC_TLS_TRANSPORT_SECURITY_TYPE "tls" + +namespace grpc_core { + +// Channel security connector using TLS as transport security protocol. +class TlsChannelSecurityConnector final + : public grpc_channel_security_connector { + public: + // static factory method to create a TLS channel security connector. + static RefCountedPtr + CreateTlsChannelSecurityConnector( + RefCountedPtr channel_creds, + RefCountedPtr options, + RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache); + + TlsChannelSecurityConnector( + RefCountedPtr channel_creds, + RefCountedPtr options, + RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache); + + ~TlsChannelSecurityConnector() override; + + void add_handshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) override; + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override; + + void cancel_check_peer(grpc_closure* /*on_peer_checked*/, + grpc_error_handle error) override { + // TODO(ZhenLian): call verifier->cancel() once the verifier is ready. + GRPC_ERROR_UNREF(error); + } + + int cmp(const grpc_security_connector* other_sc) const override; + + bool check_call_host(absl::string_view host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error_handle* error) override; + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error_handle error) override; + + tsi_ssl_client_handshaker_factory* ClientHandshakerFactoryForTesting() { + MutexLock lock(&mu_); + return client_handshaker_factory_; + }; + + absl::optional RootCertsForTesting() { + MutexLock lock(&mu_); + return pem_root_certs_; + } + + absl::optional KeyCertPairListForTesting() { + MutexLock lock(&mu_); + return pem_key_cert_pair_list_; + } + + private: + // A watcher that watches certificate updates from + // grpc_tls_certificate_distributor. It will never outlive + // |security_connector_|. + class TlsChannelCertificateWatcher : public grpc_tls_certificate_distributor:: + TlsCertificatesWatcherInterface { + public: + explicit TlsChannelCertificateWatcher( + TlsChannelSecurityConnector* security_connector) + : security_connector_(security_connector) {} + void OnCertificatesChanged( + absl::optional root_certs, + absl::optional key_cert_pairs) override; + void OnError(grpc_error_handle root_cert_error, + grpc_error_handle identity_cert_error) override; + + private: + TlsChannelSecurityConnector* security_connector_ = nullptr; + }; + + // Updates |client_handshaker_factory_| when the certificates that + // |certificate_watcher_| is watching get updated. + grpc_security_status UpdateHandshakerFactoryLocked() + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); + + // gRPC-provided callback executed by application, which servers to bring the + // control back to gRPC core. + static void ServerAuthorizationCheckDone( + grpc_tls_server_authorization_check_arg* arg); + + // A util function to process server authorization check result. + static grpc_error_handle ProcessServerAuthorizationCheckResult( + grpc_tls_server_authorization_check_arg* arg); + + // A util function to create a server authorization check arg instance. + static grpc_tls_server_authorization_check_arg* + ServerAuthorizationCheckArgCreate(void* user_data); + + // A util function to destroy a server authorization check arg instance. + static void ServerAuthorizationCheckArgDestroy( + grpc_tls_server_authorization_check_arg* arg); + + RefCountedPtr options_; + grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface* + certificate_watcher_ = nullptr; + grpc_closure* on_peer_checked_ = nullptr; + std::string target_name_; + std::string overridden_target_name_; + grpc_tls_server_authorization_check_arg* check_arg_ = nullptr; + + Mutex mu_; + tsi_ssl_client_handshaker_factory* client_handshaker_factory_ + ABSL_GUARDED_BY(mu_) = nullptr; + tsi_ssl_session_cache* ssl_session_cache_ ABSL_GUARDED_BY(mu_) = nullptr; + absl::optional pem_root_certs_ ABSL_GUARDED_BY(mu_); + absl::optional pem_key_cert_pair_list_ + ABSL_GUARDED_BY(mu_); +}; + +// Server security connector using TLS as transport security protocol. +class TlsServerSecurityConnector final : public grpc_server_security_connector { + public: + // static factory method to create a TLS server security connector. + static RefCountedPtr + CreateTlsServerSecurityConnector( + RefCountedPtr server_creds, + RefCountedPtr options); + + TlsServerSecurityConnector( + RefCountedPtr server_creds, + RefCountedPtr options); + ~TlsServerSecurityConnector() override; + + void add_handshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) override; + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override; + + void cancel_check_peer(grpc_closure* /*on_peer_checked*/, + grpc_error_handle error) override { + // TODO(ZhenLian): call verifier->cancel() once the verifier is ready. + GRPC_ERROR_UNREF(error); + } + + int cmp(const grpc_security_connector* other) const override; + + tsi_ssl_server_handshaker_factory* ServerHandshakerFactoryForTesting() { + MutexLock lock(&mu_); + return server_handshaker_factory_; + }; + + const absl::optional& RootCertsForTesting() { + MutexLock lock(&mu_); + return pem_root_certs_; + } + + const absl::optional& KeyCertPairListForTesting() { + MutexLock lock(&mu_); + return pem_key_cert_pair_list_; + } + + private: + // A watcher that watches certificate updates from + // grpc_tls_certificate_distributor. It will never outlive + // |security_connector_|. + class TlsServerCertificateWatcher : public grpc_tls_certificate_distributor:: + TlsCertificatesWatcherInterface { + public: + explicit TlsServerCertificateWatcher( + TlsServerSecurityConnector* security_connector) + : security_connector_(security_connector) {} + void OnCertificatesChanged( + absl::optional root_certs, + absl::optional key_cert_pairs) override; + void OnError(grpc_error_handle root_cert_error, + grpc_error_handle identity_cert_error) override; + + private: + TlsServerSecurityConnector* security_connector_ = nullptr; + }; + + // Updates |server_handshaker_factory_| when the certificates that + // |certificate_watcher_| is watching get updated. + grpc_security_status UpdateHandshakerFactoryLocked() + ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); + + // gRPC-provided callback executed by application, which servers to bring the + // control back to gRPC core. + static void ClientAuthorizationCheckDone( + grpc_tls_server_authorization_check_arg* arg); + + // A util function to process server authorization check result. + static grpc_error_handle ProcessClientAuthorizationCheckResult( + grpc_tls_server_authorization_check_arg* arg); + + // A util function to create a server authorization check arg instance. + static grpc_tls_server_authorization_check_arg* + ClientAuthorizationCheckArgCreate(void* user_data); + + // A util function to destroy a server authorization check arg instance. + static void ClientAuthorizationCheckArgDestroy( + grpc_tls_server_authorization_check_arg* arg); + + RefCountedPtr options_; + + grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface* + certificate_watcher_ = nullptr; + grpc_closure* on_peer_checked_ = nullptr; + std::string target_name_ = "localhost"; + std::string overridden_target_name_= "localhost"; + grpc_tls_server_authorization_check_arg* check_arg_ = nullptr; + + Mutex mu_; + tsi_ssl_server_handshaker_factory* server_handshaker_factory_ + ABSL_GUARDED_BY(mu_) = nullptr; + absl::optional pem_root_certs_ ABSL_GUARDED_BY(mu_); + absl::optional pem_key_cert_pair_list_ + ABSL_GUARDED_BY(mu_); +}; + +// ---- Functions below are exposed for testing only ----------------------- +namespace internal { + +// TlsCheckHostName checks if |peer_name| matches the identity information +// contained in |peer|. This is AKA hostname check. +grpc_error_handle TlsCheckHostName(const char* peer_name, const tsi_peer* peer); + +} // namespace internal + +} // namespace grpc_core + +#endif // GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_TLS_SECURITY_CONNECTOR_H diff --git a/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_credentials.cc b/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_credentials.cc new file mode 100644 index 000000000..027fb961c --- /dev/null +++ b/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_credentials.cc @@ -0,0 +1,98 @@ +/* + * + * Copyright 2019 gRPC 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. + * + */ + +#include "sgx_ra_tls_utils.h" + +namespace grpc { +namespace sgx { + +/* +RA-TLS: on client, only need to register ra_tls_verify_callback() for cert verification + 1. extract SGX quote from "quote" OID extension from crt + 2. compare public key's hash from cert against quote's report_data + 3. prepare user-supplied verification parameter "allow outdated TCB" + 4. call into libsgx_dcap_quoteverify to verify ECDSA/based SGX quote + 5. verify all measurements from the SGX quote +*/ + +std::shared_ptr TlsCredentials(sgx_config sgx_cfg) { + grpc::sgx::CredentialsOptions options; + + // sgx certificate provide + credential_option_set_certificate_provider(options); + + // sgx certificate authorization check + ra_tls_verify_init(sgx_cfg); + credential_option_set_authorization_check(options); + + return grpc::experimental::TlsCredentials( + reinterpret_cast(options)); +}; + +std::shared_ptr TlsCredentials(const char* sgx_cfg_json) { + grpc::sgx::CredentialsOptions options; + + // sgx certificate provide + credential_option_set_certificate_provider(options); + + // sgx certificate authorization check + ra_tls_verify_init(sgx_cfg_json); + credential_option_set_authorization_check(options); + + return grpc::experimental::TlsCredentials( + reinterpret_cast(options)); +}; + +std::shared_ptr TlsServerCredentials(sgx_config sgx_cfg) { + grpc::sgx::CredentialsOptions options; + + // sgx certificate provide + credential_option_set_certificate_provider(options); + + // sgx certificate authorization check + ra_tls_verify_init(sgx_cfg); + credential_option_set_authorization_check(options); + + return grpc::experimental::TlsServerCredentials( + reinterpret_cast(options)); +}; + +std::shared_ptr TlsServerCredentials(const char* sgx_cfg_json) { + grpc::sgx::CredentialsOptions options; + + // sgx certificate provide + credential_option_set_certificate_provider(options); + + // sgx certificate authorization check + ra_tls_verify_init(sgx_cfg_json); + credential_option_set_authorization_check(options); + + return grpc::experimental::TlsServerCredentials( + reinterpret_cast(options)); +}; + +std::shared_ptr CreateSecureChannel( + string target_str, std::shared_ptr channel_creds) { + GPR_ASSERT(channel_creds.get() != nullptr); + auto channel_args = grpc::ChannelArguments(); + channel_args.SetSslTargetNameOverride("RATLS"); + return grpc::CreateCustomChannel(target_str, std::move(channel_creds), channel_args); +}; + +} // namespace sgx +} // namespace grpc diff --git a/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_options.cc b/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_options.cc new file mode 100644 index 000000000..e27976b0e --- /dev/null +++ b/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_options.cc @@ -0,0 +1,55 @@ +/* + * + * Copyright 2019 gRPC 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. + * + */ + +#include +#include +#include + +#include "absl/container/inlined_vector.h" +#include "src/cpp/common/tls_credentials_options_util.h" + +namespace grpc { +namespace sgx { + +void CredentialsOptions::set_verification_option( + grpc_tls_server_verification_option server_verification_option) { + grpc_tls_credentials_options* options = c_credentials_options(); + GPR_ASSERT(options != nullptr); + grpc_tls_credentials_options_set_server_verification_option( + options, server_verification_option); +} + +void CredentialsOptions::set_authorization_check_config( + std::shared_ptr config) { + grpc_tls_credentials_options* options = c_credentials_options(); + GPR_ASSERT(options != nullptr); + if (config != nullptr) { + grpc_tls_credentials_options_set_server_authorization_check_config( + options, config->c_config()); + } +} + +void CredentialsOptions::set_cert_request_type( + grpc_ssl_client_certificate_request_type cert_request_type) { + grpc_tls_credentials_options* options = c_credentials_options(); + GPR_ASSERT(options != nullptr); + grpc_tls_credentials_options_set_cert_request_type(options, cert_request_type); +} + +} // namespace sgx +} // namespace grpc diff --git a/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_utils.cc b/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_utils.cc new file mode 100644 index 000000000..5907669a2 --- /dev/null +++ b/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_utils.cc @@ -0,0 +1,490 @@ +/* + * + * Copyright 2019 gRPC 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. + * + */ + +#include "sgx_ra_tls_utils.h" + +namespace grpc { +namespace sgx { + +struct ra_tls_context _ctx_; + +bool hex_to_byte(const char *src, char *dst, size_t dst_size) { + if (strlen(src) < dst_size*2) { + return false; + } else { + for (auto i = 0; i < dst_size; i++) { + if (!isxdigit(src[i*2]) || !isxdigit(src[i*2+1])) { + return false; + } else { + sscanf(src+i*2, "%02hhx", dst+i); + } + } + return true; + } +}; + +void byte_to_hex(const char *src, char *dst, size_t src_size) { + for (auto i = 0; i < src_size; i++) { + sprintf(dst+i*2, "%02hhx", src[i]); + } +}; + +std::string byte_to_hex(const char *src, size_t src_size) { + char dst[src_size*2]; + memset(dst, 0, sizeof(dst)); + byte_to_hex(src, dst, src_size); + return std::string(dst); +}; + +library_engine::library_engine() : handle(nullptr), error(nullptr) {}; + +library_engine::library_engine(const char* file, int mode) : handle(nullptr), error(nullptr) { + this->open(file, mode); +} + +library_engine::~library_engine() { + this->close(); +} + +void library_engine::open(const char* file, int mode) { + this->close(); + handle = dlopen(file, mode); + error = dlerror(); + if (error != nullptr || handle == nullptr) { + throw std::runtime_error("dlopen " + std::string(file) + " error, " + std::string(error)); + } +} + +void library_engine::close() { + if (handle) { + dlclose(handle); + } + handle = nullptr; + error = nullptr; +} + +void* library_engine::get_func(const char* name) { + auto func = dlsym(handle, name); + error = dlerror(); + if (error != nullptr || func == nullptr) { + throw std::runtime_error("dlsym " + std::string(name) + " error, " + std::string(error)); + return nullptr; + } else { + return func; + } +} + +void* library_engine::get_handle() { + return handle; +} + +json_engine::json_engine() : handle(nullptr){}; + +json_engine::json_engine(const char *file) : handle(nullptr) +{ + this->open(file); +} + +json_engine::~json_engine() +{ + this->close(); +} + +bool json_engine::open(const char *file) +{ + if (!file) + { + grpc_printf("wrong json file path\n"); + return false; + } + + this->close(); + + auto file_ptr = fopen(file, "r"); + fseek(file_ptr, 0, SEEK_END); + auto length = ftell(file_ptr); + fseek(file_ptr, 0, SEEK_SET); + auto buffer = malloc(length + 1); + memset(buffer, 0, length); + fread(buffer, 1, length, file_ptr); + fclose(file_ptr); + + this->handle = cJSON_Parse((const char*)buffer); + + if (buffer) + { + free(buffer); + buffer = nullptr; + } + + if (this->handle) + { + return true; + } + else + { + grpc_printf("cjson open %s error: %s", file, cJSON_GetErrorPtr()); + return false; + } +} + +void json_engine::close() +{ + if (this->handle) + { + cJSON_Delete(this->handle); + this->handle = nullptr; + } +} + +cJSON *json_engine::get_handle() +{ + return this->handle; +} + +cJSON *json_engine::get_item(cJSON *obj, const char *item) +{ + return cJSON_GetObjectItem(obj, item); +}; + +bool json_engine::compare_item(cJSON *obj, const char *item) +{ + if (!obj || !cJSON_IsString(obj)){ + return false; + } + auto obj_item = obj->valuestring; + return strncmp(obj_item, item, std::min(strlen(item), strlen(obj_item))) == 0; +}; + +const char* json_engine::get_item_string(cJSON *obj, const char* item){ + auto item_json = get_item(obj, item); + return cJSON_IsString(item_json) ? item_json->valuestring : ""; +} + + +sgx_config parse_sgx_config_json(const char *file) +{ + class json_engine sgx_json(file); + struct sgx_config sgx_cfg; + + sgx_cfg.verify_in_enclave = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_in_enclave"), "on"); + sgx_cfg.verify_mr_enclave = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_mr_enclave"), "on"); + sgx_cfg.verify_mr_signer = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_mr_signer"), "on"); + sgx_cfg.verify_isv_prod_id = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_isv_prod_id"), "on"); + sgx_cfg.verify_isv_svn = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_isv_svn"), "on"); + + grpc_printf("|- verify_in_enclave: %s\n", sgx_cfg.verify_in_enclave ? "on" : "off"); + grpc_printf("|- verify_mr_enclave: %s\n", sgx_cfg.verify_mr_enclave ? "on" : "off"); + grpc_printf("|- verify_mr_signer: %s\n", sgx_cfg.verify_mr_signer ? "on" : "off"); + grpc_printf("|- verify_isv_prod_id: %s\n", sgx_cfg.verify_isv_prod_id ? "on" : "off"); + grpc_printf("|- verify_isv_svn: %s\n", sgx_cfg.verify_isv_svn ? "on" : "off"); + + auto objs = sgx_json.get_item(sgx_json.get_handle(), "sgx_mrs"); + auto obj_num = cJSON_GetArraySize(objs); + + sgx_cfg.sgx_mrs = std::vector(obj_num, sgx_measurement()); + for (auto i = 0; i < obj_num; i++) + { + auto obj = cJSON_GetArrayItem(objs, i); + grpc_printf(" |- expect measurement [%d]:\n", i + 1); + auto mr_enclave = sgx_json.get_item_string(obj, "mr_enclave"); + grpc_printf(" |- mr_enclave: %s\n", mr_enclave); + memset(sgx_cfg.sgx_mrs[i].mr_enclave, 0, sizeof(sgx_cfg.sgx_mrs[i].mr_enclave)); + auto res = hex_to_byte(mr_enclave, sgx_cfg.sgx_mrs[i].mr_enclave, sizeof(sgx_cfg.sgx_mrs[i].mr_enclave)); + if (!res){ + grpc_printf("mr_enclave invalid, %s\n", mr_enclave); + } + + auto mr_signer = sgx_json.get_item_string(obj, "mr_signer"); + grpc_printf(" |- mr_signer: %s\n", mr_signer); + memset(sgx_cfg.sgx_mrs[i].mr_signer, 0, sizeof(sgx_cfg.sgx_mrs[i].mr_signer)); + res = hex_to_byte(mr_signer, sgx_cfg.sgx_mrs[i].mr_signer, sizeof(sgx_cfg.sgx_mrs[i].mr_signer)); + if (!res){ + grpc_printf("mr_signer invalid, %s\n", mr_signer); + } + + auto isv_prod_id = sgx_json.get_item_string(obj, "isv_prod_id"); + grpc_printf(" |- isv_prod_id: %s\n", isv_prod_id); + sgx_cfg.sgx_mrs[i].isv_prod_id = strtoul(isv_prod_id ,nullptr, 10); + + auto isv_svn = sgx_json.get_item_string(obj, "isv_svn"); + grpc_printf(" |- isv_svn: %s\n", isv_svn); + sgx_cfg.sgx_mrs[i].isv_svn = strtoul(isv_svn ,nullptr, 10);; + }; + return sgx_cfg; +} + +int TlsAuthorizationCheck::Schedule(grpc::experimental::TlsServerAuthorizationCheckArg* arg) { + GPR_ASSERT(arg != nullptr); + + char der_crt[16000] = ""; + auto peer_cert_buf = arg->peer_cert(); + peer_cert_buf.copy(der_crt, peer_cert_buf.length(), 0); + + int ret = (*_ctx_.verify_callback_f)(reinterpret_cast(der_crt), 16000); + + if (ret != 0) { + grpc_printf("something went wrong while verifying quote, error: %s\n", mbedtls_high_level_strerr(ret)); + arg->set_success(0); + arg->set_status(GRPC_STATUS_UNAUTHENTICATED); + } else { + arg->set_success(1); + arg->set_status(GRPC_STATUS_OK); + } + return 0; /* synchronous check */ +}; + +void TlsAuthorizationCheck::Cancel(grpc::experimental::TlsServerAuthorizationCheckArg* arg) { + GPR_ASSERT(arg != nullptr); + arg->set_status(GRPC_STATUS_PERMISSION_DENIED); + arg->set_error_details("cancelled"); +}; + +bool ra_tls_verify_measurement(const char* mr_enclave, const char* mr_signer, + const char* isv_prod_id, const char* isv_svn) { + bool status = false; + auto & sgx_cfg = _ctx_.sgx_cfg; + for (auto & obj : sgx_cfg.sgx_mrs) { + status = true; + + if (status && sgx_cfg.verify_mr_enclave && \ + memcmp(obj.mr_enclave, mr_enclave, 32)) { + status = false; + } + + if (status && sgx_cfg.verify_mr_signer && \ + memcmp(obj.mr_signer, mr_signer, 32)) { + status = false; + } + + if (status && sgx_cfg.verify_isv_prod_id && \ + (obj.isv_prod_id != *(uint16_t*)isv_prod_id)) { + status = false; + } + + if (status && sgx_cfg.verify_isv_svn && \ + (obj.isv_svn != *(uint16_t*)isv_svn)) { + status = false; + } + + if (status) { + break; + } + } + return status; +} + +int ra_tls_verify_measurements_callback(const char* mr_enclave, const char* mr_signer, + const char* isv_prod_id, const char* isv_svn) { + std::lock_guard lock(_ctx_.mtx); + bool status = false; + try { + assert(mr_enclave && mr_signer && isv_prod_id && isv_svn); + + status = ra_tls_verify_measurement(mr_enclave, mr_signer, isv_prod_id, isv_svn); + + grpc_printf("remote sgx measurements\n"); + grpc_printf(" |- mr_enclave : %s\n", byte_to_hex(mr_enclave, 32).c_str()); + grpc_printf(" |- mr_signer : %s\n", byte_to_hex(mr_signer, 32).c_str()); + grpc_printf(" |- isv_prod_id : %hu\n", *((uint16_t*)isv_prod_id)); + grpc_printf(" |- isv_svn : %hu\n", *((uint16_t*)isv_svn)); + + if (status) { + grpc_printf(" |- verify result : success\n"); + } else { + grpc_printf(" |- verify result : failed\n"); + } + } catch (...) { + grpc_printf("unable to verify measurement!"); + } + + fflush(stdout); + return status ? 0 : -1; +} + +void ra_tls_verify_init() { + if (_ctx_.sgx_cfg.verify_in_enclave) { + if (!_ctx_.verify_lib.get_handle()) { + _ctx_.verify_lib.open("libra_tls_verify_dcap_gramine.so", RTLD_LAZY); + } + } else { + if (!_ctx_.sgx_urts_lib.get_handle()) { + _ctx_.sgx_urts_lib.open("libsgx_urts.so", RTLD_NOW | RTLD_GLOBAL); + } + if (!_ctx_.verify_lib.get_handle()) { + _ctx_.verify_lib.open("libra_tls_verify_dcap.so", RTLD_LAZY); + } + } + + if (!_ctx_.verify_callback_f) { + _ctx_.verify_callback_f = + reinterpret_cast( + _ctx_.verify_lib.get_func("ra_tls_verify_callback_der")); + } + + auto ra_tls_set_measurement_callback_f = + reinterpret_cast( + _ctx_.verify_lib.get_func("ra_tls_set_measurement_callback")); + (*ra_tls_set_measurement_callback_f)(ra_tls_verify_measurements_callback); +} + +void ra_tls_verify_init(const char* file) { + std::lock_guard lock(_ctx_.mtx); + _ctx_.sgx_cfg = parse_sgx_config_json(file); + ra_tls_verify_init(); +} + +void ra_tls_verify_init(sgx_config sgx_cfg) { + std::lock_guard lock(_ctx_.mtx); + _ctx_.sgx_cfg = sgx_cfg; + ra_tls_verify_init(); +} + +std::vector ra_tls_get_key_cert() { + if (!_ctx_.attest_lib.get_handle()) { + _ctx_.attest_lib.open("libra_tls_attest.so", RTLD_LAZY); + } + + auto ra_tls_create_key_and_crt_f = + reinterpret_cast( + _ctx_.attest_lib.get_func("ra_tls_create_key_and_crt")); + + std::string error = ""; + std::vector key_cert; + + mbedtls_x509_crt srvcert; + mbedtls_pk_context pkey; + + mbedtls_x509_crt_init(&srvcert); + mbedtls_pk_init(&pkey); + + int ret = (*ra_tls_create_key_and_crt_f)(&pkey, &srvcert); + if (ret != 0) { + error = "ra_tls_get_key_cert->ra_tls_create_key_and_crt_f"; + goto out; + } + + unsigned char private_key_pem[16000], cert_pem[16000]; + size_t olen; + + ret = mbedtls_pk_write_key_pem(&pkey, private_key_pem, 16000); + if (ret != 0) { + error = "ra_tls_get_key_cert->mbedtls_pk_write_key_pem"; + goto out; + } + + ret = mbedtls_pem_write_buffer(PEM_BEGIN_CRT, PEM_END_CRT, + srvcert.raw.p, srvcert.raw.len, + cert_pem, 16000, &olen); + if (ret != 0) { + error = "ra_tls_get_key_cert->mbedtls_pem_write_buffer"; + goto out; + }; + + key_cert.emplace_back(std::string((char*) private_key_pem)); + key_cert.emplace_back(std::string((char*) cert_pem)); + + // grpc_printf("Server key:\n%s\n", private_key_pem); + // grpc_printf("Server crt:\n%s\n", cert_pem); + + out: + mbedtls_x509_crt_free(&srvcert); + mbedtls_pk_free(&pkey); + + if (ret != 0) { + throw std::runtime_error( + std::string((error + std::string(" failed: %s\n")).c_str(), mbedtls_high_level_strerr(ret))); + } + + return key_cert; +}; + +int ra_tls_auth_check_schedule(void* /* confiuser_data */, + grpc_tls_server_authorization_check_arg* arg) { + char der_crt[16000] = ""; + memcpy(der_crt, arg->peer_cert, strlen(arg->peer_cert)); + + // char der_crt[16000] = TEST_CRT_PEM; + // grpc_printf("%s\n", der_crt); + + int ret = (*_ctx_.verify_callback_f)(reinterpret_cast(der_crt), 16000); + + if (ret != 0) { + grpc_printf("something went wrong while verifying quote, error: %s\n", mbedtls_high_level_strerr(ret)); + arg->success = 0; + arg->status = GRPC_STATUS_UNAUTHENTICATED; + } else { + arg->success = 1; + arg->status = GRPC_STATUS_OK; + } + return 0; /* synchronous check */ +} + +std::vector get_identity_key_cert_pairs( + std::vector key_cert) { + grpc::experimental::IdentityKeyCertPair key_cert_pair; + key_cert_pair.private_key = key_cert[0]; + key_cert_pair.certificate_chain = key_cert[1]; + std::vector identity_key_cert_pairs; + identity_key_cert_pairs.emplace_back(key_cert_pair); + return identity_key_cert_pairs; +} + +void credential_option_set_authorization_check( + grpc::sgx::CredentialsOptions& options) { + std::lock_guard lock(_ctx_.mtx); + + _ctx_.cache.id++; + + auto authorization_check = _ctx_.cache.authorization_check.insert({ + _ctx_.cache.id, std::make_shared() + }).first; + + auto authorization_check_config = _ctx_.cache.authorization_check_config.insert({ + _ctx_.cache.id, + std::make_shared( + authorization_check->second) + }).first; + + options.set_authorization_check_config(authorization_check_config->second); + options.set_verification_option(GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION); +} + +void credential_option_set_certificate_provider(grpc::sgx::CredentialsOptions& options) { + std::lock_guard lock(_ctx_.mtx); + + _ctx_.cache.id++; + + auto certificate_provider = _ctx_.cache.certificate_provider.insert({ + _ctx_.cache.id, std::make_shared( + get_identity_key_cert_pairs(ra_tls_get_key_cert())) + }).first; + + options.set_certificate_provider(certificate_provider->second); + // options.watch_root_certs(); + options.watch_identity_key_cert_pairs(); + options.set_cert_request_type(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY); + options.set_root_cert_name(""); + options.set_identity_cert_name(""); +} + +} // namespace sgx +} // namespace grpc diff --git a/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_utils.h b/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_utils.h new file mode 100644 index 000000000..f2a897a4b --- /dev/null +++ b/sgx/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_utils.h @@ -0,0 +1,314 @@ +/* + * + * Copyright 2019 gRPC 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. + * + */ + +#ifndef SGX_RA_TLS_UTILS_H +#define SGX_RA_TLS_UTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define grpc_printf printf +#define grpc_fprintf fprintf + +#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" +#define PEM_END_CRT "-----END CERTIFICATE-----\n" + +namespace grpc { +namespace sgx { + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class library_engine { + public: + library_engine(); + + library_engine(const char*, int); + + ~library_engine(); + + void open(const char*, int); + + void close(); + + void* get_func(const char*); + + void* get_handle(); + + private: + void* handle; + char* error; +}; + +class json_engine +{ +public: + json_engine(); + + json_engine(const char *); + + ~json_engine(); + + bool open(const char *); + + void close(); + + cJSON *get_handle(); + + cJSON *get_item(cJSON *obj, const char *item); + + bool compare_item(cJSON *obj, const char *item); + + const char* get_item_string(cJSON *obj, const char* item); + +private: + cJSON *handle; +}; + +class TlsAuthorizationCheck + : public grpc::experimental::TlsServerAuthorizationCheckInterface { + int Schedule(grpc::experimental::TlsServerAuthorizationCheckArg* arg) override; + + void Cancel(grpc::experimental::TlsServerAuthorizationCheckArg* arg) override; +}; + +struct sgx_measurement { + char mr_enclave[32]; + char mr_signer[32]; + uint16_t isv_prod_id; + uint16_t isv_svn; +}; + +struct sgx_config { + bool verify_in_enclave = true; + bool verify_mr_enclave = true; + bool verify_mr_signer = true; + bool verify_isv_prod_id = true; + bool verify_isv_svn = true; + std::vector sgx_mrs; +}; + +struct ra_tls_cache { + int id = 0; + std::unordered_map< + int, std::shared_ptr + > certificate_provider; + std::unordered_map< + int, std::shared_ptr + > authorization_check; + std::unordered_map< + int, std::shared_ptr + > authorization_check_config; +}; + +struct ra_tls_context { + std::mutex mtx; + struct sgx_config sgx_cfg; + struct ra_tls_cache cache; + class library_engine attest_lib; + class library_engine verify_lib; + class library_engine sgx_urts_lib; + int (*verify_callback_f)(uint8_t* der_crt, size_t der_crt_size) = nullptr; +}; + +sgx_config parse_sgx_config_json(const char* file); + +bool ra_tls_verify_measurement(const char* mr_enclave, const char* mr_signer, + const char* isv_prod_id, const char* isv_svn); + +int ra_tls_verify_measurements_callback(const char* mr_enclave, const char* mr_signer, + const char* isv_prod_id, const char* isv_svn); + +void ra_tls_verify_init(); + +void ra_tls_verify_init(sgx_config sgx_cfg); + +void ra_tls_verify_init(const char* config_json); + +std::vector ra_tls_get_key_cert(); + +std::vector get_identity_key_cert_pairs(std::vector key_cert); + +void credential_option_set_certificate_provider(grpc::sgx::CredentialsOptions& options); + +void credential_option_set_authorization_check(grpc::sgx::CredentialsOptions& options); + +} // namespace sgx +} // namespace grpc + +/* +// Format of pem crt +#define TEST_CRT_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIW4TCCFUmgAwIBAgIBATANBgkqhkiG9w0BAQsFADA6MQ4wDAYDVQQDDAVSQVRM\r\n" \ + "UzEbMBkGA1UECgwSR3JhcGhlbmVEZXZlbG9wZXJzMQswCQYDVQQGEwJVUzAeFw0w\r\n" \ + "MTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMDoxDjAMBgNVBAMMBVJBVExTMRsw\r\n" \ + "GQYDVQQKDBJHcmFwaGVuZURldmVsb3BlcnMxCzAJBgNVBAYTAlVTMIIBojANBgkq\r\n" \ + "hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA1Yvii4iVMKHLGHFxtjagJEaNYuli0tSZ\r\n" \ + "Gfqgq+BLILF7mcDaGGF3X9wWUuu+xVP8N1s48+uQ6Ki5/fQ59vzqXXOS6LG7Apkq\r\n" \ + "R9rstlRscnm9DnYeT7Nri8AXexL0RTqisbgRn8KLIqquNbmV7TArO7jWUftPsjlA\r\n" \ + "K968gKbI+qQ+FQPiho3yLdPdRg5pip6cKeHrjT7629JoGGCDVECaGVgwqYiBcYyp\r\n" \ + "oVCZmGemGOee30tymfrxKWLUIqov5PNvRNF0KvTVYMldebXnn4IOJtJM15vvAZwT\r\n" \ + "aKgCA14JrRrOPfjSd4JDbzQSg+ais2dveDOatvuWKNP9MxwNiWAcryMXkklruiFu\r\n" \ + "clFXYr376Bg5G3WOGSss0zN4Qs0lljdtaaA7GCNuI6NDPuXjX8IqO2ATbfyCwM1l\r\n" \ + "vcgNtrmT4hDTW9CmlLOZRFeki+n4YqbXDx/85UWwDKg0mrwIt+2LUv44t3dPuvIW\r\n" \ + "XImeFxQkDg4mFoXsgXcz7jIQKGceTs3/AgMBAAGjghLwMIIS7DAJBgNVHRMEAjAA\r\n" \ + "MB0GA1UdDgQWBBTA+Ea+oNAjPIT4F7uhg7Dwp9JMYjAfBgNVHSMEGDAWgBTA+Ea+\r\n" \ + "oNAjPIT4F7uhg7Dwp9JMYjCCEp0GCwYJKoZIhvhNijkGBIISjAMAAgAAAAAABgAL\r\n" \ + "AJOacjP3nEyplAoNs5V/Bgc5qzHmdaA6pmT8XGeFZK9YAAAAAAMDBAb//wAAAAAA\r\n" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAA5wIA\r\n" \ + "AAAAAADR0so9p0O1cu0/ZkZk4f8RDqyZE8rryjjwNOyagqG9GAAAAAAAAAAAAAAA\r\n" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAdfredRISu8eqkT+CyQPI8j7f/+CZQUpvLSAg\r\n" \ + "e1PrnbsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAQOeu3WxZqxSQv2BnBSRk9S35u5U433tVBFyf\r\n" \ + "dOLbemcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANgQAADyVRDyFJOE\r\n" \ + "h8UoHzA1lXwtxfqCiltBzLQqH2DRfRLJlnO2CqfWFUgVNM2EHFwNGxJLagJOoV/U\r\n" \ + "0dojT5dZ6N4EYPG9Ekgrv1yBb8uIvGg3PEASXEEA4AGEM8YCbdiSH1lrcg8DhyIl\r\n" \ + "nBQXjcdFKa8FPRHEvGkxbPC7AENChemu/gMDBAb//wAAAAAAAAAAAAAAAAAAAAAA\r\n" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUAAAAAAAAA5wAAAAAAAABcYGk7k4JS\r\n" \ + "A21jz4CdrQXSqh3NGk4N3/kRUTC62iQmPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n" \ + "AAAAAAAAAAAAjE9XddeWUD6WE393xoqCmgBWrI3tcBQLCBsJRJDFe/8AAAAAAAAA\r\n" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAYAAAAA\r\n" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n" \ + "AAAAAAAAAAAAaHHu8fwO94iKd+Nd/nnDc6cn0VlfWZEbRVdnqqL2YLYAAAAAAAAA\r\n" \ + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADLk4a0E8J+eE/tZxID53/DUJP6E+0g\r\n" \ + "4v4HZmmBo2Gd4sOZLg0/c+1j+BRDmFc3yL60o9kbzWX/uGTQ9OGZh1ggAAABAgME\r\n" \ + "BQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fBQBwDgAALS0tLS1CRUdJTiBDRVJU\r\n" \ + "SUZJQ0FURS0tLS0tCk1JSUU5VENDQkp1Z0F3SUJBZ0lWQU00ZGtCODhoazRvTm1G\r\n" \ + "OTQvVi9vMG1IWUVXL01Bb0dDQ3FHU000OUJBTUNNSEF4SWpBZ0JnTlYKQkFNTUdV\r\n" \ + "bHVkR1ZzSUZOSFdDQlFRMHNnVUd4aGRHWnZjbTBnUTBFeEdqQVlCZ05WQkFvTUVV\r\n" \ + "bHVkR1ZzSUVOdmNuQnZjbUYwYVc5dQpNUlF3RWdZRFZRUUhEQXRUWVc1MFlTQkRi\r\n" \ + "R0Z5WVRFTE1Ba0dBMVVFQ0F3Q1EwRXhDekFKQmdOVkJBWVRBbFZUTUI0WERUSXhN\r\n" \ + "RGN5Ck1UQTJNRE15T0ZvWERUSTRNRGN5TVRBMk1ETXlPRm93Y0RFaU1DQUdBMVVF\r\n" \ + "QXd3WlNXNTBaV3dnVTBkWUlGQkRTeUJEWlhKMGFXWnAKWTJGMFpURWFNQmdHQTFV\r\n" \ + "RUNnd1JTVzUwWld3Z1EyOXljRzl5WVhScGIyNHhGREFTQmdOVkJBY01DMU5oYm5S\r\n" \ + "aElFTnNZWEpoTVFzdwpDUVlEVlFRSURBSkRRVEVMTUFrR0ExVUVCaE1DVlZNd1dU\r\n" \ + "QVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTT3Rwbk83K3FICmJYL2c4\r\n" \ + "WXN1TE56TzBYRGJMek0xQ3RCakJFK3Q5UG02bnV4aXFkVEtHV3grVXZEV0twUUdR\r\n" \ + "WTVZOFdqdWhxV3k1Tk1EOHNzbEFDbmIKbzRJREVEQ0NBd3d3SHdZRFZSMGpCQmd3\r\n" \ + "Rm9BVVdTUFRwMHFvWTFRdU9YQ3Q0QThISzFja0tyY3did1lEVlIwZkJHZ3daakJr\r\n" \ + "b0dLZwpZSVplYUhSMGNITTZMeTl6WW5ndVlYQnBMblJ5ZFhOMFpXUnpaWEoyYVdO\r\n" \ + "bGN5NXBiblJsYkM1amIyMHZjMmQ0TDJObGNuUnBabWxqCllYUnBiMjR2ZGpNdmNH\r\n" \ + "TnJZM0pzUDJOaFBYQnNZWFJtYjNKdEptVnVZMjlrYVc1blBXUmxjakFkQmdOVkhR\r\n" \ + "NEVGZ1FVejZ0Q2p3RWYKUGlqcnVMeGFpdTNya204cGVkMHdEZ1lEVlIwUEFRSC9C\r\n" \ + "QVFEQWdiQU1Bd0dBMVVkRXdFQi93UUNNQUF3Z2dJNUJna3Foa2lHK0UwQgpEUUVF\r\n" \ + "Z2dJcU1JSUNKakFlQmdvcWhraUcrRTBCRFFFQkJCQUtpeHJXSTRNSk5VMkNXc2xj\r\n" \ + "bnJQdU1JSUJZd1lLS29aSWh2aE5BUTBCCkFqQ0NBVk13RUFZTEtvWklodmhOQVEw\r\n" \ + "QkFnRUNBUU13RUFZTEtvWklodmhOQVEwQkFnSUNBUU13RUFZTEtvWklodmhOQVEw\r\n" \ + "QkFnTUMKQVFBd0VBWUxLb1pJaHZoTkFRMEJBZ1FDQVFBd0VBWUxLb1pJaHZoTkFR\r\n" \ + "MEJBZ1VDQVFBd0VBWUxLb1pJaHZoTkFRMEJBZ1lDQVFBdwpFQVlMS29aSWh2aE5B\r\n" \ + "UTBCQWdjQ0FRQXdFQVlMS29aSWh2aE5BUTBCQWdnQ0FRQXdFQVlMS29aSWh2aE5B\r\n" \ + "UTBCQWdrQ0FRQXdFQVlMCktvWklodmhOQVEwQkFnb0NBUUF3RUFZTEtvWklodmhO\r\n" \ + "QVEwQkFnc0NBUUF3RUFZTEtvWklodmhOQVEwQkFnd0NBUUF3RUFZTEtvWkkKaHZo\r\n" \ + "TkFRMEJBZzBDQVFBd0VBWUxLb1pJaHZoTkFRMEJBZzRDQVFBd0VBWUxLb1pJaHZo\r\n" \ + "TkFRMEJBZzhDQVFBd0VBWUxLb1pJaHZoTgpBUTBCQWhBQ0FRQXdFQVlMS29aSWh2\r\n" \ + "aE5BUTBCQWhFQ0FRb3dId1lMS29aSWh2aE5BUTBCQWhJRUVBTURBQUFBQUFBQUFB\r\n" \ + "QUFBQUFBCkFBQXdFQVlLS29aSWh2aE5BUTBCQXdRQ0FBQXdGQVlLS29aSWh2aE5B\r\n" \ + "UTBCQkFRR0VHQnFBQUFBTUE4R0NpcUdTSWI0VFFFTkFRVUsKQVFFd0hnWUtLb1pJ\r\n" \ + "aHZoTkFRMEJCZ1FRdHlVMjN6NGdKMWxOSGhGQmdPMmVkakJFQmdvcWhraUcrRTBC\r\n" \ + "RFFFSE1EWXdFQVlMS29aSQpodmhOQVEwQkJ3RUJBZjh3RUFZTEtvWklodmhOQVEw\r\n" \ + "QkJ3SUJBZjh3RUFZTEtvWklodmhOQVEwQkJ3TUJBZjh3Q2dZSUtvWkl6ajBFCkF3\r\n" \ + "SURTQUF3UlFJaEFJZGN3UmZyUmNiL1E1dmpqUVVydTAwR3dyT3F4M09UcWx1MWN1\r\n" \ + "eGwwMjZEQWlCVHg5RFBleTF3TDJ3L1JsbXoKd0tUc2JaUENSdTMvQ2RFTllhWUFy\r\n" \ + "L2JiMnc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tLS0tLS1CRUdJTiBDRVJU\r\n" \ + "SUZJQ0FURS0tLS0tCk1JSUNtakNDQWtDZ0F3SUJBZ0lVV1NQVHAwcW9ZMVF1T1hD\r\n" \ + "dDRBOEhLMWNrS3Jjd0NnWUlLb1pJemowRUF3SXcKYURFYU1CZ0dBMVVFQXd3UlNX\r\n" \ + "NTBaV3dnVTBkWUlGSnZiM1FnUTBFeEdqQVlCZ05WQkFvTUVVbHVkR1ZzSUVOdgpj\r\n" \ + "bkJ2Y21GMGFXOXVNUlF3RWdZRFZRUUhEQXRUWVc1MFlTQkRiR0Z5WVRFTE1Ba0dB\r\n" \ + "MVVFQ0F3Q1EwRXhDekFKCkJnTlZCQVlUQWxWVE1CNFhEVEU1TVRBek1URXlNek0w\r\n" \ + "TjFvWERUTTBNVEF6TVRFeU16TTBOMW93Y0RFaU1DQUcKQTFVRUF3d1pTVzUwWld3\r\n" \ + "Z1UwZFlJRkJEU3lCUWJHRjBabTl5YlNCRFFURWFNQmdHQTFVRUNnd1JTVzUwWld3\r\n" \ + "ZwpRMjl5Y0c5eVlYUnBiMjR4RkRBU0JnTlZCQWNNQzFOaGJuUmhJRU5zWVhKaE1R\r\n" \ + "c3dDUVlEVlFRSURBSkRRVEVMCk1Ba0dBMVVFQmhNQ1ZWTXdXVEFUQmdjcWhrak9Q\r\n" \ + "UUlCQmdncWhrak9QUU1CQndOQ0FBUXdwK0xjK1RVQnRnMUgKK1U4SklzTXNiakhq\r\n" \ + "Q2tUdFhiOGpQTTZyMmRodTl6SWJsaERaN0lOZnF0M0l4OFhjRktEOGswTkVYcmta\r\n" \ + "NjZxSgpYYTFLekxJS280Ry9NSUc4TUI4R0ExVWRJd1FZTUJhQUZPbm9SRkpUTmx4\r\n" \ + "TEdKb1IvRU1ZTEtYY0lJQklNRllHCkExVWRId1JQTUUwd1M2QkpvRWVHUldoMGRI\r\n" \ + "QnpPaTh2YzJKNExXTmxjblJwWm1sallYUmxjeTUwY25WemRHVmsKYzJWeWRtbGpa\r\n" \ + "WE11YVc1MFpXd3VZMjl0TDBsdWRHVnNVMGRZVW05dmRFTkJMbVJsY2pBZEJnTlZI\r\n" \ + "UTRFRmdRVQpXU1BUcDBxb1kxUXVPWEN0NEE4SEsxY2tLcmN3RGdZRFZSMFBBUUgv\r\n" \ + "QkFRREFnRUdNQklHQTFVZEV3RUIvd1FJCk1BWUJBZjhDQVFBd0NnWUlLb1pJemow\r\n" \ + "RUF3SURTQUF3UlFJaEFKMXErRlR6K2dVdVZmQlF1Q2dKc0ZyTDJUVFMKZTFhQlo1\r\n" \ + "M081MlRqRmllNkFpQXJpUGFSYWhVWDlPYTlrR0xsQWNoV1hLVDZqNFJXU1I1MEJx\r\n" \ + "aHJOM1VUNEE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4g\r\n" \ + "Q0VSVElGSUNBVEUtLS0tLQpNSUlDbERDQ0FqbWdBd0lCQWdJVkFPbm9SRkpUTmx4\r\n" \ + "TEdKb1IvRU1ZTEtYY0lJQklNQW9HQ0NxR1NNNDlCQU1DCk1HZ3hHakFZQmdOVkJB\r\n" \ + "TU1FVWx1ZEdWc0lGTkhXQ0JTYjI5MElFTkJNUm93R0FZRFZRUUtEQkZKYm5SbGJD\r\n" \ + "QkQKYjNKd2IzSmhkR2x2YmpFVU1CSUdBMVVFQnd3TFUyRnVkR0VnUTJ4aGNtRXhD\r\n" \ + "ekFKQmdOVkJBZ01Ba05CTVFzdwpDUVlEVlFRR0V3SlZVekFlRncweE9URXdNekV3\r\n" \ + "T1RRNU1qRmFGdzAwT1RFeU16RXlNelU1TlRsYU1HZ3hHakFZCkJnTlZCQU1NRVVs\r\n" \ + "dWRHVnNJRk5IV0NCU2IyOTBJRU5CTVJvd0dBWURWUVFLREJGSmJuUmxiQ0JEYjNK\r\n" \ + "d2IzSmgKZEdsdmJqRVVNQklHQTFVRUJ3d0xVMkZ1ZEdFZ1EyeGhjbUV4Q3pBSkJn\r\n" \ + "TlZCQWdNQWtOQk1Rc3dDUVlEVlFRRwpFd0pWVXpCWk1CTUdCeXFHU000OUFnRUdD\r\n" \ + "Q3FHU000OUF3RUhBMElBQkUvNkQvMVdITnJXd1BtTk1JeUJLTVc1Cko2SnpNc2pv\r\n" \ + "NnhQMnZrSzFjZFpHYjFQR1JQL0MvOEVDZ2lEa21rbG16d0x6TGkrMDAwbTdMTHJ0\r\n" \ + "S0pBM29DMmoKZ2I4d2did3dId1lEVlIwakJCZ3dGb0FVNmVoRVVsTTJYRXNZbWhI\r\n" \ + "OFF4Z3NwZHdnZ0Vnd1ZnWURWUjBmQkU4dwpUVEJMb0VtZ1I0WkZhSFIwY0hNNkx5\r\n" \ + "OXpZbmd0WTJWeWRHbG1hV05oZEdWekxuUnlkWE4wWldSelpYSjJhV05sCmN5NXBi\r\n" \ + "blJsYkM1amIyMHZTVzUwWld4VFIxaFNiMjkwUTBFdVpHVnlNQjBHQTFVZERnUVdC\r\n" \ + "QlRwNkVSU1V6WmMKU3hpYUVmeERHQ3lsM0NDQVNEQU9CZ05WSFE4QkFmOEVCQU1D\r\n" \ + "QVFZd0VnWURWUjBUQVFIL0JBZ3dCZ0VCL3dJQgpBVEFLQmdncWhrak9QUVFEQWdO\r\n" \ + "SkFEQkdBaUVBenc5emRVaVVIUE1VZDBDNG14NDFqbEZaa3JNM3k1ZjFsZ25WCk83\r\n" \ + "RmJqT29DSVFDb0d0VW1UNGNYdDdWK3lTSGJKOEhvYjlBYW5wdlhOSDFFUisvZ1pG\r\n" \ + "K29wUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KMA0GCSqGSIb3DQEBCwUA\r\n" \ + "A4IBgQCuYf+3FXNepEjTlmcaXn35w3Oq9ge+We0YsO8y/dfI4S4AU5Vo8J5xkr+M\r\n" \ + "ZrJYrJqsSNmSiB94fQQ3Z9drRiS2pqwG+qSDjM/7oU+54bcFesSiZwhcxEAcTYae\r\n" \ + "Etss/L8vuqKyt+jHxnRE74F+a38hmqhcYV84K+zNwaxG6H5fsj5Qa3Nrdrx7UDbO\r\n" \ + "8wvmof8+4CisZRvVbStAebhHYQNYmgt+DdF2FxgGtxiZR8DEtWI94gxQNDXBeoGv\r\n" \ + "ixBQ3WfxclWN0Iktar+Us97LopLH0t39K+l9D7lm/vkjZV/hTSGyOOJBiIkfmr2K\r\n" \ + "3U5b3mn5eqrAZq48K8oRqsdfj2CH30sB7yz1MQeI3rPKb+uT5tTn9fuIOcfThiCt\r\n" \ + "woMWzk9xW/VkghBlMl1YCXzQfOhAr83/fWczfKx/AmZ7C9/OgYJ029/CPqTGzLqV\r\n" \ + "LQHAvnx5bWCP3h0YazM6SqmtqKHXGBJogT4ZHo1ZsN3C6kj9vpFQmpNZ1R78KJB9\r\n" \ + "EJaIecY=\r\n" \ + "-----END CERTIFICATE-----\r\n" \ +*/ + +#endif // SGX_RA_TLS_UTILS_H diff --git a/sgx/grpc/v1.38.1/src/python/grpcio/grpc/__init__.py b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/__init__.py new file mode 100644 index 000000000..5395f5fdb --- /dev/null +++ b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/__init__.py @@ -0,0 +1,2211 @@ +# Copyright 2015-2016 gRPC 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. +"""gRPC's Python API.""" + +import abc +import contextlib +import enum +import logging +import sys +import six + +from grpc._cython import cygrpc as _cygrpc +from grpc import _compression + +logging.getLogger(__name__).addHandler(logging.NullHandler()) + +try: + from grpc._grpcio_metadata import __version__ +except ImportError: + __version__ = "dev0" + +############################## Future Interface ############################### + + +class FutureTimeoutError(Exception): + """Indicates that a method call on a Future timed out.""" + + +class FutureCancelledError(Exception): + """Indicates that the computation underlying a Future was cancelled.""" + + +class Future(six.with_metaclass(abc.ABCMeta)): + """A representation of a computation in another control flow. + + Computations represented by a Future may be yet to be begun, + may be ongoing, or may have already completed. + """ + + @abc.abstractmethod + def cancel(self): + """Attempts to cancel the computation. + + This method does not block. + + Returns: + bool: + Returns True if the computation was canceled. + + Returns False under all other circumstances, for example: + + 1. computation has begun and could not be canceled. + 2. computation has finished + 3. computation is scheduled for execution and it is impossible + to determine its state without blocking. + """ + raise NotImplementedError() + + @abc.abstractmethod + def cancelled(self): + """Describes whether the computation was cancelled. + + This method does not block. + + Returns: + bool: + Returns True if the computation was cancelled before its result became + available. + + Returns False under all other circumstances, for example: + + 1. computation was not cancelled. + 2. computation's result is available. + """ + raise NotImplementedError() + + @abc.abstractmethod + def running(self): + """Describes whether the computation is taking place. + + This method does not block. + + Returns: + Returns True if the computation is scheduled for execution or + currently executing. + + Returns False if the computation already executed or was cancelled. + """ + raise NotImplementedError() + + @abc.abstractmethod + def done(self): + """Describes whether the computation has taken place. + + This method does not block. + + Returns: + bool: + Returns True if the computation already executed or was cancelled. + Returns False if the computation is scheduled for execution or + currently executing. + This is exactly opposite of the running() method's result. + """ + raise NotImplementedError() + + @abc.abstractmethod + def result(self, timeout=None): + """Returns the result of the computation or raises its exception. + + This method may return immediately or may block. + + Args: + timeout: The length of time in seconds to wait for the computation to + finish or be cancelled. If None, the call will block until the + computations's termination. + + Returns: + The return value of the computation. + + Raises: + FutureTimeoutError: If a timeout value is passed and the computation + does not terminate within the allotted time. + FutureCancelledError: If the computation was cancelled. + Exception: If the computation raised an exception, this call will + raise the same exception. + """ + raise NotImplementedError() + + @abc.abstractmethod + def exception(self, timeout=None): + """Return the exception raised by the computation. + + This method may return immediately or may block. + + Args: + timeout: The length of time in seconds to wait for the computation to + terminate or be cancelled. If None, the call will block until the + computations's termination. + + Returns: + The exception raised by the computation, or None if the computation + did not raise an exception. + + Raises: + FutureTimeoutError: If a timeout value is passed and the computation + does not terminate within the allotted time. + FutureCancelledError: If the computation was cancelled. + """ + raise NotImplementedError() + + @abc.abstractmethod + def traceback(self, timeout=None): + """Access the traceback of the exception raised by the computation. + + This method may return immediately or may block. + + Args: + timeout: The length of time in seconds to wait for the computation + to terminate or be cancelled. If None, the call will block until + the computation's termination. + + Returns: + The traceback of the exception raised by the computation, or None + if the computation did not raise an exception. + + Raises: + FutureTimeoutError: If a timeout value is passed and the computation + does not terminate within the allotted time. + FutureCancelledError: If the computation was cancelled. + """ + raise NotImplementedError() + + @abc.abstractmethod + def add_done_callback(self, fn): + """Adds a function to be called at completion of the computation. + + The callback will be passed this Future object describing the outcome + of the computation. Callbacks will be invoked after the future is + terminated, whether successfully or not. + + If the computation has already completed, the callback will be called + immediately. + + Exceptions raised in the callback will be logged at ERROR level, but + will not terminate any threads of execution. + + Args: + fn: A callable taking this Future object as its single parameter. + """ + raise NotImplementedError() + + +################################ gRPC Enums ################################## + + +@enum.unique +class ChannelConnectivity(enum.Enum): + """Mirrors grpc_connectivity_state in the gRPC Core. + + Attributes: + IDLE: The channel is idle. + CONNECTING: The channel is connecting. + READY: The channel is ready to conduct RPCs. + TRANSIENT_FAILURE: The channel has seen a failure from which it expects + to recover. + SHUTDOWN: The channel has seen a failure from which it cannot recover. + """ + IDLE = (_cygrpc.ConnectivityState.idle, 'idle') + CONNECTING = (_cygrpc.ConnectivityState.connecting, 'connecting') + READY = (_cygrpc.ConnectivityState.ready, 'ready') + TRANSIENT_FAILURE = (_cygrpc.ConnectivityState.transient_failure, + 'transient failure') + SHUTDOWN = (_cygrpc.ConnectivityState.shutdown, 'shutdown') + + +@enum.unique +class StatusCode(enum.Enum): + """Mirrors grpc_status_code in the gRPC Core. + + Attributes: + OK: Not an error; returned on success + CANCELLED: The operation was cancelled (typically by the caller). + UNKNOWN: Unknown error. + INVALID_ARGUMENT: Client specified an invalid argument. + DEADLINE_EXCEEDED: Deadline expired before operation could complete. + NOT_FOUND: Some requested entity (e.g., file or directory) was not found. + ALREADY_EXISTS: Some entity that we attempted to create (e.g., file or directory) + already exists. + PERMISSION_DENIED: The caller does not have permission to execute the specified + operation. + UNAUTHENTICATED: The request does not have valid authentication credentials for the + operation. + RESOURCE_EXHAUSTED: Some resource has been exhausted, perhaps a per-user quota, or + perhaps the entire file system is out of space. + FAILED_PRECONDITION: Operation was rejected because the system is not in a state + required for the operation's execution. + ABORTED: The operation was aborted, typically due to a concurrency issue + like sequencer check failures, transaction aborts, etc. + UNIMPLEMENTED: Operation is not implemented or not supported/enabled in this service. + INTERNAL: Internal errors. Means some invariants expected by underlying + system has been broken. + UNAVAILABLE: The service is currently unavailable. + DATA_LOSS: Unrecoverable data loss or corruption. + """ + OK = (_cygrpc.StatusCode.ok, 'ok') + CANCELLED = (_cygrpc.StatusCode.cancelled, 'cancelled') + UNKNOWN = (_cygrpc.StatusCode.unknown, 'unknown') + INVALID_ARGUMENT = (_cygrpc.StatusCode.invalid_argument, 'invalid argument') + DEADLINE_EXCEEDED = (_cygrpc.StatusCode.deadline_exceeded, + 'deadline exceeded') + NOT_FOUND = (_cygrpc.StatusCode.not_found, 'not found') + ALREADY_EXISTS = (_cygrpc.StatusCode.already_exists, 'already exists') + PERMISSION_DENIED = (_cygrpc.StatusCode.permission_denied, + 'permission denied') + RESOURCE_EXHAUSTED = (_cygrpc.StatusCode.resource_exhausted, + 'resource exhausted') + FAILED_PRECONDITION = (_cygrpc.StatusCode.failed_precondition, + 'failed precondition') + ABORTED = (_cygrpc.StatusCode.aborted, 'aborted') + OUT_OF_RANGE = (_cygrpc.StatusCode.out_of_range, 'out of range') + UNIMPLEMENTED = (_cygrpc.StatusCode.unimplemented, 'unimplemented') + INTERNAL = (_cygrpc.StatusCode.internal, 'internal') + UNAVAILABLE = (_cygrpc.StatusCode.unavailable, 'unavailable') + DATA_LOSS = (_cygrpc.StatusCode.data_loss, 'data loss') + UNAUTHENTICATED = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated') + + +############################# gRPC Status ################################ + + +class Status(six.with_metaclass(abc.ABCMeta)): + """Describes the status of an RPC. + + This is an EXPERIMENTAL API. + + Attributes: + code: A StatusCode object to be sent to the client. + details: A UTF-8-encodable string to be sent to the client upon + termination of the RPC. + trailing_metadata: The trailing :term:`metadata` in the RPC. + """ + + +############################# gRPC Exceptions ################################ + + +class RpcError(Exception): + """Raised by the gRPC library to indicate non-OK-status RPC termination.""" + + +############################## Shared Context ################################ + + +class RpcContext(six.with_metaclass(abc.ABCMeta)): + """Provides RPC-related information and action.""" + + @abc.abstractmethod + def is_active(self): + """Describes whether the RPC is active or has terminated. + + Returns: + bool: + True if RPC is active, False otherwise. + """ + raise NotImplementedError() + + @abc.abstractmethod + def time_remaining(self): + """Describes the length of allowed time remaining for the RPC. + + Returns: + A nonnegative float indicating the length of allowed time in seconds + remaining for the RPC to complete before it is considered to have + timed out, or None if no deadline was specified for the RPC. + """ + raise NotImplementedError() + + @abc.abstractmethod + def cancel(self): + """Cancels the RPC. + + Idempotent and has no effect if the RPC has already terminated. + """ + raise NotImplementedError() + + @abc.abstractmethod + def add_callback(self, callback): + """Registers a callback to be called on RPC termination. + + Args: + callback: A no-parameter callable to be called on RPC termination. + + Returns: + True if the callback was added and will be called later; False if + the callback was not added and will not be called (because the RPC + already terminated or some other reason). + """ + raise NotImplementedError() + + +######################### Invocation-Side Context ############################ + + +class Call(six.with_metaclass(abc.ABCMeta, RpcContext)): + """Invocation-side utility object for an RPC.""" + + @abc.abstractmethod + def initial_metadata(self): + """Accesses the initial metadata sent by the server. + + This method blocks until the value is available. + + Returns: + The initial :term:`metadata`. + """ + raise NotImplementedError() + + @abc.abstractmethod + def trailing_metadata(self): + """Accesses the trailing metadata sent by the server. + + This method blocks until the value is available. + + Returns: + The trailing :term:`metadata`. + """ + raise NotImplementedError() + + @abc.abstractmethod + def code(self): + """Accesses the status code sent by the server. + + This method blocks until the value is available. + + Returns: + The StatusCode value for the RPC. + """ + raise NotImplementedError() + + @abc.abstractmethod + def details(self): + """Accesses the details sent by the server. + + This method blocks until the value is available. + + Returns: + The details string of the RPC. + """ + raise NotImplementedError() + + +############## Invocation-Side Interceptor Interfaces & Classes ############## + + +class ClientCallDetails(six.with_metaclass(abc.ABCMeta)): + """Describes an RPC to be invoked. + + Attributes: + method: The method name of the RPC. + timeout: An optional duration of time in seconds to allow for the RPC. + metadata: Optional :term:`metadata` to be transmitted to + the service-side of the RPC. + credentials: An optional CallCredentials for the RPC. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + """ + + +class UnaryUnaryClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting unary-unary invocations.""" + + @abc.abstractmethod + def intercept_unary_unary(self, continuation, client_call_details, request): + """Intercepts a unary-unary invocation asynchronously. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_future = continuation(client_call_details, request)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and a Future. In the event of RPC + completion, the return Call-Future's result value will be + the response message of the RPC. Should the event terminate + with non-OK status, the returned Call-Future's exception value + will be an RpcError. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request: The request value for the RPC. + + Returns: + An object that is both a Call for the RPC and a Future. + In the event of RPC completion, the return Call-Future's + result value will be the response message of the RPC. + Should the event terminate with non-OK status, the returned + Call-Future's exception value will be an RpcError. + """ + raise NotImplementedError() + + +class UnaryStreamClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting unary-stream invocations.""" + + @abc.abstractmethod + def intercept_unary_stream(self, continuation, client_call_details, + request): + """Intercepts a unary-stream invocation. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_iterator = continuation(client_call_details, request)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and an iterator for response values. + Drawing response values from the returned Call-iterator may + raise RpcError indicating termination of the RPC with non-OK + status. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request: The request value for the RPC. + + Returns: + An object that is both a Call for the RPC and an iterator of + response values. Drawing response values from the returned + Call-iterator may raise RpcError indicating termination of + the RPC with non-OK status. This object *should* also fulfill the + Future interface, though it may not. + """ + raise NotImplementedError() + + +class StreamUnaryClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting stream-unary invocations.""" + + @abc.abstractmethod + def intercept_stream_unary(self, continuation, client_call_details, + request_iterator): + """Intercepts a stream-unary invocation asynchronously. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_future = continuation(client_call_details, request_iterator)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and a Future. In the event of RPC completion, + the return Call-Future's result value will be the response message + of the RPC. Should the event terminate with non-OK status, the + returned Call-Future's exception value will be an RpcError. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request_iterator: An iterator that yields request values for the RPC. + + Returns: + An object that is both a Call for the RPC and a Future. + In the event of RPC completion, the return Call-Future's + result value will be the response message of the RPC. + Should the event terminate with non-OK status, the returned + Call-Future's exception value will be an RpcError. + """ + raise NotImplementedError() + + +class StreamStreamClientInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting stream-stream invocations.""" + + @abc.abstractmethod + def intercept_stream_stream(self, continuation, client_call_details, + request_iterator): + """Intercepts a stream-stream invocation. + + Args: + continuation: A function that proceeds with the invocation by + executing the next interceptor in chain or invoking the + actual RPC on the underlying Channel. It is the interceptor's + responsibility to call it if it decides to move the RPC forward. + The interceptor can use + `response_iterator = continuation(client_call_details, request_iterator)` + to continue with the RPC. `continuation` returns an object that is + both a Call for the RPC and an iterator for response values. + Drawing response values from the returned Call-iterator may + raise RpcError indicating termination of the RPC with non-OK + status. + client_call_details: A ClientCallDetails object describing the + outgoing RPC. + request_iterator: An iterator that yields request values for the RPC. + + Returns: + An object that is both a Call for the RPC and an iterator of + response values. Drawing response values from the returned + Call-iterator may raise RpcError indicating termination of + the RPC with non-OK status. This object *should* also fulfill the + Future interface, though it may not. + """ + raise NotImplementedError() + + +############ Authentication & Authorization Interfaces & Classes ############# + + +class ChannelCredentials(object): + """An encapsulation of the data required to create a secure Channel. + + This class has no supported interface - it exists to define the type of its + instances and its instances exist to be passed to other functions. For + example, ssl_channel_credentials returns an instance of this class and + secure_channel requires an instance of this class. + """ + + def __init__(self, credentials): + self._credentials = credentials + + +class CallCredentials(object): + """An encapsulation of the data required to assert an identity over a call. + + A CallCredentials has to be used with secure Channel, otherwise the + metadata will not be transmitted to the server. + + A CallCredentials may be composed with ChannelCredentials to always assert + identity for every call over that Channel. + + This class has no supported interface - it exists to define the type of its + instances and its instances exist to be passed to other functions. + """ + + def __init__(self, credentials): + self._credentials = credentials + + +class AuthMetadataContext(six.with_metaclass(abc.ABCMeta)): + """Provides information to call credentials metadata plugins. + + Attributes: + service_url: A string URL of the service being called into. + method_name: A string of the fully qualified method name being called. + """ + + +class AuthMetadataPluginCallback(six.with_metaclass(abc.ABCMeta)): + """Callback object received by a metadata plugin.""" + + def __call__(self, metadata, error): + """Passes to the gRPC runtime authentication metadata for an RPC. + + Args: + metadata: The :term:`metadata` used to construct the CallCredentials. + error: An Exception to indicate error or None to indicate success. + """ + raise NotImplementedError() + + +class AuthMetadataPlugin(six.with_metaclass(abc.ABCMeta)): + """A specification for custom authentication.""" + + def __call__(self, context, callback): + """Implements authentication by passing metadata to a callback. + + This method will be invoked asynchronously in a separate thread. + + Args: + context: An AuthMetadataContext providing information on the RPC that + the plugin is being called to authenticate. + callback: An AuthMetadataPluginCallback to be invoked either + synchronously or asynchronously. + """ + raise NotImplementedError() + + +class ServerCredentials(object): + """An encapsulation of the data required to open a secure port on a Server. + + This class has no supported interface - it exists to define the type of its + instances and its instances exist to be passed to other functions. + """ + + def __init__(self, credentials): + self._credentials = credentials + + +class ServerCertificateConfiguration(object): + """A certificate configuration for use with an SSL-enabled Server. + + Instances of this class can be returned in the certificate configuration + fetching callback. + + This class has no supported interface -- it exists to define the + type of its instances and its instances exist to be passed to + other functions. + """ + + def __init__(self, certificate_configuration): + self._certificate_configuration = certificate_configuration + + +######################## Multi-Callable Interfaces ########################### + + +class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): + """Affords invoking a unary-unary RPC from client-side.""" + + @abc.abstractmethod + def __call__(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Synchronously invokes the underlying RPC. + + Args: + request: The request value for the RPC. + timeout: An optional duration of time in seconds to allow + for the RPC. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + The response value for the RPC. + + Raises: + RpcError: Indicating that the RPC terminated with non-OK status. The + raised RpcError will also be a Call for the RPC affording the RPC's + metadata, status code, and details. + """ + raise NotImplementedError() + + @abc.abstractmethod + def with_call(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Synchronously invokes the underlying RPC. + + Args: + request: The request value for the RPC. + timeout: An optional durating of time in seconds to allow for + the RPC. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + The response value for the RPC and a Call value for the RPC. + + Raises: + RpcError: Indicating that the RPC terminated with non-OK status. The + raised RpcError will also be a Call for the RPC affording the RPC's + metadata, status code, and details. + """ + raise NotImplementedError() + + @abc.abstractmethod + def future(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Asynchronously invokes the underlying RPC. + + Args: + request: The request value for the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + An object that is both a Call for the RPC and a Future. + In the event of RPC completion, the return Call-Future's result + value will be the response message of the RPC. + Should the event terminate with non-OK status, + the returned Call-Future's exception value will be an RpcError. + """ + raise NotImplementedError() + + +class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): + """Affords invoking a unary-stream RPC from client-side.""" + + @abc.abstractmethod + def __call__(self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Invokes the underlying RPC. + + Args: + request: The request value for the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. If None, the timeout is considered infinite. + metadata: An optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + An object that is a Call for the RPC, an iterator of response + values, and a Future for the RPC. Drawing response values from the + returned Call-iterator may raise RpcError indicating termination of + the RPC with non-OK status. + """ + raise NotImplementedError() + + +class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): + """Affords invoking a stream-unary RPC from client-side.""" + + @abc.abstractmethod + def __call__(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Synchronously invokes the underlying RPC. + + Args: + request_iterator: An iterator that yields request values for + the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. If None, the timeout is considered infinite. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + The response value for the RPC. + + Raises: + RpcError: Indicating that the RPC terminated with non-OK status. The + raised RpcError will also implement grpc.Call, affording methods + such as metadata, code, and details. + """ + raise NotImplementedError() + + @abc.abstractmethod + def with_call(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Synchronously invokes the underlying RPC on the client. + + Args: + request_iterator: An iterator that yields request values for + the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. If None, the timeout is considered infinite. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + The response value for the RPC and a Call object for the RPC. + + Raises: + RpcError: Indicating that the RPC terminated with non-OK status. The + raised RpcError will also be a Call for the RPC affording the RPC's + metadata, status code, and details. + """ + raise NotImplementedError() + + @abc.abstractmethod + def future(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Asynchronously invokes the underlying RPC on the client. + + Args: + request_iterator: An iterator that yields request values for the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. If None, the timeout is considered infinite. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + An object that is both a Call for the RPC and a Future. + In the event of RPC completion, the return Call-Future's result value + will be the response message of the RPC. Should the event terminate + with non-OK status, the returned Call-Future's exception value will + be an RpcError. + """ + raise NotImplementedError() + + +class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): + """Affords invoking a stream-stream RPC on client-side.""" + + @abc.abstractmethod + def __call__(self, + request_iterator, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): + """Invokes the underlying RPC on the client. + + Args: + request_iterator: An iterator that yields request values for the RPC. + timeout: An optional duration of time in seconds to allow for + the RPC. If not specified, the timeout is considered infinite. + metadata: Optional :term:`metadata` to be transmitted to the + service-side of the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. + wait_for_ready: This is an EXPERIMENTAL argument. An optional + flag to enable :term:`wait_for_ready` mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. + + Returns: + An object that is a Call for the RPC, an iterator of response + values, and a Future for the RPC. Drawing response values from the + returned Call-iterator may raise RpcError indicating termination of + the RPC with non-OK status. + """ + raise NotImplementedError() + + +############################# Channel Interface ############################## + + +class Channel(six.with_metaclass(abc.ABCMeta)): + """Affords RPC invocation via generic methods on client-side. + + Channel objects implement the Context Manager type, although they need not + support being entered and exited multiple times. + """ + + @abc.abstractmethod + def subscribe(self, callback, try_to_connect=False): + """Subscribe to this Channel's connectivity state machine. + + A Channel may be in any of the states described by ChannelConnectivity. + This method allows application to monitor the state transitions. + The typical use case is to debug or gain better visibility into gRPC + runtime's state. + + Args: + callback: A callable to be invoked with ChannelConnectivity argument. + ChannelConnectivity describes current state of the channel. + The callable will be invoked immediately upon subscription + and again for every change to ChannelConnectivity until it + is unsubscribed or this Channel object goes out of scope. + try_to_connect: A boolean indicating whether or not this Channel + should attempt to connect immediately. If set to False, gRPC + runtime decides when to connect. + """ + raise NotImplementedError() + + @abc.abstractmethod + def unsubscribe(self, callback): + """Unsubscribes a subscribed callback from this Channel's connectivity. + + Args: + callback: A callable previously registered with this Channel from + having been passed to its "subscribe" method. + """ + raise NotImplementedError() + + @abc.abstractmethod + def unary_unary(self, + method, + request_serializer=None, + response_deserializer=None): + """Creates a UnaryUnaryMultiCallable for a unary-unary method. + + Args: + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the + response message. Response goes undeserialized in case None + is passed. + + Returns: + A UnaryUnaryMultiCallable value for the named unary-unary method. + """ + raise NotImplementedError() + + @abc.abstractmethod + def unary_stream(self, + method, + request_serializer=None, + response_deserializer=None): + """Creates a UnaryStreamMultiCallable for a unary-stream method. + + Args: + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the + response message. Response goes undeserialized in case None is + passed. + + Returns: + A UnaryStreamMultiCallable value for the name unary-stream method. + """ + raise NotImplementedError() + + @abc.abstractmethod + def stream_unary(self, + method, + request_serializer=None, + response_deserializer=None): + """Creates a StreamUnaryMultiCallable for a stream-unary method. + + Args: + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the + response message. Response goes undeserialized in case None is + passed. + + Returns: + A StreamUnaryMultiCallable value for the named stream-unary method. + """ + raise NotImplementedError() + + @abc.abstractmethod + def stream_stream(self, + method, + request_serializer=None, + response_deserializer=None): + """Creates a StreamStreamMultiCallable for a stream-stream method. + + Args: + method: The name of the RPC method. + request_serializer: Optional :term:`serializer` for serializing the request + message. Request goes unserialized in case None is passed. + response_deserializer: Optional :term:`deserializer` for deserializing the + response message. Response goes undeserialized in case None + is passed. + + Returns: + A StreamStreamMultiCallable value for the named stream-stream method. + """ + raise NotImplementedError() + + @abc.abstractmethod + def close(self): + """Closes this Channel and releases all resources held by it. + + Closing the Channel will immediately terminate all RPCs active with the + Channel and it is not valid to invoke new RPCs with the Channel. + + This method is idempotent. + """ + raise NotImplementedError() + + def __enter__(self): + """Enters the runtime context related to the channel object.""" + raise NotImplementedError() + + def __exit__(self, exc_type, exc_val, exc_tb): + """Exits the runtime context related to the channel object.""" + raise NotImplementedError() + + +########################## Service-Side Context ############################## + + +class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): + """A context object passed to method implementations.""" + + @abc.abstractmethod + def invocation_metadata(self): + """Accesses the metadata from the sent by the client. + + Returns: + The invocation :term:`metadata`. + """ + raise NotImplementedError() + + @abc.abstractmethod + def peer(self): + """Identifies the peer that invoked the RPC being serviced. + + Returns: + A string identifying the peer that invoked the RPC being serviced. + The string format is determined by gRPC runtime. + """ + raise NotImplementedError() + + @abc.abstractmethod + def peer_identities(self): + """Gets one or more peer identity(s). + + Equivalent to + servicer_context.auth_context().get(servicer_context.peer_identity_key()) + + Returns: + An iterable of the identities, or None if the call is not + authenticated. Each identity is returned as a raw bytes type. + """ + raise NotImplementedError() + + @abc.abstractmethod + def peer_identity_key(self): + """The auth property used to identify the peer. + + For example, "x509_common_name" or "x509_subject_alternative_name" are + used to identify an SSL peer. + + Returns: + The auth property (string) that indicates the + peer identity, or None if the call is not authenticated. + """ + raise NotImplementedError() + + @abc.abstractmethod + def auth_context(self): + """Gets the auth context for the call. + + Returns: + A map of strings to an iterable of bytes for each auth property. + """ + raise NotImplementedError() + + def set_compression(self, compression): + """Set the compression algorithm to be used for the entire call. + + This is an EXPERIMENTAL method. + + Args: + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. + """ + raise NotImplementedError() + + @abc.abstractmethod + def send_initial_metadata(self, initial_metadata): + """Sends the initial metadata value to the client. + + This method need not be called by implementations if they have no + metadata to add to what the gRPC runtime will transmit. + + Args: + initial_metadata: The initial :term:`metadata`. + """ + raise NotImplementedError() + + @abc.abstractmethod + def set_trailing_metadata(self, trailing_metadata): + """Sets the trailing metadata for the RPC. + + Sets the trailing metadata to be sent upon completion of the RPC. + + If this method is invoked multiple times throughout the lifetime of an + RPC, the value supplied in the final invocation will be the value sent + over the wire. + + This method need not be called by implementations if they have no + metadata to add to what the gRPC runtime will transmit. + + Args: + trailing_metadata: The trailing :term:`metadata`. + """ + raise NotImplementedError() + + def trailing_metadata(self): + """Access value to be used as trailing metadata upon RPC completion. + + This is an EXPERIMENTAL API. + + Returns: + The trailing :term:`metadata` for the RPC. + """ + raise NotImplementedError() + + @abc.abstractmethod + def abort(self, code, details): + """Raises an exception to terminate the RPC with a non-OK status. + + The code and details passed as arguments will supercede any existing + ones. + + Args: + code: A StatusCode object to be sent to the client. + It must not be StatusCode.OK. + details: A UTF-8-encodable string to be sent to the client upon + termination of the RPC. + + Raises: + Exception: An exception is always raised to signal the abortion the + RPC to the gRPC runtime. + """ + raise NotImplementedError() + + @abc.abstractmethod + def abort_with_status(self, status): + """Raises an exception to terminate the RPC with a non-OK status. + + The status passed as argument will supercede any existing status code, + status message and trailing metadata. + + This is an EXPERIMENTAL API. + + Args: + status: A grpc.Status object. The status code in it must not be + StatusCode.OK. + + Raises: + Exception: An exception is always raised to signal the abortion the + RPC to the gRPC runtime. + """ + raise NotImplementedError() + + @abc.abstractmethod + def set_code(self, code): + """Sets the value to be used as status code upon RPC completion. + + This method need not be called by method implementations if they wish + the gRPC runtime to determine the status code of the RPC. + + Args: + code: A StatusCode object to be sent to the client. + """ + raise NotImplementedError() + + @abc.abstractmethod + def set_details(self, details): + """Sets the value to be used as detail string upon RPC completion. + + This method need not be called by method implementations if they have + no details to transmit. + + Args: + details: A UTF-8-encodable string to be sent to the client upon + termination of the RPC. + """ + raise NotImplementedError() + + def code(self): + """Accesses the value to be used as status code upon RPC completion. + + This is an EXPERIMENTAL API. + + Returns: + The StatusCode value for the RPC. + """ + raise NotImplementedError() + + def details(self): + """Accesses the value to be used as detail string upon RPC completion. + + This is an EXPERIMENTAL API. + + Returns: + The details string of the RPC. + """ + raise NotImplementedError() + + def disable_next_message_compression(self): + """Disables compression for the next response message. + + This is an EXPERIMENTAL method. + + This method will override any compression configuration set during + server creation or set on the call. + """ + raise NotImplementedError() + + +##################### Service-Side Handler Interfaces ######################## + + +class RpcMethodHandler(six.with_metaclass(abc.ABCMeta)): + """An implementation of a single RPC method. + + Attributes: + request_streaming: Whether the RPC supports exactly one request message + or any arbitrary number of request messages. + response_streaming: Whether the RPC supports exactly one response message + or any arbitrary number of response messages. + request_deserializer: A callable :term:`deserializer` that accepts a byte string and + returns an object suitable to be passed to this object's business + logic, or None to indicate that this object's business logic should be + passed the raw request bytes. + response_serializer: A callable :term:`serializer` that accepts an object produced + by this object's business logic and returns a byte string, or None to + indicate that the byte strings produced by this object's business logic + should be transmitted on the wire as they are. + unary_unary: This object's application-specific business logic as a + callable value that takes a request value and a ServicerContext object + and returns a response value. Only non-None if both request_streaming + and response_streaming are False. + unary_stream: This object's application-specific business logic as a + callable value that takes a request value and a ServicerContext object + and returns an iterator of response values. Only non-None if + request_streaming is False and response_streaming is True. + stream_unary: This object's application-specific business logic as a + callable value that takes an iterator of request values and a + ServicerContext object and returns a response value. Only non-None if + request_streaming is True and response_streaming is False. + stream_stream: This object's application-specific business logic as a + callable value that takes an iterator of request values and a + ServicerContext object and returns an iterator of response values. + Only non-None if request_streaming and response_streaming are both + True. + """ + + +class HandlerCallDetails(six.with_metaclass(abc.ABCMeta)): + """Describes an RPC that has just arrived for service. + + Attributes: + method: The method name of the RPC. + invocation_metadata: The :term:`metadata` sent by the client. + """ + + +class GenericRpcHandler(six.with_metaclass(abc.ABCMeta)): + """An implementation of arbitrarily many RPC methods.""" + + @abc.abstractmethod + def service(self, handler_call_details): + """Returns the handler for servicing the RPC. + + Args: + handler_call_details: A HandlerCallDetails describing the RPC. + + Returns: + An RpcMethodHandler with which the RPC may be serviced if the + implementation chooses to service this RPC, or None otherwise. + """ + raise NotImplementedError() + + +class ServiceRpcHandler(six.with_metaclass(abc.ABCMeta, GenericRpcHandler)): + """An implementation of RPC methods belonging to a service. + + A service handles RPC methods with structured names of the form + '/Service.Name/Service.Method', where 'Service.Name' is the value + returned by service_name(), and 'Service.Method' is the method + name. A service can have multiple method names, but only a single + service name. + """ + + @abc.abstractmethod + def service_name(self): + """Returns this service's name. + + Returns: + The service name. + """ + raise NotImplementedError() + + +#################### Service-Side Interceptor Interfaces ##################### + + +class ServerInterceptor(six.with_metaclass(abc.ABCMeta)): + """Affords intercepting incoming RPCs on the service-side.""" + + @abc.abstractmethod + def intercept_service(self, continuation, handler_call_details): + """Intercepts incoming RPCs before handing them over to a handler. + + Args: + continuation: A function that takes a HandlerCallDetails and + proceeds to invoke the next interceptor in the chain, if any, + or the RPC handler lookup logic, with the call details passed + as an argument, and returns an RpcMethodHandler instance if + the RPC is considered serviced, or None otherwise. + handler_call_details: A HandlerCallDetails describing the RPC. + + Returns: + An RpcMethodHandler with which the RPC may be serviced if the + interceptor chooses to service this RPC, or None otherwise. + """ + raise NotImplementedError() + + +############################# Server Interface ############################### + + +class Server(six.with_metaclass(abc.ABCMeta)): + """Services RPCs.""" + + @abc.abstractmethod + def add_generic_rpc_handlers(self, generic_rpc_handlers): + """Registers GenericRpcHandlers with this Server. + + This method is only safe to call before the server is started. + + Args: + generic_rpc_handlers: An iterable of GenericRpcHandlers that will be + used to service RPCs. + """ + raise NotImplementedError() + + @abc.abstractmethod + def add_insecure_port(self, address): + """Opens an insecure port for accepting RPCs. + + This method may only be called before starting the server. + + Args: + address: The address for which to open a port. If the port is 0, + or not specified in the address, then gRPC runtime will choose a port. + + Returns: + An integer port on which server will accept RPC requests. + """ + raise NotImplementedError() + + @abc.abstractmethod + def add_secure_port(self, address, server_credentials): + """Opens a secure port for accepting RPCs. + + This method may only be called before starting the server. + + Args: + address: The address for which to open a port. + if the port is 0, or not specified in the address, then gRPC + runtime will choose a port. + server_credentials: A ServerCredentials object. + + Returns: + An integer port on which server will accept RPC requests. + """ + raise NotImplementedError() + + @abc.abstractmethod + def start(self): + """Starts this Server. + + This method may only be called once. (i.e. it is not idempotent). + """ + raise NotImplementedError() + + @abc.abstractmethod + def stop(self, grace): + """Stops this Server. + + This method immediately stop service of new RPCs in all cases. + + If a grace period is specified, this method returns immediately + and all RPCs active at the end of the grace period are aborted. + If a grace period is not specified (by passing None for `grace`), + all existing RPCs are aborted immediately and this method + blocks until the last RPC handler terminates. + + This method is idempotent and may be called at any time. + Passing a smaller grace value in a subsequent call will have + the effect of stopping the Server sooner (passing None will + have the effect of stopping the server immediately). Passing + a larger grace value in a subsequent call *will not* have the + effect of stopping the server later (i.e. the most restrictive + grace value is used). + + Args: + grace: A duration of time in seconds or None. + + Returns: + A threading.Event that will be set when this Server has completely + stopped, i.e. when running RPCs either complete or are aborted and + all handlers have terminated. + """ + raise NotImplementedError() + + def wait_for_termination(self, timeout=None): + """Block current thread until the server stops. + + This is an EXPERIMENTAL API. + + The wait will not consume computational resources during blocking, and + it will block until one of the two following conditions are met: + + 1) The server is stopped or terminated; + 2) A timeout occurs if timeout is not `None`. + + The timeout argument works in the same way as `threading.Event.wait()`. + https://docs.python.org/3/library/threading.html#threading.Event.wait + + Args: + timeout: A floating point number specifying a timeout for the + operation in seconds. + + Returns: + A bool indicates if the operation times out. + """ + raise NotImplementedError() + + +################################# Functions ################################ + + +def unary_unary_rpc_method_handler(behavior, + request_deserializer=None, + response_serializer=None): + """Creates an RpcMethodHandler for a unary-unary RPC method. + + Args: + behavior: The implementation of an RPC that accepts one request + and returns one response. + request_deserializer: An optional :term:`deserializer` for request deserialization. + response_serializer: An optional :term:`serializer` for response serialization. + + Returns: + An RpcMethodHandler object that is typically used by grpc.Server. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.RpcMethodHandler(False, False, request_deserializer, + response_serializer, behavior, None, + None, None) + + +def unary_stream_rpc_method_handler(behavior, + request_deserializer=None, + response_serializer=None): + """Creates an RpcMethodHandler for a unary-stream RPC method. + + Args: + behavior: The implementation of an RPC that accepts one request + and returns an iterator of response values. + request_deserializer: An optional :term:`deserializer` for request deserialization. + response_serializer: An optional :term:`serializer` for response serialization. + + Returns: + An RpcMethodHandler object that is typically used by grpc.Server. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.RpcMethodHandler(False, True, request_deserializer, + response_serializer, None, behavior, + None, None) + + +def stream_unary_rpc_method_handler(behavior, + request_deserializer=None, + response_serializer=None): + """Creates an RpcMethodHandler for a stream-unary RPC method. + + Args: + behavior: The implementation of an RPC that accepts an iterator of + request values and returns a single response value. + request_deserializer: An optional :term:`deserializer` for request deserialization. + response_serializer: An optional :term:`serializer` for response serialization. + + Returns: + An RpcMethodHandler object that is typically used by grpc.Server. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.RpcMethodHandler(True, False, request_deserializer, + response_serializer, None, None, + behavior, None) + + +def stream_stream_rpc_method_handler(behavior, + request_deserializer=None, + response_serializer=None): + """Creates an RpcMethodHandler for a stream-stream RPC method. + + Args: + behavior: The implementation of an RPC that accepts an iterator of + request values and returns an iterator of response values. + request_deserializer: An optional :term:`deserializer` for request deserialization. + response_serializer: An optional :term:`serializer` for response serialization. + + Returns: + An RpcMethodHandler object that is typically used by grpc.Server. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.RpcMethodHandler(True, True, request_deserializer, + response_serializer, None, None, None, + behavior) + + +def method_handlers_generic_handler(service, method_handlers): + """Creates a GenericRpcHandler from RpcMethodHandlers. + + Args: + service: The name of the service that is implemented by the + method_handlers. + method_handlers: A dictionary that maps method names to corresponding + RpcMethodHandler. + + Returns: + A GenericRpcHandler. This is typically added to the grpc.Server object + with add_generic_rpc_handlers() before starting the server. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.DictionaryGenericHandler(service, method_handlers) + + +def ssl_channel_credentials(root_certificates=None, + private_key=None, + certificate_chain=None): + """Creates a ChannelCredentials for use with an SSL-enabled Channel. + + Args: + root_certificates: The PEM-encoded root certificates as a byte string, + or None to retrieve them from a default location chosen by gRPC + runtime. + private_key: The PEM-encoded private key as a byte string, or None if no + private key should be used. + certificate_chain: The PEM-encoded certificate chain as a byte string + to use or None if no certificate chain should be used. + + Returns: + A ChannelCredentials for use with an SSL-enabled Channel. + """ + return ChannelCredentials( + _cygrpc.SSLChannelCredentials(root_certificates, private_key, + certificate_chain)) + + +def xds_channel_credentials(fallback_credentials=None): + """Creates a ChannelCredentials for use with xDS. This is an EXPERIMENTAL + API. + + Args: + fallback_credentials: Credentials to use in case it is not possible to + establish a secure connection via xDS. If no fallback_credentials + argument is supplied, a default SSLChannelCredentials is used. + """ + fallback_credentials = ssl_channel_credentials( + ) if fallback_credentials is None else fallback_credentials + return ChannelCredentials( + _cygrpc.XDSChannelCredentials(fallback_credentials._credentials)) + + +def metadata_call_credentials(metadata_plugin, name=None): + """Construct CallCredentials from an AuthMetadataPlugin. + + Args: + metadata_plugin: An AuthMetadataPlugin to use for authentication. + name: An optional name for the plugin. + + Returns: + A CallCredentials. + """ + from grpc import _plugin_wrapping # pylint: disable=cyclic-import + return _plugin_wrapping.metadata_plugin_call_credentials( + metadata_plugin, name) + + +def access_token_call_credentials(access_token): + """Construct CallCredentials from an access token. + + Args: + access_token: A string to place directly in the http request + authorization header, for example + "authorization: Bearer ". + + Returns: + A CallCredentials. + """ + from grpc import _auth # pylint: disable=cyclic-import + from grpc import _plugin_wrapping # pylint: disable=cyclic-import + return _plugin_wrapping.metadata_plugin_call_credentials( + _auth.AccessTokenAuthMetadataPlugin(access_token), None) + + +def composite_call_credentials(*call_credentials): + """Compose multiple CallCredentials to make a new CallCredentials. + + Args: + *call_credentials: At least two CallCredentials objects. + + Returns: + A CallCredentials object composed of the given CallCredentials objects. + """ + return CallCredentials( + _cygrpc.CompositeCallCredentials( + tuple(single_call_credentials._credentials + for single_call_credentials in call_credentials))) + + +def composite_channel_credentials(channel_credentials, *call_credentials): + """Compose a ChannelCredentials and one or more CallCredentials objects. + + Args: + channel_credentials: A ChannelCredentials object. + *call_credentials: One or more CallCredentials objects. + + Returns: + A ChannelCredentials composed of the given ChannelCredentials and + CallCredentials objects. + """ + return ChannelCredentials( + _cygrpc.CompositeChannelCredentials( + tuple(single_call_credentials._credentials + for single_call_credentials in call_credentials), + channel_credentials._credentials)) + + +def ssl_server_credentials(private_key_certificate_chain_pairs, + root_certificates=None, + require_client_auth=False): + """Creates a ServerCredentials for use with an SSL-enabled Server. + + Args: + private_key_certificate_chain_pairs: A list of pairs of the form + [PEM-encoded private key, PEM-encoded certificate chain]. + root_certificates: An optional byte string of PEM-encoded client root + certificates that the server will use to verify client authentication. + If omitted, require_client_auth must also be False. + require_client_auth: A boolean indicating whether or not to require + clients to be authenticated. May only be True if root_certificates + is not None. + + Returns: + A ServerCredentials for use with an SSL-enabled Server. Typically, this + object is an argument to add_secure_port() method during server setup. + """ + if not private_key_certificate_chain_pairs: + raise ValueError( + 'At least one private key-certificate chain pair is required!') + elif require_client_auth and root_certificates is None: + raise ValueError( + 'Illegal to require client auth without providing root certificates!' + ) + else: + return ServerCredentials( + _cygrpc.server_credentials_ssl(root_certificates, [ + _cygrpc.SslPemKeyCertPair(key, pem) + for key, pem in private_key_certificate_chain_pairs + ], require_client_auth)) + +def xds_server_credentials(fallback_credentials): + """Creates a ServerCredentials for use with xDS. This is an EXPERIMENTAL + API. + + Args: + fallback_credentials: Credentials to use in case it is not possible to + establish a secure connection via xDS. No default value is provided. + """ + return ServerCredentials( + _cygrpc.xds_server_credentials(fallback_credentials._credentials)) + + +def insecure_server_credentials(): + """Creates a credentials object directing the server to use no credentials. + This is an EXPERIMENTAL API. + + This object cannot be used directly in a call to `add_secure_port`. + Instead, it should be used to construct other credentials objects, e.g. + with xds_server_credentials. + """ + return ServerCredentials(_cygrpc.insecure_server_credentials()) + + +def ssl_server_certificate_configuration(private_key_certificate_chain_pairs, + root_certificates=None): + """Creates a ServerCertificateConfiguration for use with a Server. + + Args: + private_key_certificate_chain_pairs: A collection of pairs of + the form [PEM-encoded private key, PEM-encoded certificate + chain]. + root_certificates: An optional byte string of PEM-encoded client root + certificates that the server will use to verify client authentication. + + Returns: + A ServerCertificateConfiguration that can be returned in the certificate + configuration fetching callback. + """ + if private_key_certificate_chain_pairs: + return ServerCertificateConfiguration( + _cygrpc.server_certificate_config_ssl(root_certificates, [ + _cygrpc.SslPemKeyCertPair(key, pem) + for key, pem in private_key_certificate_chain_pairs + ])) + else: + raise ValueError( + 'At least one private key-certificate chain pair is required!') + + +def dynamic_ssl_server_credentials(initial_certificate_configuration, + certificate_configuration_fetcher, + require_client_authentication=False): + """Creates a ServerCredentials for use with an SSL-enabled Server. + + Args: + initial_certificate_configuration (ServerCertificateConfiguration): The + certificate configuration with which the server will be initialized. + certificate_configuration_fetcher (callable): A callable that takes no + arguments and should return a ServerCertificateConfiguration to + replace the server's current certificate, or None for no change + (i.e., the server will continue its current certificate + config). The library will call this callback on *every* new + client connection before starting the TLS handshake with the + client, thus allowing the user application to optionally + return a new ServerCertificateConfiguration that the server will then + use for the handshake. + require_client_authentication: A boolean indicating whether or not to + require clients to be authenticated. + + Returns: + A ServerCredentials. + """ + return ServerCredentials( + _cygrpc.server_credentials_ssl_dynamic_cert_config( + initial_certificate_configuration, + certificate_configuration_fetcher, require_client_authentication)) + + +@enum.unique +class LocalConnectionType(enum.Enum): + """Types of local connection for local credential creation. + + Attributes: + UDS: Unix domain socket connections + LOCAL_TCP: Local TCP connections. + """ + UDS = _cygrpc.LocalConnectionType.uds + LOCAL_TCP = _cygrpc.LocalConnectionType.local_tcp + + +def local_channel_credentials(local_connect_type=LocalConnectionType.LOCAL_TCP): + """Creates a local ChannelCredentials used for local connections. + + This is an EXPERIMENTAL API. + + Local credentials are used by local TCP endpoints (e.g. localhost:10000) + also UDS connections. + + The connections created by local channel credentials are not + encrypted, but will be checked if they are local or not. + The UDS connections are considered secure by providing peer authentication + and data confidentiality while TCP connections are considered insecure. + + It is allowed to transmit call credentials over connections created by + local channel credentials. + + Local channel credentials are useful for 1) eliminating insecure_channel usage; + 2) enable unit testing for call credentials without setting up secrets. + + Args: + local_connect_type: Local connection type (either + grpc.LocalConnectionType.UDS or grpc.LocalConnectionType.LOCAL_TCP) + + Returns: + A ChannelCredentials for use with a local Channel + """ + return ChannelCredentials( + _cygrpc.channel_credentials_local(local_connect_type.value)) + + +def local_server_credentials(local_connect_type=LocalConnectionType.LOCAL_TCP): + """Creates a local ServerCredentials used for local connections. + + This is an EXPERIMENTAL API. + + Local credentials are used by local TCP endpoints (e.g. localhost:10000) + also UDS connections. + + The connections created by local server credentials are not + encrypted, but will be checked if they are local or not. + The UDS connections are considered secure by providing peer authentication + and data confidentiality while TCP connections are considered insecure. + + It is allowed to transmit call credentials over connections created by local + server credentials. + + Local server credentials are useful for 1) eliminating insecure_channel usage; + 2) enable unit testing for call credentials without setting up secrets. + + Args: + local_connect_type: Local connection type (either + grpc.LocalConnectionType.UDS or grpc.LocalConnectionType.LOCAL_TCP) + + Returns: + A ServerCredentials for use with a local Server + """ + return ServerCredentials( + _cygrpc.server_credentials_local(local_connect_type.value)) + + +def alts_channel_credentials(service_accounts=None): + """Creates a ChannelCredentials for use with an ALTS-enabled Channel. + + This is an EXPERIMENTAL API. + ALTS credentials API can only be used in GCP environment as it relies on + handshaker service being available. For more info about ALTS see + https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security + + Args: + service_accounts: A list of server identities accepted by the client. + If target service accounts are provided and none of them matches the + peer identity of the server, handshake will fail. The arg can be empty + if the client does not have any information about trusted server + identity. + Returns: + A ChannelCredentials for use with an ALTS-enabled Channel + """ + return ChannelCredentials( + _cygrpc.channel_credentials_alts(service_accounts or [])) + + +def alts_server_credentials(): + """Creates a ServerCredentials for use with an ALTS-enabled connection. + + This is an EXPERIMENTAL API. + ALTS credentials API can only be used in GCP environment as it relies on + handshaker service being available. For more info about ALTS see + https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security + + Returns: + A ServerCredentials for use with an ALTS-enabled Server + """ + return ServerCredentials(_cygrpc.server_credentials_alts()) + + +def sgxratls_channel_credentials(config_json): + """Creates a ChannelCredentials for use with an SGX-enabled Channel. + + Args: + + Returns: + A ChannelCredentials for use with an SGX-enabled Channel Credential. + """ + return ChannelCredentials( + _cygrpc.channel_credentials_sgxratls(config_json)) + + +def sgxratls_server_credentials(config_json): + """Creates a ServerCredentials for use with an SGX-enabled Server. + + Args: + + Returns: + A ServerCredentials for use with an SGX-enabled Server Credential. + """ + return ServerCredentials( + _cygrpc.server_credentials_sgxratls(config_json)) + + +def compute_engine_channel_credentials(call_credentials): + """Creates a compute engine channel credential. + + This credential can only be used in a GCP environment as it relies on + a handshaker service. For more info about ALTS, see + https://cloud.google.com/security/encryption-in-transit/application-layer-transport-security + + This channel credential is expected to be used as part of a composite + credential in conjunction with a call credentials that authenticates the + VM's default service account. If used with any other sort of call + credential, the connection may suddenly and unexpectedly begin failing RPCs. + """ + return ChannelCredentials( + _cygrpc.channel_credentials_compute_engine( + call_credentials._credentials)) + + +def channel_ready_future(channel): + """Creates a Future that tracks when a Channel is ready. + + Cancelling the Future does not affect the channel's state machine. + It merely decouples the Future from channel state machine. + + Args: + channel: A Channel object. + + Returns: + A Future object that matures when the channel connectivity is + ChannelConnectivity.READY. + """ + from grpc import _utilities # pylint: disable=cyclic-import + return _utilities.channel_ready_future(channel) + + +def insecure_channel(target, options=None, compression=None): + """Creates an insecure Channel to a server. + + The returned Channel is thread-safe. + + Args: + target: The server address + options: An optional list of key-value pairs (:term:`channel_arguments` + in gRPC Core runtime) to configure the channel. + compression: An optional value indicating the compression method to be + used over the lifetime of the channel. This is an EXPERIMENTAL option. + + Returns: + A Channel. + """ + from grpc import _channel # pylint: disable=cyclic-import + return _channel.Channel(target, () if options is None else options, None, + compression) + + +def secure_channel(target, credentials, options=None, compression=None): + """Creates a secure Channel to a server. + + The returned Channel is thread-safe. + + Args: + target: The server address. + credentials: A ChannelCredentials instance. + options: An optional list of key-value pairs (:term:`channel_arguments` + in gRPC Core runtime) to configure the channel. + compression: An optional value indicating the compression method to be + used over the lifetime of the channel. This is an EXPERIMENTAL option. + + Returns: + A Channel. + """ + from grpc import _channel # pylint: disable=cyclic-import + from grpc.experimental import _insecure_channel_credentials + if credentials._credentials is _insecure_channel_credentials: + raise ValueError( + "secure_channel cannot be called with insecure credentials." + + " Call insecure_channel instead.") + return _channel.Channel(target, () if options is None else options, + credentials._credentials, compression) + +def intercept_channel(channel, *interceptors): + """Intercepts a channel through a set of interceptors. + + Args: + channel: A Channel. + interceptors: Zero or more objects of type + UnaryUnaryClientInterceptor, + UnaryStreamClientInterceptor, + StreamUnaryClientInterceptor, or + StreamStreamClientInterceptor. + Interceptors are given control in the order they are listed. + + Returns: + A Channel that intercepts each invocation via the provided interceptors. + + Raises: + TypeError: If interceptor does not derive from any of + UnaryUnaryClientInterceptor, + UnaryStreamClientInterceptor, + StreamUnaryClientInterceptor, or + StreamStreamClientInterceptor. + """ + from grpc import _interceptor # pylint: disable=cyclic-import + return _interceptor.intercept_channel(channel, *interceptors) + + +def server(thread_pool, + handlers=None, + interceptors=None, + options=None, + maximum_concurrent_rpcs=None, + compression=None, + xds=False): + """Creates a Server with which RPCs can be serviced. + + Args: + thread_pool: A futures.ThreadPoolExecutor to be used by the Server + to execute RPC handlers. + handlers: An optional list of GenericRpcHandlers used for executing RPCs. + More handlers may be added by calling add_generic_rpc_handlers any time + before the server is started. + interceptors: An optional list of ServerInterceptor objects that observe + and optionally manipulate the incoming RPCs before handing them over to + handlers. The interceptors are given control in the order they are + specified. This is an EXPERIMENTAL API. + options: An optional list of key-value pairs (:term:`channel_arguments` in gRPC runtime) + to configure the channel. + maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server + will service before returning RESOURCE_EXHAUSTED status, or None to + indicate no limit. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This compression algorithm will be used for the + lifetime of the server unless overridden. This is an EXPERIMENTAL option. + xds: If set to true, retrieves server configuration via xDS. This is an + EXPERIMENTAL option. + + Returns: + A Server object. + """ + from grpc import _server # pylint: disable=cyclic-import + return _server.create_server(thread_pool, + () if handlers is None else handlers, + () if interceptors is None else interceptors, + () if options is None else options, + maximum_concurrent_rpcs, compression, xds) + + +@contextlib.contextmanager +def _create_servicer_context(rpc_event, state, request_deserializer): + from grpc import _server # pylint: disable=cyclic-import + context = _server._Context(rpc_event, state, request_deserializer) + yield context + context._finalize_state() # pylint: disable=protected-access + + +@enum.unique +class Compression(enum.IntEnum): + """Indicates the compression method to be used for an RPC. + + This enumeration is part of an EXPERIMENTAL API. + + Attributes: + NoCompression: Do not use compression algorithm. + Deflate: Use "Deflate" compression algorithm. + Gzip: Use "Gzip" compression algorithm. + """ + NoCompression = _compression.NoCompression + Deflate = _compression.Deflate + Gzip = _compression.Gzip + + +from grpc._runtime_protos import protos, services, protos_and_services # pylint: disable=wrong-import-position + +################################### __all__ ################################# + +__all__ = ( + 'FutureTimeoutError', + 'FutureCancelledError', + 'Future', + 'ChannelConnectivity', + 'StatusCode', + 'Status', + 'RpcError', + 'RpcContext', + 'Call', + 'ChannelCredentials', + 'CallCredentials', + 'AuthMetadataContext', + 'AuthMetadataPluginCallback', + 'AuthMetadataPlugin', + 'Compression', + 'ClientCallDetails', + 'ServerCertificateConfiguration', + 'ServerCredentials', + 'LocalConnectionType', + 'UnaryUnaryMultiCallable', + 'UnaryStreamMultiCallable', + 'StreamUnaryMultiCallable', + 'StreamStreamMultiCallable', + 'UnaryUnaryClientInterceptor', + 'UnaryStreamClientInterceptor', + 'StreamUnaryClientInterceptor', + 'StreamStreamClientInterceptor', + 'Channel', + 'ServicerContext', + 'RpcMethodHandler', + 'HandlerCallDetails', + 'GenericRpcHandler', + 'ServiceRpcHandler', + 'Server', + 'ServerInterceptor', + 'unary_unary_rpc_method_handler', + 'unary_stream_rpc_method_handler', + 'stream_unary_rpc_method_handler', + 'stream_stream_rpc_method_handler', + 'method_handlers_generic_handler', + 'ssl_channel_credentials', + 'metadata_call_credentials', + 'access_token_call_credentials', + 'composite_call_credentials', + 'composite_channel_credentials', + 'local_channel_credentials', + 'local_server_credentials', + 'alts_channel_credentials', + 'alts_server_credentials', + 'sgxratls_channel_credentials', + 'sgxratls_server_credentials', + 'ssl_server_credentials', + 'ssl_server_certificate_configuration', + 'dynamic_ssl_server_credentials', + 'channel_ready_future', + 'insecure_channel', + 'secure_channel', + 'intercept_channel', + 'server', + 'protos', + 'services', + 'protos_and_services', + 'xds_channel_credentials', + 'xds_server_credentials', + 'insecure_server_credentials', +) + +############################### Extension Shims ################################ + +# Here to maintain backwards compatibility; avoid using these in new code! +try: + import grpc_tools + sys.modules.update({'grpc.tools': grpc_tools}) +except ImportError: + pass +try: + import grpc_health + sys.modules.update({'grpc.health': grpc_health}) +except ImportError: + pass +try: + import grpc_reflection + sys.modules.update({'grpc.reflection': grpc_reflection}) +except ImportError: + pass + +# Prevents import order issue in the case of renamed path. +if sys.version_info >= (3, 6) and __name__ == "grpc": + from grpc import aio # pylint: disable=ungrouped-imports + sys.modules.update({'grpc.aio': aio}) diff --git a/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi new file mode 100644 index 000000000..59645b465 --- /dev/null +++ b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -0,0 +1,791 @@ +# Copyright 2015 gRPC 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. + +cimport libc.time + +ctypedef ssize_t intptr_t +ctypedef size_t uintptr_t +ctypedef signed char int8_t +ctypedef signed short int16_t +ctypedef signed int int32_t +ctypedef signed long long int64_t +ctypedef unsigned char uint8_t +ctypedef unsigned short uint16_t +ctypedef unsigned int uint32_t +ctypedef unsigned long long uint64_t + + +cdef extern from "grpc/support/alloc.h": + + void *gpr_malloc(size_t size) nogil + void *gpr_zalloc(size_t size) nogil + void gpr_free(void *ptr) nogil + void *gpr_realloc(void *p, size_t size) nogil + + +cdef extern from "grpc/byte_buffer_reader.h": + + struct grpc_byte_buffer_reader: + # We don't care about the internals + pass + + +cdef extern from "grpc/impl/codegen/grpc_types.h": + ctypedef struct grpc_experimental_completion_queue_functor: + void (*functor_run)(grpc_experimental_completion_queue_functor*, int); + + +cdef extern from "grpc/grpc.h": + + ctypedef struct grpc_slice: + # don't worry about writing out the members of grpc_slice; we never access + # them directly. + pass + + grpc_slice grpc_slice_ref(grpc_slice s) nogil + void grpc_slice_unref(grpc_slice s) nogil + grpc_slice grpc_empty_slice() nogil + grpc_slice grpc_slice_new(void *p, size_t len, void (*destroy)(void *)) nogil + grpc_slice grpc_slice_new_with_len( + void *p, size_t len, void (*destroy)(void *, size_t)) nogil + grpc_slice grpc_slice_malloc(size_t length) nogil + grpc_slice grpc_slice_from_copied_string(const char *source) nogil + grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t len) nogil + grpc_slice grpc_slice_copy(grpc_slice s) nogil + + # Declare functions for function-like macros (because Cython)... + void *grpc_slice_start_ptr "GRPC_SLICE_START_PTR" (grpc_slice s) nogil + size_t grpc_slice_length "GRPC_SLICE_LENGTH" (grpc_slice s) nogil + + const int GPR_MS_PER_SEC + const int GPR_US_PER_SEC + const int GPR_NS_PER_SEC + + ctypedef enum gpr_clock_type: + GPR_CLOCK_MONOTONIC + GPR_CLOCK_REALTIME + GPR_CLOCK_PRECISE + GPR_TIMESPAN + + ctypedef struct gpr_timespec: + int64_t seconds "tv_sec" + int32_t nanoseconds "tv_nsec" + gpr_clock_type clock_type + + gpr_timespec gpr_time_0(gpr_clock_type type) nogil + gpr_timespec gpr_inf_future(gpr_clock_type type) nogil + gpr_timespec gpr_inf_past(gpr_clock_type type) nogil + + gpr_timespec gpr_now(gpr_clock_type clock) nogil + + gpr_timespec gpr_convert_clock_type(gpr_timespec t, + gpr_clock_type target_clock) nogil + + gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type type) nogil + gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type type) nogil + double gpr_timespec_to_micros(gpr_timespec t) nogil + + gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) nogil + + int gpr_time_cmp(gpr_timespec a, gpr_timespec b) nogil + + ctypedef struct grpc_byte_buffer: + # We don't care about the internals. + pass + + grpc_byte_buffer *grpc_raw_byte_buffer_create(grpc_slice *slices, + size_t nslices) nogil + size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) nogil + void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer) nogil + + int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, + grpc_byte_buffer *buffer) nogil + int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, + grpc_slice *slice) nogil + void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) nogil + + ctypedef enum grpc_status_code: + GRPC_STATUS_OK + GRPC_STATUS_CANCELLED + GRPC_STATUS_UNKNOWN + GRPC_STATUS_INVALID_ARGUMENT + GRPC_STATUS_DEADLINE_EXCEEDED + GRPC_STATUS_NOT_FOUND + GRPC_STATUS_ALREADY_EXISTS + GRPC_STATUS_PERMISSION_DENIED + GRPC_STATUS_UNAUTHENTICATED + GRPC_STATUS_RESOURCE_EXHAUSTED + GRPC_STATUS_FAILED_PRECONDITION + GRPC_STATUS_ABORTED + GRPC_STATUS_OUT_OF_RANGE + GRPC_STATUS_UNIMPLEMENTED + GRPC_STATUS_INTERNAL + GRPC_STATUS_UNAVAILABLE + GRPC_STATUS_DATA_LOSS + GRPC_STATUS__DO_NOT_USE + + const char *GRPC_ARG_ENABLE_CENSUS + const char *GRPC_ARG_MAX_CONCURRENT_STREAMS + const char *GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH + const char *GRPC_ARG_MAX_SEND_MESSAGE_LENGTH + const char *GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER + const char *GRPC_ARG_DEFAULT_AUTHORITY + const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING + const char *GRPC_ARG_SECONDARY_USER_AGENT_STRING + const char *GRPC_SSL_TARGET_NAME_OVERRIDE_ARG + const char *GRPC_SSL_SESSION_CACHE_ARG + const char *_GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \ + "GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM" + const char *GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL + const char *GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET + + const int GRPC_WRITE_BUFFER_HINT + const int GRPC_WRITE_NO_COMPRESS + const int GRPC_WRITE_USED_MASK + + const int GRPC_INITIAL_METADATA_WAIT_FOR_READY + const int GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET + const int GRPC_INITIAL_METADATA_USED_MASK + + const int GRPC_MAX_COMPLETION_QUEUE_PLUCKERS + + ctypedef struct grpc_completion_queue: + # We don't care about the internals (and in fact don't know them) + pass + + ctypedef struct grpc_channel: + # We don't care about the internals (and in fact don't know them) + pass + + ctypedef struct grpc_server: + # We don't care about the internals (and in fact don't know them) + pass + + ctypedef struct grpc_call: + # We don't care about the internals (and in fact don't know them) + pass + + ctypedef enum grpc_arg_type: + GRPC_ARG_STRING + GRPC_ARG_INTEGER + GRPC_ARG_POINTER + + ctypedef struct grpc_arg_pointer_vtable: + void *(*copy)(void *) + void (*destroy)(void *) + int (*cmp)(void *, void *) + + ctypedef struct grpc_arg_value_pointer: + void *address "p" + grpc_arg_pointer_vtable *vtable + + union grpc_arg_value: + char *string + int integer + grpc_arg_value_pointer pointer + + ctypedef struct grpc_arg: + grpc_arg_type type + char *key + grpc_arg_value value + + ctypedef struct grpc_channel_args: + size_t arguments_length "num_args" + grpc_arg *arguments "args" + + ctypedef enum grpc_stream_compression_level: + GRPC_STREAM_COMPRESS_LEVEL_NONE + GRPC_STREAM_COMPRESS_LEVEL_LOW + GRPC_STREAM_COMPRESS_LEVEL_MED + GRPC_STREAM_COMPRESS_LEVEL_HIGH + + ctypedef enum grpc_call_error: + GRPC_CALL_OK + GRPC_CALL_ERROR + GRPC_CALL_ERROR_NOT_ON_SERVER + GRPC_CALL_ERROR_NOT_ON_CLIENT + GRPC_CALL_ERROR_ALREADY_ACCEPTED + GRPC_CALL_ERROR_ALREADY_INVOKED + GRPC_CALL_ERROR_NOT_INVOKED + GRPC_CALL_ERROR_ALREADY_FINISHED + GRPC_CALL_ERROR_TOO_MANY_OPERATIONS + GRPC_CALL_ERROR_INVALID_FLAGS + GRPC_CALL_ERROR_INVALID_METADATA + + ctypedef enum grpc_cq_completion_type: + GRPC_CQ_NEXT + GRPC_CQ_PLUCK + + ctypedef enum grpc_cq_polling_type: + GRPC_CQ_DEFAULT_POLLING + GRPC_CQ_NON_LISTENING + GRPC_CQ_NON_POLLING + + ctypedef struct grpc_completion_queue_attributes: + int version + grpc_cq_completion_type cq_completion_type + grpc_cq_polling_type cq_polling_type + + ctypedef enum grpc_connectivity_state: + GRPC_CHANNEL_IDLE + GRPC_CHANNEL_CONNECTING + GRPC_CHANNEL_READY + GRPC_CHANNEL_TRANSIENT_FAILURE + GRPC_CHANNEL_SHUTDOWN + + ctypedef struct grpc_metadata: + grpc_slice key + grpc_slice value + # ignore the 'internal_data.obfuscated' fields. + + ctypedef enum grpc_completion_type: + GRPC_QUEUE_SHUTDOWN + GRPC_QUEUE_TIMEOUT + GRPC_OP_COMPLETE + + ctypedef struct grpc_event: + grpc_completion_type type + int success + void *tag + + ctypedef struct grpc_metadata_array: + size_t count + size_t capacity + grpc_metadata *metadata + + void grpc_metadata_array_init(grpc_metadata_array *array) nogil + void grpc_metadata_array_destroy(grpc_metadata_array *array) nogil + + ctypedef struct grpc_call_details: + grpc_slice method + grpc_slice host + gpr_timespec deadline + + void grpc_call_details_init(grpc_call_details *details) nogil + void grpc_call_details_destroy(grpc_call_details *details) nogil + + ctypedef enum grpc_op_type: + GRPC_OP_SEND_INITIAL_METADATA + GRPC_OP_SEND_MESSAGE + GRPC_OP_SEND_CLOSE_FROM_CLIENT + GRPC_OP_SEND_STATUS_FROM_SERVER + GRPC_OP_RECV_INITIAL_METADATA + GRPC_OP_RECV_MESSAGE + GRPC_OP_RECV_STATUS_ON_CLIENT + GRPC_OP_RECV_CLOSE_ON_SERVER + + ctypedef struct grpc_op_send_initial_metadata_maybe_compression_level: + uint8_t is_set + grpc_compression_level level + + ctypedef struct grpc_op_data_send_initial_metadata: + size_t count + grpc_metadata *metadata + grpc_op_send_initial_metadata_maybe_compression_level maybe_compression_level + + ctypedef struct grpc_op_data_send_status_from_server: + size_t trailing_metadata_count + grpc_metadata *trailing_metadata + grpc_status_code status + grpc_slice *status_details + + ctypedef struct grpc_op_data_recv_status_on_client: + grpc_metadata_array *trailing_metadata + grpc_status_code *status + grpc_slice *status_details + char** error_string + + ctypedef struct grpc_op_data_recv_close_on_server: + int *cancelled + + ctypedef struct grpc_op_data_send_message: + grpc_byte_buffer *send_message + + ctypedef struct grpc_op_data_receive_message: + grpc_byte_buffer **receive_message "recv_message" + + ctypedef struct grpc_op_data_receive_initial_metadata: + grpc_metadata_array *receive_initial_metadata "recv_initial_metadata" + + union grpc_op_data: + grpc_op_data_send_initial_metadata send_initial_metadata + grpc_op_data_send_message send_message + grpc_op_data_send_status_from_server send_status_from_server + grpc_op_data_receive_initial_metadata receive_initial_metadata "recv_initial_metadata" + grpc_op_data_receive_message receive_message "recv_message" + grpc_op_data_recv_status_on_client receive_status_on_client "recv_status_on_client" + grpc_op_data_recv_close_on_server receive_close_on_server "recv_close_on_server" + + ctypedef struct grpc_op: + grpc_op_type type "op" + uint32_t flags + void * reserved + grpc_op_data data + + void grpc_init() nogil + void grpc_shutdown() nogil + void grpc_shutdown_blocking() nogil + int grpc_is_initialized() nogil + + ctypedef struct grpc_completion_queue_factory: + pass + + grpc_completion_queue_factory *grpc_completion_queue_factory_lookup( + const grpc_completion_queue_attributes* attributes) nogil + grpc_completion_queue *grpc_completion_queue_create( + const grpc_completion_queue_factory* factory, + const grpc_completion_queue_attributes* attr, void* reserved) nogil + grpc_completion_queue *grpc_completion_queue_create_for_next(void *reserved) nogil + + grpc_event grpc_completion_queue_next(grpc_completion_queue *cq, + gpr_timespec deadline, + void *reserved) nogil + grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cq, void *tag, + gpr_timespec deadline, + void *reserved) nogil + void grpc_completion_queue_shutdown(grpc_completion_queue *cq) nogil + void grpc_completion_queue_destroy(grpc_completion_queue *cq) nogil + + grpc_completion_queue *grpc_completion_queue_create_for_callback( + grpc_experimental_completion_queue_functor* shutdown_callback, + void *reserved) nogil + + grpc_call_error grpc_call_start_batch( + grpc_call *call, const grpc_op *ops, size_t nops, void *tag, + void *reserved) nogil + grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved) nogil + grpc_call_error grpc_call_cancel_with_status(grpc_call *call, + grpc_status_code status, + const char *description, + void *reserved) nogil + char *grpc_call_get_peer(grpc_call *call) nogil + void grpc_call_unref(grpc_call *call) nogil + + grpc_channel *grpc_insecure_channel_create(const char *target, + const grpc_channel_args *args, + void *reserved) nogil + grpc_call *grpc_channel_create_call( + grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, + grpc_completion_queue *completion_queue, grpc_slice method, + const grpc_slice *host, gpr_timespec deadline, void *reserved) nogil + grpc_connectivity_state grpc_channel_check_connectivity_state( + grpc_channel *channel, int try_to_connect) nogil + void grpc_channel_watch_connectivity_state( + grpc_channel *channel, grpc_connectivity_state last_observed_state, + gpr_timespec deadline, grpc_completion_queue *cq, void *tag) nogil + char *grpc_channel_get_target(grpc_channel *channel) nogil + void grpc_channel_destroy(grpc_channel *channel) nogil + + grpc_server *grpc_server_create( + const grpc_channel_args *args, void *reserved) nogil + grpc_call_error grpc_server_request_call( + grpc_server *server, grpc_call **call, grpc_call_details *details, + grpc_metadata_array *request_metadata, grpc_completion_queue + *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void + *tag_new) nogil + void grpc_server_register_completion_queue(grpc_server *server, + grpc_completion_queue *cq, + void *reserved) nogil + + ctypedef struct grpc_server_config_fetcher: + pass + + void grpc_server_set_config_fetcher( + grpc_server* server, grpc_server_config_fetcher* config_fetcher) nogil + + ctypedef struct grpc_server_xds_status_notifier: + void (*on_serving_status_update)(void* user_data, const char* uri, + grpc_status_code code, + const char* error_message) + void* user_data; + + grpc_server_config_fetcher* grpc_server_config_fetcher_xds_create( + grpc_server_xds_status_notifier notifier, + const grpc_channel_args* args) nogil + + + int grpc_server_add_insecure_http2_port( + grpc_server *server, const char *addr) nogil + void grpc_server_start(grpc_server *server) nogil + void grpc_server_shutdown_and_notify( + grpc_server *server, grpc_completion_queue *cq, void *tag) nogil + void grpc_server_cancel_all_calls(grpc_server *server) nogil + void grpc_server_destroy(grpc_server *server) nogil + + char* grpc_channelz_get_top_channels(intptr_t start_channel_id) + char* grpc_channelz_get_servers(intptr_t start_server_id) + char* grpc_channelz_get_server(intptr_t server_id) + char* grpc_channelz_get_server_sockets(intptr_t server_id, + intptr_t start_socket_id, + intptr_t max_results) + char* grpc_channelz_get_channel(intptr_t channel_id) + char* grpc_channelz_get_subchannel(intptr_t subchannel_id) + char* grpc_channelz_get_socket(intptr_t socket_id) + + grpc_slice grpc_dump_xds_configs() nogil + +cdef extern from "grpc/grpc_security.h": + + # Declare this as an enum, this is the only way to make it a const in + # cython + enum: GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX + + ctypedef enum grpc_ssl_roots_override_result: + GRPC_SSL_ROOTS_OVERRIDE_OK + GRPC_SSL_ROOTS_OVERRIDE_FAILED_PERMANENTLY + GRPC_SSL_ROOTS_OVERRIDE_FAILED + + ctypedef enum grpc_ssl_client_certificate_request_type: + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, + GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY + GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY + GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY + GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY + + ctypedef enum grpc_security_level: + GRPC_SECURITY_MIN + GRPC_SECURITY_NONE = GRPC_SECURITY_MIN + GRPC_INTEGRITY_ONLY + GRPC_PRIVACY_AND_INTEGRITY + GRPC_SECURITY_MAX = GRPC_PRIVACY_AND_INTEGRITY + + ctypedef enum grpc_ssl_certificate_config_reload_status: + GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED + GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW + GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL + + ctypedef struct grpc_ssl_server_certificate_config: + # We don't care about the internals + pass + + ctypedef struct grpc_ssl_server_credentials_options: + # We don't care about the internals + pass + + grpc_ssl_server_certificate_config * grpc_ssl_server_certificate_config_create( + const char *pem_root_certs, + const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, + size_t num_key_cert_pairs) + + void grpc_ssl_server_certificate_config_destroy(grpc_ssl_server_certificate_config *config) + + ctypedef grpc_ssl_certificate_config_reload_status (*grpc_ssl_server_certificate_config_callback)( + void *user_data, + grpc_ssl_server_certificate_config **config) + + grpc_ssl_server_credentials_options *grpc_ssl_server_credentials_create_options_using_config( + grpc_ssl_client_certificate_request_type client_certificate_request, + grpc_ssl_server_certificate_config *certificate_config) + + grpc_ssl_server_credentials_options* grpc_ssl_server_credentials_create_options_using_config_fetcher( + grpc_ssl_client_certificate_request_type client_certificate_request, + grpc_ssl_server_certificate_config_callback cb, + void *user_data) + + grpc_server_credentials *grpc_ssl_server_credentials_create_with_options( + grpc_ssl_server_credentials_options *options) + + ctypedef struct grpc_ssl_pem_key_cert_pair: + const char *private_key + const char *certificate_chain "cert_chain" + + ctypedef struct grpc_channel_credentials: + # We don't care about the internals (and in fact don't know them) + pass + + ctypedef struct grpc_call_credentials: + # We don't care about the internals (and in fact don't know them) + pass + + ctypedef struct grpc_ssl_session_cache: + # We don't care about the internals (and in fact don't know them) + pass + + ctypedef struct verify_peer_options: + # We don't care about the internals (and in fact don't know them) + pass + + ctypedef void (*grpc_ssl_roots_override_callback)(char **pem_root_certs) + + grpc_ssl_session_cache *grpc_ssl_session_cache_create_lru(size_t capacity) + void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache) + + void grpc_set_ssl_roots_override_callback( + grpc_ssl_roots_override_callback cb) nogil + + grpc_channel_credentials *grpc_google_default_credentials_create(grpc_call_credentials* call_credentials) nogil + grpc_channel_credentials *grpc_ssl_credentials_create( + const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, + verify_peer_options *verify_options, void *reserved) nogil + grpc_channel_credentials *grpc_composite_channel_credentials_create( + grpc_channel_credentials *creds1, grpc_call_credentials *creds2, + void *reserved) nogil + void grpc_channel_credentials_release(grpc_channel_credentials *creds) nogil + + grpc_channel_credentials *grpc_xds_credentials_create( + grpc_channel_credentials *fallback_creds) nogil + + grpc_channel_credentials *grpc_insecure_credentials_create() nogil + + grpc_server_credentials *grpc_xds_server_credentials_create( + grpc_server_credentials *fallback_creds) nogil + + grpc_server_credentials *grpc_insecure_server_credentials_create() nogil + + grpc_call_credentials *grpc_composite_call_credentials_create( + grpc_call_credentials *creds1, grpc_call_credentials *creds2, + void *reserved) nogil + grpc_call_credentials *grpc_google_compute_engine_credentials_create( + void *reserved) nogil + grpc_call_credentials *grpc_service_account_jwt_access_credentials_create( + const char *json_key, + gpr_timespec token_lifetime, void *reserved) nogil + grpc_call_credentials *grpc_google_refresh_token_credentials_create( + const char *json_refresh_token, void *reserved) nogil + grpc_call_credentials *grpc_google_iam_credentials_create( + const char *authorization_token, const char *authority_selector, + void *reserved) nogil + void grpc_call_credentials_release(grpc_call_credentials *creds) nogil + + grpc_channel *grpc_secure_channel_create( + grpc_channel_credentials *creds, const char *target, + const grpc_channel_args *args, void *reserved) nogil + + ctypedef struct grpc_server_credentials: + # We don't care about the internals (and in fact don't know them) + pass + + void grpc_server_credentials_release(grpc_server_credentials *creds) nogil + + int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, + grpc_server_credentials *creds) nogil + + grpc_call_error grpc_call_set_credentials(grpc_call *call, + grpc_call_credentials *creds) nogil + + ctypedef struct grpc_auth_context: + # We don't care about the internals (and in fact don't know them) + pass + + ctypedef struct grpc_auth_metadata_context: + const char *service_url + const char *method_name + const grpc_auth_context *channel_auth_context + + ctypedef void (*grpc_credentials_plugin_metadata_cb)( + void *user_data, const grpc_metadata *creds_md, size_t num_creds_md, + grpc_status_code status, const char *error_details) nogil + + ctypedef struct grpc_metadata_credentials_plugin: + int (*get_metadata)( + void *state, grpc_auth_metadata_context context, + grpc_credentials_plugin_metadata_cb cb, void *user_data, + grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], + size_t *num_creds_md, grpc_status_code *status, + const char **error_details) except * + void (*destroy)(void *state) except * + void *state + const char *type + + grpc_call_credentials *grpc_metadata_credentials_create_from_plugin( + grpc_metadata_credentials_plugin plugin, grpc_security_level min_security_level, void *reserved) nogil + + ctypedef struct grpc_auth_property_iterator: + pass + + ctypedef struct grpc_auth_property: + char *name + char *value + size_t value_length + + grpc_auth_property *grpc_auth_property_iterator_next( + grpc_auth_property_iterator *it) + + grpc_auth_property_iterator grpc_auth_context_property_iterator( + const grpc_auth_context *ctx) + + grpc_auth_property_iterator grpc_auth_context_peer_identity( + const grpc_auth_context *ctx) + + char *grpc_auth_context_peer_identity_property_name( + const grpc_auth_context *ctx) + + grpc_auth_property_iterator grpc_auth_context_find_properties_by_name( + const grpc_auth_context *ctx, const char *name) + + grpc_auth_context_peer_is_authenticated( + const grpc_auth_context *ctx) + + grpc_auth_context *grpc_call_auth_context(grpc_call *call) + + void grpc_auth_context_release(grpc_auth_context *context) + + grpc_channel_credentials *grpc_local_credentials_create( + grpc_local_connect_type type) + grpc_server_credentials *grpc_local_server_credentials_create( + grpc_local_connect_type type) + + ctypedef struct grpc_alts_credentials_options: + # We don't care about the internals (and in fact don't know them) + pass + + grpc_channel_credentials *grpc_alts_credentials_create( + const grpc_alts_credentials_options *options) + grpc_server_credentials *grpc_alts_server_credentials_create( + const grpc_alts_credentials_options *options) + + grpc_alts_credentials_options* grpc_alts_credentials_client_options_create() + grpc_alts_credentials_options* grpc_alts_credentials_server_options_create() + void grpc_alts_credentials_options_destroy(grpc_alts_credentials_options *options) + void grpc_alts_credentials_client_options_add_target_service_account(grpc_alts_credentials_options *options, const char *service_account) + + ctypedef enum grpc_tls_server_verification_option: + GRPC_TLS_SERVER_VERIFICATION + GRPC_TLS_SKIP_HOSTNAME_VERIFICATION + GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION + + ctypedef struct grpc_tls_error_details: + pass + + ctypedef struct grpc_tls_identity_pairs: + pass + + ctypedef struct grpc_tls_certificate_provider: + pass + + ctypedef struct grpc_tls_credentials_options: + pass + + ctypedef struct grpc_tls_server_authorization_check_arg: + pass + + ctypedef struct grpc_tls_server_authorization_check_config: + pass + + grpc_tls_identity_pairs* grpc_tls_identity_pairs_create(); + + void grpc_tls_identity_pairs_add_pair(grpc_tls_identity_pairs* pairs, + const char* private_key, + const char* cert_chain); + + void grpc_tls_identity_pairs_destroy(grpc_tls_identity_pairs* pairs); + + grpc_tls_certificate_provider* grpc_tls_certificate_provider_static_data_create( + const char* root_certificate, grpc_tls_identity_pairs* pem_key_cert_pairs); + + grpc_tls_certificate_provider* grpc_tls_certificate_provider_file_watcher_create( + const char* private_key_path, const char* identity_certificate_path, + const char* root_cert_path, unsigned int refresh_interval_sec); + + void grpc_tls_certificate_provider_release( + grpc_tls_certificate_provider* provider); + + grpc_tls_credentials_options* grpc_tls_credentials_options_create() + + void grpc_tls_credentials_options_set_cert_request_type( + grpc_tls_credentials_options* options, + grpc_ssl_client_certificate_request_type type); + + void grpc_tls_credentials_options_set_server_verification_option( + grpc_tls_credentials_options* options, + grpc_tls_server_verification_option server_verification_option); + + void grpc_tls_credentials_options_set_certificate_provider( + grpc_tls_credentials_options* options, + grpc_tls_certificate_provider* provider); + + void grpc_tls_credentials_options_watch_root_certs( + grpc_tls_credentials_options* options); + + void grpc_tls_credentials_options_set_root_cert_name( + grpc_tls_credentials_options* options, const char* root_cert_name); + + void grpc_tls_credentials_options_watch_identity_key_cert_pairs( + grpc_tls_credentials_options* options); + + void grpc_tls_credentials_options_set_identity_cert_name( + grpc_tls_credentials_options* options, const char* identity_cert_name); + + void grpc_tls_credentials_options_set_server_authorization_check_config( + grpc_tls_credentials_options* options, + grpc_tls_server_authorization_check_config* config); + + grpc_tls_server_authorization_check_config* grpc_tls_server_authorization_check_config_create( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*destruct)(void* config_user_data)); + + void grpc_tls_server_authorization_check_config_release( + grpc_tls_server_authorization_check_config* config); + + grpc_channel_credentials* grpc_tls_credentials_create( + grpc_tls_credentials_options* options); + + grpc_server_credentials* grpc_tls_server_credentials_create( + grpc_tls_credentials_options* options); + +cdef extern from "grpc/compression.h": + + ctypedef enum grpc_compression_algorithm: + GRPC_COMPRESS_NONE + GRPC_COMPRESS_DEFLATE + GRPC_COMPRESS_GZIP + GRPC_COMPRESS_STREAM_GZIP + GRPC_COMPRESS_ALGORITHMS_COUNT + + ctypedef enum grpc_compression_level: + GRPC_COMPRESS_LEVEL_NONE + GRPC_COMPRESS_LEVEL_LOW + GRPC_COMPRESS_LEVEL_MED + GRPC_COMPRESS_LEVEL_HIGH + GRPC_COMPRESS_LEVEL_COUNT + + ctypedef struct grpc_compression_options: + uint32_t enabled_algorithms_bitset + + int grpc_compression_algorithm_parse( + grpc_slice value, grpc_compression_algorithm *algorithm) nogil + int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm, + const char **name) nogil + grpc_compression_algorithm grpc_compression_algorithm_for_level( + grpc_compression_level level, uint32_t accepted_encodings) nogil + void grpc_compression_options_init(grpc_compression_options *opts) nogil + void grpc_compression_options_enable_algorithm( + grpc_compression_options *opts, + grpc_compression_algorithm algorithm) nogil + void grpc_compression_options_disable_algorithm( + grpc_compression_options *opts, + grpc_compression_algorithm algorithm) nogil + int grpc_compression_options_is_algorithm_enabled( + const grpc_compression_options *opts, + grpc_compression_algorithm algorithm) nogil + +cdef extern from "grpc/impl/codegen/compression_types.h": + + const char *_GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \ + "GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY" + + +cdef extern from "grpc/grpc_security_constants.h": + + ctypedef enum grpc_local_connect_type: + UDS + LOCAL_TCP + + +cdef extern from "src/core/lib/iomgr/error.h": + const grpc_error* GRPC_ERROR_CANCELLED diff --git a/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/_cygrpc/sgx_ra_tls.pxd.pxi b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/_cygrpc/sgx_ra_tls.pxd.pxi new file mode 100644 index 000000000..56241dd70 --- /dev/null +++ b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/_cygrpc/sgx_ra_tls.pxd.pxi @@ -0,0 +1,44 @@ +# Copyright 2015 gRPC 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. + +from libcpp.vector cimport vector as cppvector +from libcpp.string cimport string as cppstring + +cdef extern from "grpcpp/security/sgx/sgx_ra_tls.h" namespace "grpc::sgx": + struct sgx_mrs_context: + pass + +cdef extern from "grpcpp/security/sgx/sgx_ra_tls.h" namespace "grpc::sgx": + cdef void grpc_sgx_ra_tls_verify_init_with_context "grpc::sgx::ra_tls_verify_init"(sgx_mrs_context); + +cdef extern from "grpcpp/security/sgx/sgx_ra_tls.h" namespace "grpc::sgx": + cdef void grpc_sgx_ra_tls_verify_init_with_config "grpc::sgx::ra_tls_verify_init"(const char *); + +cdef extern from "grpcpp/security/sgx/sgx_ra_tls.h" namespace "grpc::sgx": + cdef cppvector[cppstring] grpc_sgx_ra_tls_get_key_cert "grpc::sgx::ra_tls_get_key_cert"() + +cdef extern from "grpcpp/security/sgx/sgx_ra_tls.h" namespace "grpc::sgx": + cdef int grpc_sgx_ra_tls_auth_check_schedule "grpc::sgx::ra_tls_auth_check_schedule"( + void *, grpc_tls_server_authorization_check_arg *); + +cdef class SGXChannelCredentials(ChannelCredentials): + cdef grpc_tls_identity_pairs *c_pairs + + cdef grpc_tls_certificate_provider *c_provider + + cdef grpc_tls_credentials_options *c_options + + cdef grpc_tls_server_authorization_check_config *c_check_config + + cdef grpc_channel_credentials *c(self) except * diff --git a/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/_cygrpc/sgx_ra_tls.pyx.pxi b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/_cygrpc/sgx_ra_tls.pyx.pxi new file mode 100644 index 000000000..9ac318ccf --- /dev/null +++ b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/_cygrpc/sgx_ra_tls.pyx.pxi @@ -0,0 +1,122 @@ +# Copyright 2015 gRPC 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. + +cdef class SGXChannelCredentials(ChannelCredentials): + + def __cinit__(self, + const char* config_json): + # tls credentials options + self.c_options = grpc_tls_credentials_options_create() + + # tls certificate provider + cdef cppvector[cppstring] cpp_key_crt = grpc_sgx_ra_tls_get_key_cert() + + self.c_pairs = grpc_tls_identity_pairs_create(); + + grpc_tls_identity_pairs_add_pair( + self.c_pairs, cpp_key_crt[0].c_str(), cpp_key_crt[1].c_str()) + + self.c_provider = grpc_tls_certificate_provider_static_data_create(NULL, self.c_pairs); + + grpc_tls_credentials_options_set_certificate_provider(self.c_options, self.c_provider) + + # grpc_tls_credentials_options_watch_root_certs(self.c_options) + + grpc_tls_credentials_options_watch_identity_key_cert_pairs(self.c_options) + + grpc_tls_credentials_options_set_cert_request_type( + self.c_options, GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY) + + grpc_tls_credentials_options_set_root_cert_name(self.c_options, "") + + grpc_tls_credentials_options_set_identity_cert_name(self.c_options, "") + + # authorization check + grpc_sgx_ra_tls_verify_init_with_config(config_json) + + grpc_tls_credentials_options_set_server_verification_option( + self.c_options, GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION) + + self.c_check_config = grpc_tls_server_authorization_check_config_create( + NULL, grpc_sgx_ra_tls_auth_check_schedule, NULL, NULL) + + grpc_tls_credentials_options_set_server_authorization_check_config( + self.c_options, self.c_check_config) + + def __dealloc__(self): + if self.c_pairs != NULL: + # grpc_tls_identity_pairs_destroy(self.c_pairs) + self.c_pairs = NULL + + if self.c_provider != NULL: + grpc_tls_certificate_provider_release(self.c_provider) + self.c_provider = NULL + + if self.c_check_config != NULL: + grpc_tls_server_authorization_check_config_release(self.c_check_config) + self.c_check_config = NULL + + cdef grpc_channel_credentials *c(self) except *: + return grpc_tls_credentials_create(self.c_options) + + +def channel_credentials_sgxratls(config_json): + config_json = bytes(config_json, encoding = "ascii") + return SGXChannelCredentials(config_json) + +def server_credentials_sgxratls(config_json): + # tls credentials options + cdef grpc_tls_credentials_options *c_options = grpc_tls_credentials_options_create() + + # tls certificate provider + cdef cppvector[cppstring] cpp_key_crt = grpc_sgx_ra_tls_get_key_cert() + + cdef grpc_tls_identity_pairs *c_pairs = grpc_tls_identity_pairs_create(); + + grpc_tls_identity_pairs_add_pair( + c_pairs, cpp_key_crt[0].c_str(), cpp_key_crt[1].c_str()) + + grpc_tls_credentials_options_watch_identity_key_cert_pairs(c_options) + + # grpc_tls_credentials_options_watch_root_certs(c_options) + + cdef grpc_tls_certificate_provider *c_provider = \ + grpc_tls_certificate_provider_static_data_create(NULL, c_pairs); + + grpc_tls_credentials_options_set_certificate_provider(c_options, c_provider) + + grpc_tls_credentials_options_set_cert_request_type( + c_options, GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY) + + grpc_tls_credentials_options_set_root_cert_name(c_options, "") + + grpc_tls_credentials_options_set_identity_cert_name(c_options, "") + + # authorization check + config_json = bytes(config_json, encoding = "ascii") + grpc_sgx_ra_tls_verify_init_with_config(config_json) + + grpc_tls_credentials_options_set_server_verification_option( + c_options, GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION) + + cdef grpc_tls_server_authorization_check_config *c_check_config = \ + grpc_tls_server_authorization_check_config_create(NULL, grpc_sgx_ra_tls_auth_check_schedule, NULL, NULL) + + grpc_tls_credentials_options_set_server_authorization_check_config( + c_options, c_check_config) + + # credentials + cdef ServerCredentials credentials = ServerCredentials() + credentials.c_credentials = grpc_tls_server_credentials_create(c_options) + return credentials diff --git a/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/cygrpc.pxd b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/cygrpc.pxd new file mode 100644 index 000000000..85bb630f4 --- /dev/null +++ b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/cygrpc.pxd @@ -0,0 +1,57 @@ +# Copyright 2015 gRPC 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. +# distutils: language=c++ + +cimport cpython + +include "_cygrpc/grpc.pxi" + +include "_cygrpc/arguments.pxd.pxi" +include "_cygrpc/call.pxd.pxi" +include "_cygrpc/channel.pxd.pxi" +include "_cygrpc/credentials.pxd.pxi" +include "_cygrpc/completion_queue.pxd.pxi" +include "_cygrpc/event.pxd.pxi" +include "_cygrpc/metadata.pxd.pxi" +include "_cygrpc/operation.pxd.pxi" +include "_cygrpc/propagation_bits.pxd.pxi" +include "_cygrpc/records.pxd.pxi" +include "_cygrpc/security.pxd.pxi" +include "_cygrpc/server.pxd.pxi" +include "_cygrpc/tag.pxd.pxi" +include "_cygrpc/time.pxd.pxi" +include "_cygrpc/vtable.pxd.pxi" +include "_cygrpc/_hooks.pxd.pxi" + +include "_cygrpc/iomgr.pxd.pxi" + +include "_cygrpc/grpc_gevent.pxd.pxi" + +IF UNAME_SYSNAME != "Windows": + include "_cygrpc/fork_posix.pxd.pxi" + +# Following pxi files are part of the Aio module +include "_cygrpc/aio/iomgr/socket.pxd.pxi" +include "_cygrpc/aio/iomgr/timer.pxd.pxi" +include "_cygrpc/aio/iomgr/resolver.pxd.pxi" +include "_cygrpc/aio/completion_queue.pxd.pxi" +include "_cygrpc/aio/rpc_status.pxd.pxi" +include "_cygrpc/aio/grpc_aio.pxd.pxi" +include "_cygrpc/aio/callback_common.pxd.pxi" +include "_cygrpc/aio/call.pxd.pxi" +include "_cygrpc/aio/channel.pxd.pxi" +include "_cygrpc/aio/server.pxd.pxi" + +# Following pxi files are part of the SGX +include "_cygrpc/sgx_ra_tls.pxd.pxi" diff --git a/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/cygrpc.pyx b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/cygrpc.pyx new file mode 100644 index 000000000..eda6fb16c --- /dev/null +++ b/sgx/grpc/v1.38.1/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -0,0 +1,102 @@ +# Copyright 2015 gRPC 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. +# distutils: language=c++ + +cimport cpython + +import logging +import os +import sys +import threading +import time + +import grpc + +try: + import asyncio +except ImportError: + # TODO(https://github.com/grpc/grpc/issues/19728) Improve how Aio Cython is + # distributed without breaking none compatible Python versions. For now, if + # Asyncio package is not available we just skip it. + pass + +# The only copy of Python logger for the Cython extension +_LOGGER = logging.getLogger(__name__) + +# TODO(atash): figure out why the coverage tool gets confused about the Cython +# coverage plugin when the following files don't have a '.pxi' suffix. +include "_cygrpc/grpc_string.pyx.pxi" +include "_cygrpc/arguments.pyx.pxi" +include "_cygrpc/call.pyx.pxi" +include "_cygrpc/channel.pyx.pxi" +include "_cygrpc/channelz.pyx.pxi" +include "_cygrpc/csds.pyx.pxi" +include "_cygrpc/credentials.pyx.pxi" +include "_cygrpc/completion_queue.pyx.pxi" +include "_cygrpc/event.pyx.pxi" +include "_cygrpc/metadata.pyx.pxi" +include "_cygrpc/operation.pyx.pxi" +include "_cygrpc/propagation_bits.pyx.pxi" +include "_cygrpc/records.pyx.pxi" +include "_cygrpc/security.pyx.pxi" +include "_cygrpc/server.pyx.pxi" +include "_cygrpc/tag.pyx.pxi" +include "_cygrpc/time.pyx.pxi" +include "_cygrpc/vtable.pyx.pxi" +include "_cygrpc/_hooks.pyx.pxi" + +include "_cygrpc/iomgr.pyx.pxi" + +include "_cygrpc/grpc_gevent.pyx.pxi" + +include "_cygrpc/thread.pyx.pxi" + +IF UNAME_SYSNAME == "Windows": + include "_cygrpc/fork_windows.pyx.pxi" +ELSE: + include "_cygrpc/fork_posix.pyx.pxi" + +# Following pxi files are part of the Aio module +include "_cygrpc/aio/iomgr/iomgr.pyx.pxi" +include "_cygrpc/aio/iomgr/socket.pyx.pxi" +include "_cygrpc/aio/iomgr/timer.pyx.pxi" +include "_cygrpc/aio/iomgr/resolver.pyx.pxi" +include "_cygrpc/aio/common.pyx.pxi" +include "_cygrpc/aio/rpc_status.pyx.pxi" +include "_cygrpc/aio/completion_queue.pyx.pxi" +include "_cygrpc/aio/callback_common.pyx.pxi" +include "_cygrpc/aio/grpc_aio.pyx.pxi" +include "_cygrpc/aio/call.pyx.pxi" +include "_cygrpc/aio/channel.pyx.pxi" +include "_cygrpc/aio/server.pyx.pxi" + +# Following pxi files are part of the SGX +include "_cygrpc/sgx_ra_tls.pyx.pxi" + +# +# initialize gRPC +# +cdef extern from "Python.h": + + int PyEval_InitThreads() + +cdef _initialize(): + # We have Python callbacks called by c-core threads, this ensures the GIL + # is initialized. + PyEval_InitThreads() + grpc_set_ssl_roots_override_callback( + ssl_roots_override_callback) + + +_initialize() diff --git a/sgx/imgs/vfl.png b/sgx/imgs/vfl.png new file mode 100644 index 000000000..04ccc03c1 Binary files /dev/null and b/sgx/imgs/vfl.png differ diff --git a/sgx/imgs/vfl_with_sgx.png b/sgx/imgs/vfl_with_sgx.png new file mode 100644 index 000000000..e1d7e2edd Binary files /dev/null and b/sgx/imgs/vfl_with_sgx.png differ diff --git a/sgx/tf/build.sh b/sgx/tf/build.sh deleted file mode 100755 index 466396ca0..000000000 --- a/sgx/tf/build.sh +++ /dev/null @@ -1,19 +0,0 @@ -set -e - -export BUILD_TYPE=Debug - -export MBEDTLS_PATH=${GRAPHENEDIR}/Examples/ra-tls-mbedtls -#export HELLO_PATH=${GRPC_PATH}/examples/cpp/helloworld - -# Build ra-tls-mbedtls -if [ ! -d "${MBEDTLS_PATH}/mbedtls" ]; then - ${MBEDTLS_PATH}/build_install.sh -fi - -# build c++ example -#cd ${HELLO_PATH} -#mkdir -p build -#cd build -#cmake -D CMAKE_PREFIX_PATH=${INSTALL_PREFIX} -D CMAKE_BUILD_TYPE=${BUILD_TYPE} .. -#make -j `nproc` -#cd - diff --git a/sgx/tf/sgx_tls_sample.diff b/sgx/tf/sgx_tls_sample.diff index 35198e624..98f6a9fbe 100644 --- a/sgx/tf/sgx_tls_sample.diff +++ b/sgx/tf/sgx_tls_sample.diff @@ -1,5 +1,5 @@ diff --git a/tensorflow/core/distributed_runtime/rpc/BUILD b/tensorflow/core/distributed_runtime/rpc/BUILD -index ce1a20a5ae9..a972f51f930 100644 +index ce1a20a5ae9..23f329096ca 100644 --- a/tensorflow/core/distributed_runtime/rpc/BUILD +++ b/tensorflow/core/distributed_runtime/rpc/BUILD @@ -41,9 +41,9 @@ filegroup( @@ -11,30 +11,22 @@ index ce1a20a5ae9..a972f51f930 100644 - linkopts = if_windows(["-DEFAULTLIB:ws2_32.lib"]), + srcs = ["grpc_util.cc", "grpc_sgx_ra_tls_utils.cc", "grpc_sgx_ra_tls_server.cc", "grpc_sgx_ra_tls_client.cc", "grpc_sgx_credentials_provider.cc"], + hdrs = ["grpc_util.h", "grpc_sgx_ra_tls.h", "grpc_sgx_ra_tls_utils.h", "grpc_sgx_credentials_provider.h"], -+ linkopts = ["-lmbedtls", "-lmbedx509", "-lmbedcrypto", "-lra_tls_attest"], ++ linkopts = ["-L/usr/local/lib", "-l:libmbedx509_gramine.a", "-l:libmbedcrypto_gramine.a", "-l:libcjson.a", "-l:libcjson_utils.a"], deps = [ "//tensorflow/core:lib", # Required to be able to overload TensorResponse parsing. diff --git a/tensorflow/core/distributed_runtime/rpc/grpc_channel.cc b/tensorflow/core/distributed_runtime/rpc/grpc_channel.cc -index 985b0454837..f0b462d06e9 100644 +index 985b0454837..2d2b6d68003 100644 --- a/tensorflow/core/distributed_runtime/rpc/grpc_channel.cc +++ b/tensorflow/core/distributed_runtime/rpc/grpc_channel.cc -@@ -36,6 +36,7 @@ limitations under the License. - #include "tensorflow/core/platform/types.h" - #include "tensorflow/core/util/device_name_utils.h" - -+ - namespace tensorflow { - - namespace { -@@ -143,8 +144,9 @@ Status NewHostPortGrpcChannel(const string& target, +@@ -143,8 +143,9 @@ Status NewHostPortGrpcChannel(const string& target, TF_RETURN_IF_ERROR(ValidateHostPortPair(target)); ::grpc::ChannelArguments args = GetChannelArguments(rpc_options); + auto cred = GetChannelCredentials(); *channel_pointer = ::grpc::CreateCustomChannel( - "dns:///" + target, ::grpc::InsecureChannelCredentials(), args); -+ "dns:///" + target, cred, args); ++ "dns:///" + target, cred, args); return Status::OK(); } @@ -65,7 +57,7 @@ index fb925e51497..2dbe6b3ba32 100644 ChannelCreationFunction GrpcServer::GetChannelCreationFunction() const { diff --git a/tensorflow/core/distributed_runtime/rpc/grpc_util.cc b/tensorflow/core/distributed_runtime/rpc/grpc_util.cc -index 98e05b64aad..fd1118d2956 100644 +index 98e05b64aad..3d802241a5b 100644 --- a/tensorflow/core/distributed_runtime/rpc/grpc_util.cc +++ b/tensorflow/core/distributed_runtime/rpc/grpc_util.cc @@ -16,6 +16,7 @@ limitations under the License. @@ -76,13 +68,15 @@ index 98e05b64aad..fd1118d2956 100644 namespace tensorflow { -@@ -128,4 +129,24 @@ bool GrpcMaybeParseProto(grpc::ByteBuffer* src, tstring* dst) { +@@ -128,4 +129,29 @@ bool GrpcMaybeParseProto(grpc::ByteBuffer* src, tstring* dst) { return true; } +std::shared_ptr<::grpc::ServerCredentials> GetCredentials() { -+ const char* secure = std::getenv("TF_OPTIONAL_TLS_ENABLE"); -+ if (secure) { ++ const char* secure = std::getenv("TF_GRPC_SGX_RA_TLS_ENABLE"); ++ LOG(INFO) << "GetCredentials"; ++ if (secure && strcmp(secure, "on") == 0) { ++ LOG(INFO) << "Secure mode: " << string(secure); + return ::grpc::sgx::TlsServerCredentials(); + } + return ::grpc::InsecureServerCredentials(); @@ -90,13 +84,16 @@ index 98e05b64aad..fd1118d2956 100644 +} + +std::shared_ptr<::grpc::ChannelCredentials> GetChannelCredentials() { -+ const char* secure = std::getenv("TF_OPTIONAL_TLS_ENABLE"); -+ if (secure) { -+ const char* mr_enclave = std::getenv("MR_ENCLAVE"); -+ const char* mr_signer = std::getenv("MR_SIGNER"); -+ const char* isv_prod_id = std::getenv("ISV_PROD_ID"); -+ const char* isv_svn = std::getenv("ISV_SVN"); -+ return ::grpc::sgx::TlsCredentials(mr_enclave, mr_signer, isv_prod_id, isv_svn); ++ const char* secure = std::getenv("TF_GRPC_SGX_RA_TLS_ENABLE"); ++ LOG(INFO) << "GetCredentials"; ++ if (secure && strcmp(secure, "on") == 0) { ++ LOG(INFO) << "Secure mode: " << string(secure); ++ const char* config_path = std::getenv("TF_GRPC_SGX_RA_TLS_CONFIG"); ++ if (!config_path){ ++ config_path = "dynamic_config.json"; ++ } ++ LOG(INFO) << "Config path: " << string(config_path); ++ return ::grpc::sgx::TlsCredentials(config_path); + } + return ::grpc::InsecureChannelCredentials(); +} @@ -115,40 +112,90 @@ index aed798217cb..aa70e94971a 100644 } // namespace tensorflow #endif // TENSORFLOW_CORE_DISTRIBUTED_RUNTIME_RPC_GRPC_UTIL_H_ -diff --git a/tensorflow/workspace.bzl b/tensorflow/workspace.bzl -index d6237e10439..8a7f0e7db64 100755 ---- a/tensorflow/workspace.bzl -+++ b/tensorflow/workspace.bzl -@@ -650,7 +650,7 @@ def tf_repositories(path_prefix = "", tf_repo_name = ""): - # WARNING: make sure ncteisen@ and vpai@ are cc-ed on any CL to change the below rule - tf_http_archive( - name = "com_github_grpc_grpc", -- sha256 = "b956598d8cbe168b5ee717b5dafa56563eb5201a947856a6688bbeac9cac4e1f", -+ sha256 = "b6783a2724cdfe2826ea92477812fddcf329f9b6e403f27a3b0194e7994cd29e", - strip_prefix = "grpc-b54a5b338637f92bfcf4b0bc05e0f57a5fd8fadd", - system_build_file = clean_dep("//third_party/systemlibs:grpc.BUILD"), - patch_file = clean_dep("//third_party/grpc:generate_cc_env_fix.patch"), -@@ -664,8 +664,9 @@ def tf_repositories(path_prefix = "", tf_repo_name = ""): - "//third_party/systemlibs:grpc.bazel.protobuf.bzl": "bazel/protobuf.bzl", - }, - urls = [ -- "https://storage.googleapis.com/mirror.tensorflow.org/github.com/grpc/grpc/archive/b54a5b338637f92bfcf4b0bc05e0f57a5fd8fadd.tar.gz", -- "https://github.com/grpc/grpc/archive/b54a5b338637f92bfcf4b0bc05e0f57a5fd8fadd.tar.gz", -+ #"https://storage.googleapis.com/mirror.tensorflow.org/github.com/grpc/grpc/archive/b54a5b338637f92bfcf4b0bc05e0f57a5fd8fadd.tar.gz", -+ #"https://github.com/grpc/grpc/archive/b54a5b338637f92bfcf4b0bc05e0f57a5fd8fadd.tar.gz", -+ "http://127.0.0.1:8000/b54a5b338637f92bfcf4b0bc05e0f57a5fd8fadd.tar.gz", - ], - ) - -diff --git a/third_party/repo.bzl b/third_party/repo.bzl -index ef729b5223d..4c59a0ef201 100644 ---- a/third_party/repo.bzl -+++ b/third_party/repo.bzl -@@ -16,6 +16,7 @@ - - _SINGLE_URL_WHITELIST = depset([ - "arm_compiler", -+ "com_github_grpc_grpc", - ]) - - def _is_windows(ctx): +diff --git a/third_party/grpc/generate_cc_env_fix.patch b/third_party/grpc/generate_cc_env_fix.patch +index 51832fe9628..4be9e293263 100644 +--- a/third_party/grpc/generate_cc_env_fix.patch ++++ b/third_party/grpc/generate_cc_env_fix.patch +@@ -1,6 +1,8 @@ ++diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl ++index 484959ebb7..81d52fd28f 100644 + --- a/bazel/generate_cc.bzl + +++ b/bazel/generate_cc.bzl +-@@ -141,6 +141,7 @@ def generate_cc_impl(ctx): ++@@ -140,6 +140,7 @@ def generate_cc_impl(ctx): + outputs = out_files, + executable = ctx.executable._protoc, + arguments = arguments, +@@ -8,3 +10,72 @@ + ) + + return struct(files = depset(out_files)) ++diff --git a/src/core/lib/security/credentials/tls/tls_credentials.cc b/src/core/lib/security/credentials/tls/tls_credentials.cc ++index 701fd3b150..0826d05933 100644 ++--- a/src/core/lib/security/credentials/tls/tls_credentials.cc +++++ b/src/core/lib/security/credentials/tls/tls_credentials.cc ++@@ -111,9 +111,9 @@ TlsServerCredentials::create_security_connector() { ++ ++ grpc_channel_credentials* grpc_tls_credentials_create( ++ grpc_tls_credentials_options* options) { ++- if (!CredentialOptionSanityCheck(options, true /* is_client */)) { ++- return nullptr; ++- } +++ //if (!CredentialOptionSanityCheck(options, true /* is_client */)) { +++ // return nullptr; +++ //} ++ return new TlsCredentials( ++ grpc_core::RefCountedPtr(options)); ++ } ++diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc ++index 1274edb6e6..cdfe9834dd 100644 ++--- a/src/core/lib/security/security_connector/alts/alts_security_connector.cc +++++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc ++@@ -108,6 +108,8 @@ class grpc_alts_channel_security_connector final ++ grpc_auth_context* /*auth_context*/, ++ grpc_closure* /*on_call_host_checked*/, ++ grpc_error** error) override { +++ *error = GRPC_ERROR_NONE; +++ return true; ++ if (host.empty() || host != target_name_) { ++ *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( ++ "ALTS call host does not match target name"); ++diff --git a/src/core/lib/security/security_connector/local/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc ++index 6fb770d7ad..61f454509e 100644 ++--- a/src/core/lib/security/security_connector/local/local_security_connector.cc +++++ b/src/core/lib/security/security_connector/local/local_security_connector.cc ++@@ -186,6 +186,8 @@ class grpc_local_channel_security_connector final ++ grpc_auth_context* /*auth_context*/, ++ grpc_closure* /*on_call_host_checked*/, ++ grpc_error** error) override { +++ *error = GRPC_ERROR_NONE; +++ return true; ++ if (host.empty() || host != target_name_) { ++ *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( ++ "local call host does not match target name"); ++diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc ++index 13b0dd59a0..a60637b7c2 100644 ++--- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc ++@@ -190,6 +190,8 @@ class grpc_ssl_channel_security_connector final ++ grpc_auth_context* auth_context, ++ grpc_closure* /*on_call_host_checked*/, ++ grpc_error** error) override { +++ *error = GRPC_ERROR_NONE; +++ return true; ++ grpc_security_status status = GRPC_SECURITY_ERROR; ++ tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); ++ if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; ++diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc ++index 2c2d706673..6c62e73040 100644 ++--- a/src/core/lib/security/security_connector/ssl_utils.cc +++++ b/src/core/lib/security/security_connector/ssl_utils.cc ++@@ -169,6 +169,8 @@ bool grpc_ssl_check_call_host(grpc_core::StringView host, ++ grpc_auth_context* auth_context, ++ grpc_closure* /*on_call_host_checked*/, ++ grpc_error** error) { +++ *error = GRPC_ERROR_NONE; +++ return true; ++ grpc_security_status status = GRPC_SECURITY_ERROR; ++ tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); ++ if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; diff --git a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_credentials_provider.cc b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_credentials_provider.cc index 83ffe9938..5f525143c 100644 --- a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_credentials_provider.cc +++ b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_credentials_provider.cc @@ -109,7 +109,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { return grpc::experimental::AltsServerCredentials(alts_opts); } else if (type == grpc::sgx::kTlsCredentialsType) { SslServerCredentialsOptions ssl_opts; - ssl_opts.pem_root_certs = ""; + ssl_opts.pem_root_certs = custom_server_cert_; if (!custom_server_key_.empty() && !custom_server_cert_.empty()) { SslServerCredentialsOptions::PemKeyCertPair pkcp = { custom_server_key_, custom_server_cert_}; @@ -119,7 +119,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { custom_server_cert_}; ssl_opts.pem_key_cert_pairs.push_back(pkcp); } - return SslServerCredentials(ssl_opts); + return SslServerCredentials(ssl_opts); } else { std::unique_lock lock(mu_); auto it(std::find(added_secure_type_names_.begin(), diff --git a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls.h b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls.h index 005d34e52..24d1b87fe 100644 --- a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls.h +++ b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls.h @@ -27,9 +27,7 @@ namespace grpc { namespace sgx { -std::shared_ptr TlsCredentials( - const char* mrenclave, const char* mrsigner, - const char* isv_prod_id, const char* isv_svn); +std::shared_ptr TlsCredentials(const char* sgx_cfg_path); std::shared_ptr CreateSecureChannel(string, std::shared_ptr); diff --git a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_client.cc b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_client.cc index 0d9ab6ac6..68ea2ab68 100644 --- a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_client.cc +++ b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_client.cc @@ -17,6 +17,9 @@ */ #include +#include +#include + #include "grpc_sgx_ra_tls_utils.h" namespace grpc { @@ -34,125 +37,220 @@ RA-TLS: on client, only need to register ra_tls_verify_callback() for cert verif class TlsServerAuthorizationCheck; -static int (*ra_tls_verify_callback_f)(uint8_t* der_crt, size_t der_crt_size) = nullptr; - -static std::shared_ptr server_authorization_check = nullptr; -static std::shared_ptr server_authorization_check_config = nullptr; - -static library_engine helper_sgx_urts_lib("libsgx_urts.so", RTLD_NOW | RTLD_GLOBAL); -static library_engine ra_tls_verify_lib("libra_tls_verify_dcap.so", RTLD_LAZY); +struct sgx_measurement { + char mr_enclave[32]; + char mr_signer[32]; + uint16_t isv_prod_id; + uint16_t isv_svn; +}; -static char g_expected_mrenclave[32]; -static char g_expected_mrsigner[32]; -static char g_expected_isv_prod_id[2]; -static char g_expected_isv_svn[2]; +struct sgx_config { + bool verify_in_enclave = true; + bool verify_mr_enclave = true; + bool verify_mr_signer = true; + bool verify_isv_prod_id = true; + bool verify_isv_svn = true; + std::vector sgx_mrs; +}; -static bool g_verify_mrenclave = true; -static bool g_verify_mrsigner = true; -static bool g_verify_isv_prod_id = true; -static bool g_verify_isv_svn = true; +struct ra_tls_cache { + int id = 0; + std::unordered_map> authorization_check; + std::unordered_map< + int, std::shared_ptr + > authorization_check_config; +}; -static pthread_mutex_t g_print_lock; +struct ra_tls_context { + std::mutex mtx; + struct sgx_config sgx_cfg; + struct ra_tls_cache cache; + class library_engine verify_lib; + class library_engine sgx_urts_lib; + int (*verify_callback_f)(uint8_t* der_crt, size_t der_crt_size) = nullptr; +}; -void parse_args(const char* s_mrenclave, const char* s_mrsigner, const char* s_isv_prod_id, const char* s_isv_svn) { - if (parse_hex(s_mrenclave, g_expected_mrenclave, sizeof(g_expected_mrenclave)) < 0) { - mbedtls_printf("Cannot parse MRENCLAVE!\n"); - return; - } +struct ra_tls_context _ctx_; + +sgx_config parse_sgx_config_json(const char *file) +{ + class json_engine sgx_json(file); + struct sgx_config sgx_cfg; + + sgx_cfg.verify_in_enclave = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_in_enclave"), "on"); + sgx_cfg.verify_mr_enclave = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_mr_enclave"), "on"); + sgx_cfg.verify_mr_signer = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_mr_signer"), "on"); + sgx_cfg.verify_isv_prod_id = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_isv_prod_id"), "on"); + sgx_cfg.verify_isv_svn = sgx_json.compare_item(sgx_json.get_item(sgx_json.get_handle(), "verify_isv_svn"), "on"); + + mbedtls_printf("|- verify_in_enclave: %s\n", sgx_cfg.verify_in_enclave ? "on" : "off"); + mbedtls_printf("|- verify_mr_enclave: %s\n", sgx_cfg.verify_mr_enclave ? "on" : "off"); + mbedtls_printf("|- verify_mr_signer: %s\n", sgx_cfg.verify_mr_signer ? "on" : "off"); + mbedtls_printf("|- verify_isv_prod_id: %s\n", sgx_cfg.verify_isv_prod_id ? "on" : "off"); + mbedtls_printf("|- verify_isv_svn: %s\n", sgx_cfg.verify_isv_svn ? "on" : "off"); + + auto objs = sgx_json.get_item(sgx_json.get_handle(), "sgx_mrs"); + auto obj_num = cJSON_GetArraySize(objs); + + sgx_cfg.sgx_mrs = std::vector(obj_num, sgx_measurement()); + for (auto i = 0; i < obj_num; i++) + { + auto obj = cJSON_GetArrayItem(objs, i); + mbedtls_printf(" |- expect measurement [%d]:\n", i + 1); + auto mr_enclave = sgx_json.get_item_string(obj, "mr_enclave"); + mbedtls_printf(" |- mr_enclave: %s\n", mr_enclave); + memset(sgx_cfg.sgx_mrs[i].mr_enclave, 0, sizeof(sgx_cfg.sgx_mrs[i].mr_enclave)); + auto res = parse_hex(mr_enclave, sgx_cfg.sgx_mrs[i].mr_enclave, sizeof(sgx_cfg.sgx_mrs[i].mr_enclave)); + if (!res){ + mbedtls_printf("mr_enclave invalid, %s\n", mr_enclave); + } - if (parse_hex(s_mrsigner, g_expected_mrsigner, sizeof(g_expected_mrsigner)) < 0) { - mbedtls_printf("Cannot parse MRSIGNER!\n"); - return; - } + auto mr_signer = sgx_json.get_item_string(obj, "mr_signer"); + mbedtls_printf(" |- mr_signer: %s\n", mr_signer); + memset(sgx_cfg.sgx_mrs[i].mr_signer, 0, sizeof(sgx_cfg.sgx_mrs[i].mr_signer)); + res = parse_hex(mr_signer, sgx_cfg.sgx_mrs[i].mr_signer, sizeof(sgx_cfg.sgx_mrs[i].mr_signer)); + if (!res){ + mbedtls_printf("mr_signer invalid, %s\n", mr_signer); + } - errno = 0; - uint16_t isv_prod_id = (uint16_t)strtoul(s_isv_prod_id, NULL, 10); - if (errno) { - mbedtls_printf("Cannot parse ISV_PROD_ID!\n"); - return; - } - memcpy(g_expected_isv_prod_id, &isv_prod_id, sizeof(isv_prod_id)); + auto isv_prod_id = sgx_json.get_item_string(obj, "isv_prod_id"); + mbedtls_printf(" |- isv_prod_id: %s\n", isv_prod_id); + sgx_cfg.sgx_mrs[i].isv_prod_id = strtoul(isv_prod_id ,nullptr, 10); - errno = 0; - uint16_t isv_svn = (uint16_t)strtoul(s_isv_svn, NULL, 10); - if (errno) { - mbedtls_printf("Cannot parse ISV_SVN\n"); - return; - } - memcpy(g_expected_isv_svn, &isv_svn, sizeof(isv_svn)); + auto isv_svn = sgx_json.get_item_string(obj, "isv_svn"); + mbedtls_printf(" |- isv_svn: %s\n", isv_svn); + sgx_cfg.sgx_mrs[i].isv_svn = strtoul(isv_svn ,nullptr, 10);; + }; + return sgx_cfg; } -// RA-TLS: our own callback to verify SGX measurements -int ra_tls_verify_measurements_callback(const char* mrenclave, const char* mrsigner, - const char* isv_prod_id, const char* isv_svn) { - assert(mrenclave && mrsigner && isv_prod_id && isv_svn); - - pthread_mutex_lock(&g_print_lock); - - mbedtls_printf("MRENCLAVE\n"); - mbedtls_printf(" |- Expect : "); hexdump_mem(g_expected_mrenclave, 32); - mbedtls_printf(" |- Get : "); hexdump_mem(mrenclave, 32); - mbedtls_printf("MRSIGNER\n"); - mbedtls_printf(" |- Expect : "); hexdump_mem(g_expected_mrsigner, 32); - mbedtls_printf(" |- Get : "); hexdump_mem(mrsigner, 32); - mbedtls_printf("ISV_PROD_ID\n"); - mbedtls_printf(" |- Expect : %hu\n", *((uint16_t*)g_expected_isv_prod_id)); - mbedtls_printf(" |- Get : %hu\n", *((uint16_t*)isv_prod_id)); - mbedtls_printf("ISV_SVN\n"); - mbedtls_printf(" |- Expect : %hu\n", *((uint16_t*)g_expected_isv_svn)); - mbedtls_printf(" |- Get : %hu\n", *((uint16_t*)isv_svn)); +bool ra_tls_verify_measurement(const char* mr_enclave, const char* mr_signer, + const char* isv_prod_id, const char* isv_svn) { + bool status = false; + auto & sgx_cfg = _ctx_.sgx_cfg; + for (auto & obj : sgx_cfg.sgx_mrs) { + status = true; - bool status = true; - if (status && g_verify_mrenclave && memcmp(mrenclave, g_expected_mrenclave, sizeof(g_expected_mrenclave))) { + if (status && sgx_cfg.verify_mr_enclave && \ + memcmp(obj.mr_enclave, mr_enclave, 32)) { status = false; } - if (status && g_verify_mrsigner && memcmp(mrsigner, g_expected_mrsigner, sizeof(g_expected_mrsigner))) { + if (status && sgx_cfg.verify_mr_signer && \ + memcmp(obj.mr_signer, mr_signer, 32)) { status = false; } - if (status && g_verify_isv_prod_id && memcmp(isv_prod_id, g_expected_isv_prod_id, sizeof(g_expected_isv_prod_id))) { + if (status && sgx_cfg.verify_isv_prod_id && \ + (obj.isv_prod_id != *(uint16_t*)isv_prod_id)) { status = false; } - if (status && g_verify_isv_svn && memcmp(isv_svn, g_expected_isv_svn, sizeof(g_expected_isv_svn))) { + if (status && sgx_cfg.verify_isv_svn && \ + (obj.isv_svn != *(uint16_t*)isv_svn)) { status = false; } + if (status) { + break; + } + } + return status; +} + +// RA-TLS: our own callback to verify SGX measurements +int ra_tls_verify_mr_callback(const char* mr_enclave, const char* mr_signer, + const char* isv_prod_id, const char* isv_svn) { + std::lock_guard lock(_ctx_.mtx); + bool status = false; + + try { + assert(mr_enclave && mr_signer && isv_prod_id && isv_svn); + + status = ra_tls_verify_measurement(mr_enclave, mr_signer, isv_prod_id, isv_svn); + + mbedtls_printf("MRENCLAVE\n"); + mbedtls_printf(" |- Get : "); hexdump_mem(mr_enclave, 32); + mbedtls_printf("MRSIGNER\n"); + mbedtls_printf(" |- Get : "); hexdump_mem(mr_signer, 32); + mbedtls_printf("ISV_PROD_ID\n"); + mbedtls_printf(" |- Get : %hu\n", *((uint16_t*)isv_prod_id)); + mbedtls_printf("ISV_SVN\n"); + mbedtls_printf(" |- Get : %hu\n", *((uint16_t*)isv_svn)); + if (status) { mbedtls_printf("Quote Verify\n |- Result : Success\n"); - pthread_mutex_unlock(&g_print_lock); - return 0; } else { mbedtls_printf("Quote Verify\n |- Result : Failed\n"); - pthread_mutex_unlock(&g_print_lock); - return -1; } + + fflush(stdout); + return status ? 0 : -1; + } catch (...) { + mbedtls_printf("Unable to verify measurement!"); + fflush(stdout); + return -1; + } } void ra_tls_verify_init() { - ra_tls_verify_callback_f = reinterpret_cast(ra_tls_verify_lib.get_func("ra_tls_verify_callback_der")); + if (_ctx_.sgx_cfg.verify_in_enclave) { + if (!_ctx_.verify_lib.get_handle()) { + _ctx_.verify_lib.open("libra_tls_verify_dcap_gramine.so", RTLD_LAZY); + } + } else { + if (!_ctx_.sgx_urts_lib.get_handle()) { + _ctx_.sgx_urts_lib.open("libsgx_urts.so", RTLD_NOW | RTLD_GLOBAL); + } + if (!_ctx_.verify_lib.get_handle()) { + _ctx_.verify_lib.open("libra_tls_verify_dcap.so", RTLD_LAZY); + } + } + + _ctx_.verify_callback_f = + reinterpret_cast( + _ctx_.verify_lib.get_func("ra_tls_verify_callback_der")); + + auto set_verify_mr_callback_f = + reinterpret_cast( + _ctx_.verify_lib.get_func("ra_tls_set_measurement_callback")); + (*set_verify_mr_callback_f)(ra_tls_verify_mr_callback); +} - auto ra_tls_set_measurement_callback_f = reinterpret_cast(ra_tls_verify_lib.get_func("ra_tls_set_measurement_callback")); - (*ra_tls_set_measurement_callback_f)(ra_tls_verify_measurements_callback); +void ra_tls_verify_init(const char* sgx_cfg_path) { + std::lock_guard lock(_ctx_.mtx); + _ctx_.sgx_cfg = parse_sgx_config_json(sgx_cfg_path); + ra_tls_verify_init(); } +typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckArg +TlsServerAuthorizationCheckArg; +typedef struct ::grpc_impl::experimental::TlsServerAuthorizationCheckInterface +TlsServerAuthorizationCheckInterface; +// typedef class ::grpc_impl::experimental::TlsKeyMaterialsConfig +// TlsKeyMaterialsConfig; +// typedef class ::grpc_impl::experimental::TlsCredentialReloadArg +// TlsCredentialReloadArg; +// typedef struct ::grpc_impl::experimental::TlsCredentialReloadInterface +// TlsCredentialReloadInterface; +// typedef class ::grpc_impl::experimental::TlsCredentialReloadConfig +// TlsCredentialReloadConfig; + // test/cpp/client/credentials_test.cc : class TestTlsServerAuthorizationCheck -class TlsServerAuthorizationCheck -: public grpc_impl::experimental::TlsServerAuthorizationCheckInterface { - int Schedule(grpc_impl::experimental::TlsServerAuthorizationCheckArg* arg) override { +class TlsServerAuthorizationCheck : public TlsServerAuthorizationCheckInterface { + int Schedule(TlsServerAuthorizationCheckArg* arg) override { GPR_ASSERT(arg != nullptr); char cert_pem[16000]; auto peer_cert_buf = arg->peer_cert(); peer_cert_buf.copy(cert_pem, peer_cert_buf.length(), 0); - int ret = (*ra_tls_verify_callback_f)(reinterpret_cast(cert_pem), 16000); + int ret = (*_ctx_.verify_callback_f)(reinterpret_cast(cert_pem), 16000); if (ret != 0) { - mbedtls_printf("something went wrong while verifying quote"); + mbedtls_printf("something went wrong while verifying quote, error: %s\n", mbedtls_high_level_strerr(ret)); arg->set_success(0); arg->set_status(GRPC_STATUS_UNAUTHENTICATED); return 0; @@ -163,68 +261,56 @@ class TlsServerAuthorizationCheck } } - void Cancel(grpc_impl::experimental::TlsServerAuthorizationCheckArg* arg) override { + void Cancel(TlsServerAuthorizationCheckArg* arg) override { GPR_ASSERT(arg != nullptr); arg->set_status(GRPC_STATUS_PERMISSION_DENIED); arg->set_error_details("cancelled"); } }; -typedef class ::grpc_impl::experimental::TlsKeyMaterialsConfig -TlsKeyMaterialsConfig; -typedef class ::grpc_impl::experimental::TlsCredentialReloadArg -TlsCredentialReloadArg; -typedef struct ::grpc_impl::experimental::TlsCredentialReloadInterface -TlsCredentialReloadInterface; -typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckArg -TlsServerAuthorizationCheckArg; -typedef struct ::grpc_impl::experimental::TlsServerAuthorizationCheckInterface -TlsServerAuthorizationCheckInterface; - -typedef class ::grpc_impl::experimental::TlsCredentialReloadConfig TlsCredentialReloadConfig; - -class TestTlsCredentialReload : public TlsCredentialReloadInterface { - int Schedule(TlsCredentialReloadArg* arg) override { - - std::cout << "000" << std::endl; - if (!arg->is_pem_key_cert_pair_list_empty()) { - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED); - return 0; - } - std::cout << "11" << std::endl; - GPR_ASSERT(arg != nullptr); - struct TlsKeyMaterialsConfig::PemKeyCertPair pair3 = {}; - std::cout << "12" << std::endl; - arg->set_pem_root_certs("new_pem_root_certs"); - arg->add_pem_key_cert_pair(pair3); - std::cout << "13" << std::endl; - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); - return 0; - } - - void Cancel(TlsCredentialReloadArg* arg) override { - GPR_ASSERT(arg != nullptr); - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL); - arg->set_error_details("cancelled"); - } -}; - -std::shared_ptr TlsCredentials( - const char* mrenclave, const char* mrsigner, - const char* isv_prod_id, const char* isv_svn) { - parse_args(mrenclave, mrsigner, isv_prod_id, isv_svn); +// class TestTlsCredentialReload : public TlsCredentialReloadInterface { +// int Schedule(TlsCredentialReloadArg* arg) override { +// if (!arg->is_pem_key_cert_pair_list_empty()) { +// arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED); +// return 0; +// } +// GPR_ASSERT(arg != nullptr); +// struct TlsKeyMaterialsConfig::PemKeyCertPair pair3 = {}; +// arg->set_pem_root_certs("new_pem_root_certs"); +// arg->add_pem_key_cert_pair(pair3); +// arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); +// return 0; +// } + +// void Cancel(TlsCredentialReloadArg* arg) override { +// GPR_ASSERT(arg != nullptr); +// arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL); +// arg->set_error_details("cancelled"); +// } +// }; + +std::shared_ptr TlsCredentials(const char* sgx_cfg_path) { + + ra_tls_verify_init(sgx_cfg_path); + + _ctx_.cache.id++; + + auto auth_check = _ctx_.cache.authorization_check.insert({ + _ctx_.cache.id, std::make_shared() + }).first; + + auto auth_check_config = _ctx_.cache.authorization_check_config.insert({ + _ctx_.cache.id, + std::make_shared( + auth_check->second) + }).first; - ra_tls_verify_init(); - - server_authorization_check = std::make_shared(); - server_authorization_check_config = std::make_shared( - server_authorization_check); grpc_impl::experimental::TlsCredentialsOptions options( GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, GRPC_TLS_SKIP_ALL_SERVER_VERIFICATION, nullptr, nullptr, - server_authorization_check_config + auth_check_config->second ); return grpc_impl::experimental::TlsCredentials(options); @@ -243,7 +329,8 @@ std::shared_ptr TlsCredentials( */ }; -std::shared_ptr CreateSecureChannel(string target_str, std::shared_ptr channel_creds) { +std::shared_ptr CreateSecureChannel( + string target_str, std::shared_ptr channel_creds) { GPR_ASSERT(channel_creds.get() != nullptr); auto channel_args = grpc::ChannelArguments(); channel_args.SetSslTargetNameOverride("RATLS"); diff --git a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_server.cc b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_server.cc index 663bdb5e1..2b00c6ab1 100644 --- a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_server.cc +++ b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_server.cc @@ -42,7 +42,7 @@ ::grpc_impl::experimental::TlsKeyMaterialsConfig::PemKeyCertPair get_cred_key_pa int ret = (*ra_tls_create_key_and_crt_f)(&pkey, &srvcert); if (ret != 0) { - throw std::runtime_error(std::string("ra_tls_create_key_and_crt failed and returned %d\n\n", ret)); + throw std::runtime_error(std::string("ra_tls_create_key_and_crt failed and error %s\n\n", mbedtls_high_level_strerr(ret))); } unsigned char private_key_pem[16000], cert_pem[16000]; @@ -50,14 +50,14 @@ ::grpc_impl::experimental::TlsKeyMaterialsConfig::PemKeyCertPair get_cred_key_pa ret = mbedtls_pk_write_key_pem(&pkey, private_key_pem, 16000); if (ret != 0) { - throw std::runtime_error(std::string("something went wrong while extracting private key\n\n")); + throw std::runtime_error(std::string("something went wrong while extracting private key, %s\n\n", mbedtls_high_level_strerr(ret))); } ret = mbedtls_pem_write_buffer(PEM_BEGIN_CRT, PEM_END_CRT, srvcert.raw.p, srvcert.raw.len, cert_pem, 16000, &olen); if (ret != 0) { - throw std::runtime_error(std::string("mbedtls_pem_write_buffer failed\n\n")); + throw std::runtime_error(std::string("mbedtls_pem_write_buffer failed, error %s\n\n", mbedtls_high_level_strerr(ret))); }; auto private_key = std::string((char*) private_key_pem); @@ -74,55 +74,6 @@ ::grpc_impl::experimental::TlsKeyMaterialsConfig::PemKeyCertPair get_cred_key_pa return pkcp; } -typedef class ::grpc_impl::experimental::TlsKeyMaterialsConfig -TlsKeyMaterialsConfig; -typedef class ::grpc_impl::experimental::TlsCredentialReloadArg -TlsCredentialReloadArg; -typedef struct ::grpc_impl::experimental::TlsCredentialReloadInterface -TlsCredentialReloadInterface; -typedef class ::grpc_impl::experimental::TlsServerAuthorizationCheckArg -TlsServerAuthorizationCheckArg; -typedef struct ::grpc_impl::experimental::TlsServerAuthorizationCheckInterface -TlsServerAuthorizationCheckInterface; - -class TestTlsCredentialReload : public TlsCredentialReloadInterface { - int Schedule(TlsCredentialReloadArg* arg) override { - if (!arg->is_pem_key_cert_pair_list_empty()) { - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED); - return 0; - } - GPR_ASSERT(arg != nullptr); - auto key_pair = get_cred_key_pair(); - struct TlsKeyMaterialsConfig::PemKeyCertPair pair3 = { key_pair.private_key.c_str(), - key_pair.cert_chain.c_str()}; - arg->set_pem_root_certs("new_pem_root_certs"); - arg->add_pem_key_cert_pair(pair3); - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); - return 0; - } - - void Cancel(TlsCredentialReloadArg* arg) override { - GPR_ASSERT(arg != nullptr); - arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL); - arg->set_error_details("cancelled"); - } -}; - - -class TestTlsServerAuthorizationCheck -: public TlsServerAuthorizationCheckInterface { - int Schedule(TlsServerAuthorizationCheckArg* arg) override { - GPR_ASSERT(arg != nullptr); - return 0; - } - - void Cancel(TlsServerAuthorizationCheckArg* arg) override { - GPR_ASSERT(arg != nullptr); - arg->set_status(GRPC_STATUS_PERMISSION_DENIED); - arg->set_error_details("cancelled"); - } -}; - std::shared_ptr TlsServerCredentials() { using namespace ::grpc_impl::experimental; auto key_pair = get_cred_key_pair(); diff --git a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_utils.cc b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_utils.cc index ce9d06c71..b874a989e 100644 --- a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_utils.cc +++ b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_utils.cc @@ -21,27 +21,27 @@ namespace grpc { namespace sgx { -void hexdump_mem(const void* data, size_t size) { - uint8_t* ptr = (uint8_t*)data; - for (size_t i = 0; i < size; i++) - printf("%02x", ptr[i]); - printf("\n"); -} - -int parse_hex(const char* hex, void* buffer, size_t buffer_size) { - if (strlen(hex) != buffer_size * 2) { - return -1; +bool parse_hex(const char* hex, void* buffer, size_t buffer_size) { + if (strlen(hex) < buffer_size * 2) { + return false; } else { for (size_t i = 0; i < buffer_size; i++) { if (!isxdigit(hex[i * 2]) || !isxdigit(hex[i * 2 + 1])) { - return -1; + return false; } sscanf(hex + i * 2, "%02hhx", &((uint8_t*)buffer)[i]); } - return 0; + return true; } } +void hexdump_mem(const void* data, size_t size) { + uint8_t* ptr = (uint8_t*)data; + for (size_t i = 0; i < size; i++) + printf("%02x", ptr[i]); + printf("\n"); +} + library_engine::library_engine() : handle(nullptr), error(nullptr) {}; library_engine::library_engine(const char* file, int mode) : handle(nullptr), error(nullptr) { @@ -83,5 +83,88 @@ void* library_engine::get_handle() { return handle; } +json_engine::json_engine() : handle(nullptr){}; + +json_engine::json_engine(const char *file) : handle(nullptr) +{ + this->open(file); +} + +json_engine::~json_engine() +{ + this->close(); +} + +bool json_engine::open(const char *file) +{ + if (!file) + { + printf("wrong json file path\n"); + return false; + } + + this->close(); + + auto file_ptr = fopen(file, "r"); + fseek(file_ptr, 0, SEEK_END); + auto length = ftell(file_ptr); + fseek(file_ptr, 0, SEEK_SET); + auto buffer = malloc(length + 1); + memset(buffer, 0, length); + fread(buffer, 1, length, file_ptr); + fclose(file_ptr); + + this->handle = cJSON_Parse((const char*)buffer); + + if (buffer) + { + free(buffer); + buffer = nullptr; + } + + if (this->handle) + { + return true; + } + else + { + printf("cjson open %s error: %s", file, cJSON_GetErrorPtr()); + return false; + } +} + +void json_engine::close() +{ + if (this->handle) + { + cJSON_Delete(this->handle); + this->handle = nullptr; + } +} + +cJSON *json_engine::get_handle() +{ + return this->handle; +} + +cJSON *json_engine::get_item(cJSON *obj, const char *item) +{ + return cJSON_GetObjectItem(obj, item); +}; + +bool json_engine::compare_item(cJSON *obj, const char *item) +{ + if (!obj || !cJSON_IsString(obj)){ + return false; + } + auto obj_item = obj->valuestring; + return strncmp(obj_item, item, std::min(strlen(item), strlen(obj_item))) == 0; +}; + +const char* json_engine::get_item_string(cJSON *obj, const char* item){ + auto item_json = get_item(obj, item); + return cJSON_IsString(item_json) ? item_json->valuestring : ""; +} + } // namespace sgx } // namespace grpc diff --git a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_utils.h b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_utils.h index fabb290c4..99554a032 100644 --- a/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_utils.h +++ b/sgx/tf/tensorflow/core/distributed_runtime/rpc/grpc_sgx_ra_tls_utils.h @@ -40,8 +40,6 @@ namespace grpc { namespace sgx { -#include -#include #include #include #include @@ -56,9 +54,11 @@ namespace sgx { #include #include -void hexdump_mem(const void*, size_t); +#include -int parse_hex(const char*, void*, size_t); +bool parse_hex(const char*, void*, size_t); + +void hexdump_mem(const void* data, size_t size); class library_engine { public: @@ -81,6 +81,31 @@ class library_engine { char* error; }; +class json_engine +{ +public: + json_engine(); + + json_engine(const char *); + + ~json_engine(); + + bool open(const char *); + + void close(); + + cJSON *get_handle(); + + cJSON *get_item(cJSON *obj, const char *item); + + bool compare_item(cJSON *obj, const char *item); + + const char* get_item_string(cJSON *obj, const char* item); + +private: + cJSON *handle; +}; + } // namespace sgx } // namespace grpc diff --git a/test/common/for_test_hooks.py b/test/common/for_test_hooks.py new file mode 100644 index 000000000..c2dbfa54e --- /dev/null +++ b/test/common/for_test_hooks.py @@ -0,0 +1,17 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +def test(): + return 1 \ No newline at end of file diff --git a/test/common/test_hooks.py b/test/common/test_hooks.py new file mode 100644 index 000000000..69001524d --- /dev/null +++ b/test/common/test_hooks.py @@ -0,0 +1,27 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +import unittest +from fedlearner.common.hooks import parse_and_call_fn + +class HooksTest(unittest.TestCase): + def test_parse_and_call_fn(self): + with self.assertRaises((RuntimeError)): + parse_and_call_fn('something_you_cannot_understand') + self.assertEqual(parse_and_call_fn('test.common.for_test_hooks:test'), 1) + + +if __name__ == '__main__': + unittest.main() diff --git a/test/data_join/test_data_portal_job_manager.py b/test/data_join/test_data_portal_job_manager.py index ee1e417cd..73f7d1388 100644 --- a/test/data_join/test_data_portal_job_manager.py +++ b/test/data_join/test_data_portal_job_manager.py @@ -57,17 +57,18 @@ def setUp(self) -> None: gfile.DeleteRecursively(self._portal_input_base_dir) gfile.MakeDirs(self._portal_input_base_dir) - self._data_fnames = ['1001/{}.data'.format(i) for i in range(100)] + self._data_fnames = ['c/20210101/{}.data'.format(i) for i in range(100)] self._data_fnames_without_success = \ - ['1002/{}.data'.format(i) for i in range(100)] - self._csv_fnames = ['1003/{}.csv'.format(i) for i in range(100)] + ['a/20210102/{}.data'.format(i) for i in range(100)] + self._csv_fnames = ['b/20210103/{}.csv'.format(i) for i in range(100)] self._unused_fnames = ['{}.xx'.format(100)] self._ignored_fnames = [f'.part-{i}.crc' for i in range(10)] self._all_fnames = self._data_fnames + \ self._data_fnames_without_success + \ self._csv_fnames + self._unused_fnames - all_fnames_with_success = ['1001/_SUCCESS'] + ['1003/_SUCCESS'] +\ + all_fnames_with_success = ['c/20210101/_SUCCESS', + 'b/20210103/_SUCCESS'] + \ self._all_fnames + self._ignored_fnames for fname in all_fnames_with_success: fpath = os.path.join(self._portal_input_base_dir, fname) @@ -102,7 +103,9 @@ def _list_input_dir(self, portal_options, file_wildcard, portal_options.check_success_tag, portal_options.single_subfolder, portal_options.files_per_job_limit, - max_files_per_job + max_files_per_job, + start_date=portal_options.start_date, + end_date=portal_options.end_date ) portal_job = data_portal_job_manager._sync_processing_job() target_fnames.sort() @@ -214,6 +217,48 @@ def test_list_input_dir_without_wildcard_and_success_check(self): ) self._list_input_dir(portal_options, None, self._all_fnames) + def test_list_input_dir_with_start_date(self): + portal_options = dp_pb.DataPotraMasterlOptions( + use_mock_etcd=True, + long_running=False, + check_success_tag=False, + single_subfolder=False, + files_per_job_limit=None, + start_date='20210102' + ) + self._list_input_dir( + portal_options, None, + self._data_fnames_without_success + self._csv_fnames + + self._unused_fnames) + + def test_list_input_dir_with_start_end_date(self): + portal_options = dp_pb.DataPotraMasterlOptions( + use_mock_etcd=True, + long_running=False, + check_success_tag=False, + single_subfolder=False, + files_per_job_limit=None, + start_date='20210101', + end_date='20210103' + ) + self._list_input_dir( + portal_options, None, + self._data_fnames + self._data_fnames_without_success + + self._unused_fnames) + + def test_list_input_dir_with_invalid_date(self): + portal_options = dp_pb.DataPotraMasterlOptions( + use_mock_etcd=True, + long_running=False, + check_success_tag=False, + single_subfolder=False, + files_per_job_limit=None, + start_date=None, + end_date='', + ) + self._list_input_dir( + portal_options, None, self._all_fnames) + if __name__ == '__main__': unittest.main() diff --git a/test/fedavg/test_fedavg.py b/test/fedavg/test_fedavg.py new file mode 100644 index 000000000..24e1182aa --- /dev/null +++ b/test/fedavg/test_fedavg.py @@ -0,0 +1,90 @@ +import threading +import unittest +import tensorflow as tf +import numpy as np +import fedlearner.common.fl_logging as logging +from fedlearner.fedavg import train_from_keras_model + +(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() +x_train = x_train.reshape(x_train.shape[0], -1).astype(np.float32) / 255.0 +y_train = y_train.astype(np.int32) + +x_test = x_test.reshape(x_test.shape[0], -1).astype(np.float32) / 255.0 +y_test = y_test.astype(np.int32) + + +def create_model(): + model = tf.keras.Sequential([ + tf.keras.layers.Dense(200, activation='relu', input_shape=(784, )), + tf.keras.layers.Dense(200, activation='relu'), + tf.keras.layers.Dense(10, activation='softmax'), + ]) + model.compile(optimizer=tf.keras.optimizers.SGD(0.01), + loss=tf.keras.losses.SparseCategoricalCrossentropy(), + metrics=['acc']) + return model + +class TestFedavgTrain(unittest.TestCase): + def setUp(self): + super(TestFedavgTrain, self).__init__() + self._fl_cluster = { + "leader": { + "name": "leader", + "address": "0.0.0.0:20050" + }, + "followers": [{ + "name": "follower" + }] + } + self._batch_size = 64 + self._epochs = 1 + self._steps_per_sync = 10 + self._l_eval_result = None + self._f_eval_result = None + + def _train_leader(self): + x = x_train[:len(x_train) // 2] + y = y_train[:len(y_train) // 2] + model = create_model() + train_from_keras_model(model, + x, + y, + batch_size=self._batch_size, + epochs=self._epochs, + fl_name="leader", + fl_cluster=self._fl_cluster, + steps_per_sync=self._steps_per_sync) + self._l_eval_result = model.evaluate(x_test, y_test) + + def _train_follower(self): + x = x_train[len(x_train) // 2:] + y = y_train[len(y_train) // 2:] + model = create_model() + train_from_keras_model(model, + x, + y, + batch_size=self._batch_size, + epochs=self._epochs, + fl_name="follower", + fl_cluster=self._fl_cluster, + steps_per_sync=self._steps_per_sync) + self._f_eval_result = model.evaluate(x_test, y_test) + + + def test_train(self): + l_thread = threading.Thread(target=self._train_leader) + f_thread = threading.Thread(target=self._train_follower) + l_thread.start() + f_thread.start() + l_thread.join() + f_thread.join() + + assert len(self._l_eval_result) == 2 + assert len(self._f_eval_result) == 2 + for v1, v2 in zip(self._l_eval_result, self._f_eval_result): + assert np.isclose(v1, v2) + + +if __name__ == '__main__': + logging.set_level("debug") + unittest.main() diff --git a/test/trainer/__init__.py b/test/trainer/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test/trainer/graph_def/horizontal_follower.py b/test/trainer/graph_def/horizontal_follower.py new file mode 100644 index 000000000..749416aa6 --- /dev/null +++ b/test/trainer/graph_def/horizontal_follower.py @@ -0,0 +1,85 @@ +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +# pylint: disable=no-else-return, inconsistent-return-statements + +import logging +import tensorflow.compat.v1 as tf +import fedlearner.trainer as flt + +def input_fn(bridge, trainer_master): + dataset = flt.data.DataBlockLoader(256, 'follower', bridge, + trainer_master)\ + .make_dataset(compression_type='GZIP') + def parse_fn(example): + feature_map = { + "example_id": tf.FixedLenFeature([], tf.string), + "y": tf.FixedLenFeature([], tf.int64) + } + features = tf.parse_example(example, features=feature_map) + labels = {'y': features.pop('y')} + return features, labels + dataset = dataset.map(map_func=parse_fn, + num_parallel_calls=tf.data.experimental.AUTOTUNE) + return dataset + + +def serving_input_receiver_fn(): + feature_map = { + "example_id": tf.FixedLenFeature([], tf.string), + } + record_batch = tf.placeholder(dtype=tf.string, name='examples') + features = tf.parse_example(record_batch, features=feature_map) + return tf.estimator.export.ServingInputReceiver(features, + {'examples': record_batch}) + + +def model_fn(model, features, labels, mode): + if mode == tf.estimator.ModeKeys.PREDICT: + return model.make_spec(mode=mode, + predictions=features) + + y = labels['y'] + if mode == tf.estimator.ModeKeys.TRAIN: + logits = model.recv('logits', tf.float32, require_grad=True) + else: + logits = model.recv('logits', tf.float32, require_grad=False) + loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, + logits=logits) + loss = tf.math.reduce_mean(loss) + correct = tf.nn.in_top_k(predictions=logits, targets=y, k=1) + acc = tf.reduce_mean(input_tensor=tf.cast(correct, tf.float32)) + model.send('loss', loss, require_grad=False) + model.send('accuracy', acc, require_grad=False) + if mode == tf.estimator.ModeKeys.EVAL: + return model.make_spec(mode=mode, loss=loss) + + logging.info("training") + optimizer = tf.train.GradientDescentOptimizer(0.1) + train_op = model.minimize( + optimizer, loss, + global_step=tf.train.get_or_create_global_step()) + return model.make_spec(mode, + loss=loss, + train_op=train_op) + + +def main(args): + flt.trainer_worker.train( + 'follower', args, input_fn, + model_fn, serving_input_receiver_fn) + +#if __name__ == '__main__': +# main() diff --git a/test/trainer/graph_def/horizontal_leader.py b/test/trainer/graph_def/horizontal_leader.py new file mode 100644 index 000000000..58e7a83f1 --- /dev/null +++ b/test/trainer/graph_def/horizontal_leader.py @@ -0,0 +1,189 @@ +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +# pylint: disable=no-else-return, inconsistent-return-statements + +import logging +# import tensorflow.compat.v1 as tf +import tensorflow as tf +import fedlearner.trainer as flt + + +def input_fn(bridge, trainer_master): + dataset = flt.data.DataBlockLoader(256, 'leader', bridge, trainer_master)\ + .make_dataset(compression_type='GZIP') + def parse_fn(example): + feature_map = { + "example_id": tf.FixedLenFeature([], tf.string), + "x": tf.FixedLenFeature([28 * 28], tf.float32), + "y": tf.FixedLenFeature([], tf.int64) + } + features = tf.parse_example(example, features=feature_map) + labels = {'y': features.pop('y')} + print("Leader worker input_fn ", labels) + return features, labels + return dataset.map(map_func=parse_fn, + num_parallel_calls=tf.data.experimental.AUTOTUNE) + + +def serving_input_receiver_fn(): + feature_map = { + "example_id": tf.FixedLenFeature([], tf.string), + "x": tf.FixedLenFeature([28 * 28], tf.float32), + } + record_batch = tf.placeholder(dtype=tf.string, name='examples') + features = tf.parse_example(record_batch, features=feature_map) + features['act1_f'] = tf.placeholder(dtype=tf.float32, name='act1_f') + receiver_tensors = {'examples': record_batch, 'act1_f': features['act1_f']} + return tf.estimator.export.ServingInputReceiver(features, receiver_tensors) + + +def model_def(features): + x = features['x'] + + w1l = tf.get_variable('w1l', + shape=[28 * 28, 256], + dtype=tf.float32, + initializer=tf.random_uniform_initializer( + -0.01, 0.01)) + b1l = tf.get_variable('b1l', + shape=[256], + dtype=tf.float32, + initializer=tf.zeros_initializer()) + w2 = tf.get_variable('w2', + shape=[256, 10], + dtype=tf.float32, + initializer=tf.random_uniform_initializer( + -0.01, 0.01)) + b2 = tf.get_variable('b2', + shape=[10], + dtype=tf.float32, + initializer=tf.zeros_initializer()) + + act1 = tf.nn.relu(tf.nn.bias_add(tf.matmul(x, w1l), b1l)) + logits = tf.nn.bias_add(tf.matmul(act1, w2), b2) + + w3 = tf.get_variable('w3', + shape=[256, 10], + dtype=tf.float32, + initializer=tf.random_uniform_initializer( + -0.01, 0.01)) + b3 = tf.get_variable('b3', + shape=[10], + dtype=tf.float32, + initializer=tf.zeros_initializer()) + local_logits = tf.nn.bias_add(tf.matmul(act1, w3), b3) + optimizer = tf.train.AdagradOptimizer(0.1) + return logits, local_logits, optimizer + +def remote_model_fn(model, features, labels, mode): + logits, local_logits, optimizer = model_def(features) + + if mode == tf.estimator.ModeKeys.PREDICT: + return model.make_spec(mode=mode, predictions=logits) + + y = labels['y'] + if mode == tf.estimator.ModeKeys.EVAL: + classes = tf.argmax(logits, axis=1) + acc_pair = tf.metrics.accuracy(y, classes) + loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, + logits=logits) + loss = tf.math.reduce_mean(loss) + return model.make_spec( + mode=mode, loss=loss, eval_metric_ops={'accuracy': acc_pair}) + + global_step = tf.train.get_or_create_global_step() + # mode == tf.estimator.ModeKeys.TRAIN + logits_grad = model.send('logits', logits, require_grad=True) + remote_train_op = model.minimize( + optimizer, logits, + grad_loss=logits_grad, + global_step=global_step) + + # mode == tf.estimator.ModeKeys.TRAIN + local_loss = tf.nn.sparse_softmax_cross_entropy_with_logits( + labels=y, logits=local_logits) + local_loss = tf.math.reduce_mean(local_loss) + + local_train_op = optimizer.minimize( + local_loss, global_step=global_step) + + acc = model.recv('accuracy', tf.float32, require_grad=False) + loss = model.recv('loss', tf.float32, require_grad=False) + logging_hook = tf.estimator.LoggingTensorHook( + {"loss" : loss, "acc" : acc}, every_n_iter=10) + return model.make_spec( + mode=mode, loss=loss, train_op=remote_train_op, + training_hooks=[logging_hook]) + + +def local_model_fn(model, features, labels, mode): + logits, local_logits, optimizer = model_def(features) + + if mode == tf.estimator.ModeKeys.PREDICT: + return model.make_spec(mode=mode, predictions=logits) + + y = labels['y'] + if mode == tf.estimator.ModeKeys.EVAL: + classes = tf.argmax(logits, axis=1) + acc_pair = tf.metrics.accuracy(y, classes) + loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, + logits=logits) + loss = tf.math.reduce_mean(loss) + return model.make_spec( + mode=mode, loss=loss, eval_metric_ops={'accuracy': acc_pair}) + + global_step = tf.train.get_or_create_global_step() + # mode == tf.estimator.ModeKeys.TRAIN + logits_grad = model.send('logits', logits, require_grad=True) + remote_train_op = model.minimize( + optimizer, logits, + grad_loss=logits_grad, + global_step=global_step) + + # mode == tf.estimator.ModeKeys.TRAIN + local_loss = tf.nn.sparse_softmax_cross_entropy_with_logits( + labels=y, logits=local_logits) + local_loss = tf.math.reduce_mean(local_loss) + + local_train_op = optimizer.minimize( + local_loss, global_step=global_step) + + correct = tf.nn.in_top_k(predictions=local_logits, targets=y, k=1) + acc = tf.reduce_mean(input_tensor=tf.cast(correct, tf.float32)) + logging_hook = tf.estimator.LoggingTensorHook( + {"local loss": local_loss, "local acc": acc}, every_n_iter=10) + return tf.estimator.EstimatorSpec( + mode=mode, + loss=local_loss, + train_op=local_train_op, + training_hooks=[logging_hook]) + + +def main(args): + logging.getLogger().setLevel(level=logging.INFO) + if args.local_worker: + flt.trainer_worker.train( + 'leader', args, input_fn, + local_model_fn, serving_input_receiver_fn) + else: + flt.trainer_worker.train( + 'leader', args, input_fn, + remote_model_fn, serving_input_receiver_fn) + +#if __name__ == '__main__': +# parser = flt.trainer_worker.create_argument_parser() +# args = parser.parse_args() +# main(args) diff --git a/test/trainer/test_data_visitor.py b/test/trainer/test_data_visitor.py index 378838c16..4099a0461 100644 --- a/test/trainer/test_data_visitor.py +++ b/test/trainer/test_data_visitor.py @@ -15,13 +15,15 @@ # coding: utf-8 import unittest -from fedlearner.trainer.data_visitor import _DataVisitor, _RawDataBlock +from datetime import datetime, timedelta +from fedlearner.trainer.data_visitor import _DataVisitor, _RawDataBlock,\ + RawDataBlockDealer, ShuffleType class TestLeaderDataVisitor(unittest.TestCase): def setUp(self): self._datablocks = [ _RawDataBlock( - "id_"+str(i), "path/to/"+str(i) + "id_"+str(i), "path/to/"+str(i), 0, 0, '' ) for i in range(10) ] @@ -29,7 +31,7 @@ def setUp(self): def test_next(self): epoch_num = 5 visitor = _DataVisitor( - self._datablocks, epoch_num) + self._datablocks, None, epoch_num) try: i = 0 c = 0 @@ -45,7 +47,7 @@ def test_next(self): def test_shuffle_next(self): epoch_num = 5 visitor = _DataVisitor( - self._datablocks, epoch_num, shuffle=True) + self._datablocks, None, epoch_num, shuffle_type=ShuffleType.ALL) try: i = 0 c = 0 @@ -70,7 +72,7 @@ def test_dump_restore(self): for i in range(epoch_num): output[i+1] = set() visitor = _DataVisitor( - self._datablocks, epoch_num, shuffle=True) + self._datablocks, None, epoch_num, shuffle_type=ShuffleType.ALL) for i in range(len(self._datablocks)*3 + 2): b = next(visitor) output[b.epoch].add(b.id) @@ -79,7 +81,7 @@ def test_dump_restore(self): print(data) visitor2 = _DataVisitor( - self._datablocks, epoch_num) + self._datablocks, None, epoch_num) visitor2.restore(buff) try: while True: @@ -92,5 +94,30 @@ def test_dump_restore(self): for j, id in enumerate(sorted(output[i+1])): assert self._datablocks[j].id == id + +class TestDataBlockDealer(unittest.TestCase): + def setUp(self): + start_time = datetime.strptime('20210101', '%Y%m%d') + hour_delta = timedelta(hours=4) + self._datablocks = [] + for i in range(20): + end_time = start_time + hour_delta + self._datablocks.append(_RawDataBlock( + "id_" + str(i), "path/to/" + str(i), + start_time.strftime('%Y%m%d%H%M%S'), + end_time.strftime('%Y%m%d%H%M%S'), + '' + )) + start_time += hour_delta + + def test_shuffle_in_day(self): + dealer = RawDataBlockDealer(self._datablocks) + dealer.shuffle_in_day() + + def test_shuffle(self): + dealer = RawDataBlockDealer(self._datablocks) + dealer.shuffle() + + if __name__ == '__main__': unittest.main() diff --git a/test/trainer/test_horizontal_nn_trainer.py b/test/trainer/test_horizontal_nn_trainer.py new file mode 100644 index 000000000..e90ddc236 --- /dev/null +++ b/test/trainer/test_horizontal_nn_trainer.py @@ -0,0 +1,479 @@ +# Copyright 2020 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 + +import unittest +import threading +import os +import time +import logging +import json +from datetime import datetime, timedelta +from multiprocessing import Process +import tensorflow.compat.v1 as tf +from tensorflow.compat.v1 import gfile +from queue import PriorityQueue +import enum +from tensorflow.core.example.feature_pb2 import FloatList, Features, Feature, \ + Int64List, BytesList + +from tensorflow.core.example.example_pb2 import Example + +import numpy as np + +from fedlearner.data_join import ( + data_block_manager, common, + raw_data_manifest_manager +) + +from fedlearner.common import ( + db_client, common_pb2 as common_pb, + data_join_service_pb2 as dj_pb +) + +from fedlearner.data_join.data_block_manager import DataBlockBuilder +from fedlearner.data_join.raw_data_iter_impl.tf_record_iter import TfExampleItem +import fedlearner.trainer as flt + +from graph_def.horizontal_leader import main as lm +from graph_def.horizontal_follower import main as fm + +debug_mode = False +local_mnist_path = "./mnist.npz" +output_path = "./output" +total_worker_num = 1 + +child_env = os.environ.copy() +child_env["KVSTORE_USE_MOCK"] = "on" +child_env["KVSTORE_MOCK_DISK_SYNC"] = "on" +os.environ = child_env + +class _Task(object): + def __init__(self, name, weight, target, args=None, kwargs=None, daemon=None, force_quit=False): + self.name = name + self.weight = 0 - weight + self._target = target + self._args = args + self._kwargs = kwargs + self.force_quit = force_quit + self._daemon = True + self._lock = threading.Lock() + self._task = None + self._stop = False + self._start_new() + + def _start_new(self): + if self._task is not None and self._task.is_alive(): + logging.info(" %s is alive, no need to start new" % self.name) + return + self._task = Process(target=self._target, name=self.name, + args=self._args, kwargs=self._kwargs, daemon=self._daemon) + self._task.start() + logging.info("Task starts %s" % self.name) + time.sleep(10) + + def __gt__(self, o): + return self.weight > o.weight + + def kill(self, force = False): + with self._lock: + logging.info("Kill task %s", self.name) + if self._task is None or not self._task.is_alive(): + return + if force or self.force_quit: + self._task.terminate() + elif self._task.is_alive(): + raise ValueError("can not kill by force") + + def start(self): + logging.info("begin to start") + with self._lock: + if self._stop: + return + if self._task.is_alive(): + logging.info(" %s is alive, no need to start" % self.name) + return + self._start_new() + time.sleep(2) + + def is_alive(self): + with self._lock: + if self._task is None: + return True + return self._task.is_alive() + +class _Signal(enum.Enum): + KILL = 1 + RUN = 2 + +class _Event(object): + def __init__(self, name, action, timeout): + self.name = name + self.action = action + self.timeout = timeout + self._start_time = time.time() + self._trigged = False + + def handle(self, task): + if self._trigged: + return + if self.timeout + self._start_time > time.time(): + return + logging.info("handle event: %s=%s", task.name, self.action) + self._trigged = True + if self.action == _Signal.KILL: + task.kill(True) + elif self.action == _Signal.RUN: + task.start() + else: + raise ValueError("unknown event %d" % self.action) + +class _TaskScheduler(object): + def __init__(self, timeout): + self._task_queue = PriorityQueue() + self._task_done = {} + self._start_time = time.time() + self._event_queue = [] + self._task_killed = {} + self._keepalive = [] + self._timeout = timeout + + def submit(self, task): + self._keepalive.append(task.name) + self._task_queue.put(task) + + def recv(self, ev): + self._event_queue.append(ev) + + def _handle_events(self, name, task): + for e in self._event_queue: + if e.name == name: + e.handle(task) + + def bye(self): + while not self._task_queue.empty(): + task = self._task_queue.get() + if task.is_alive(): + task.kill(True) + + def run(self): + while not self._task_queue.empty(): + task = [] + done = {} + while not self._task_queue.empty(): + next_task = self._task_queue.get() + logging.info("handle queue: %s", next_task.name) + if not next_task.is_alive(): + done[next_task.name] = next_task + continue + self._handle_events(next_task.name, next_task) + if next_task.is_alive(): + task.append(next_task) + else: + done[next_task.name] = next_task + for t in task: + self._task_queue.put(t) + + for k, v in done.items(): + if k in self._keepalive: + if v._task.exitcode != 0: + v.start() + self._task_queue.put(v) + continue + self._task_done[k] = v + time.sleep(1) + if self._timeout + self._start_time < time.time(): + logging.info("stop!!!!!") + return + + +def make_ckpt_dir(role, remote="local", rank=None): + if rank is None: + rank = "N" + ckpt_path = "{}/{}_ckpt_{}_{}".format(output_path, remote, role, rank) + exp_path = "{}/saved_model".format(ckpt_path) + if gfile.Exists(ckpt_path): + gfile.DeleteRecursively(ckpt_path) + return ckpt_path, exp_path + +def run_ps(port, env=None): + if env is not None: + os.environ = env + addr = "0.0.0.0:{}".format(port) + cluster_spec = tf.train.ClusterSpec({'local': {0: addr}}) + server = tf.train.Server(cluster_spec, job_name="local", task_index=0) + server.join() + +def run_lm(args, env=None): + if env is not None: + os.environ = env + lm(args) + +def run_fm(args, env=None): + if env is not None: + os.environ = env + fm(args) + + +class TestHorizontalNNTraining(unittest.TestCase): + def _create_data_block(self, data_source, partition_id, x, y, N): + data_block_metas = [] + dbm = data_block_manager.DataBlockManager(data_source, partition_id) + self.assertEqual(dbm.get_dumped_data_block_count(), 0) + self.assertEqual(dbm.get_lastest_data_block_meta(), None) + print(data_source.data_source_meta.name, data_source.output_base_dir, + x.shape) + chunk_size = x.shape[0] // N + + leader_index = 0 + follower_index = N * chunk_size * 10 + event_time = datetime.strptime('20210101', '%Y%m%d') + delta = timedelta(minutes=1) + for i in range(N): + builder = DataBlockBuilder( + common.data_source_data_block_dir(data_source), + data_source.data_source_meta.name, + partition_id, i, + dj_pb.WriterOptions(output_writer="TF_RECORD", + compressed_type="GZIP"), None + ) + builder.set_data_block_manager(dbm) + for j in range(chunk_size): + feat = {} + idx = i * chunk_size + j + exam_id = '{}'.format(idx).encode() + feat['example_id'] = Feature( + bytes_list=BytesList(value=[exam_id])) + evt_time =int(event_time.strftime('%Y%m%d%H%M%S')) + feat['event_time'] = Feature( + int64_list = Int64List(value=[evt_time]) + ) + feat['x'] = Feature(float_list=FloatList(value=list(x[idx]))) + if y is not None: + feat['y'] = Feature(int64_list=Int64List(value=[y[idx]])) + + feat['leader_index'] = Feature( + int64_list = Int64List(value=[leader_index]) + ) + feat['follower_index'] = Feature( + int64_list = Int64List(value=[follower_index]) + ) + example = Example(features=Features(feature=feat)) + builder.append_item(TfExampleItem(example.SerializeToString()), + leader_index, follower_index) + leader_index += 1 + follower_index += 1 + event_time += delta + data_block_metas.append(builder.finish_data_block()) + self.max_index = follower_index + return data_block_metas + + def _gen_ds_meta(self, role, index, data_source_name): + data_source = common_pb.DataSource() + data_source.data_source_meta.name = data_source_name + data_source.data_source_meta.partition_num = 1 + data_source.data_source_meta.start_time = 0 + data_source.data_source_meta.end_time = 100000 + data_source.output_base_dir = "{}/{}_{}_{}/data_source/".format( + output_path, data_source.data_source_meta.name, role, index) + data_source.role = role + return data_source + + def setUp(self): + self.sche = _TaskScheduler(250) + self.app_id = "test_trainer_v1" + if debug_mode: + (x, y), _ = tf.keras.datasets.mnist.load_data(local_mnist_path) + else: + (x, y), _ = tf.keras.datasets.mnist.load_data() + + x = x.reshape(x.shape[0], -1).astype(np.float32) / 255.0 + y = y.astype(np.int64) + + num_parts = 3 + num_sample = x.shape[0] + chunk_size = (num_sample // 2) + 1 + xs = [x[:chunk_size], x[chunk_size:num_sample], x[:chunk_size]] + ys = [y[:chunk_size], y[chunk_size:num_sample], y[:chunk_size]] + + self.kv_store = [None, None, None] + self._local_data_source = "test-liuqi-mnist-local" + data_source = [self._gen_ds_meta(common_pb.FLRole.Leader, 0, "test-liuqi-mnist-v1"), + self._gen_ds_meta(common_pb.FLRole.Leader, 1, self._local_data_source), + self._gen_ds_meta(common_pb.FLRole.Follower, 0, "test-liuqi-mnist-v1")] + self._etcd_base_dirs = ["fedlearner0", "fedlearner0", "fedlearner2"] + for role in range(num_parts): + os.environ['ETCD_BASE_DIR'] = self._etcd_base_dirs[role] + self.kv_store[role] = db_client.DBClient("etcd", True) + self.data_source = data_source + for role in range(num_parts): + common.commit_data_source(self.kv_store[role], data_source[role]) + if gfile.Exists(data_source[role].output_base_dir): + gfile.DeleteRecursively(data_source[role].output_base_dir) + manifest_manager = raw_data_manifest_manager.RawDataManifestManager( + self.kv_store[role], data_source[role] + ) + partition_num = data_source[role].data_source_meta.partition_num + #num_data_blocks = 100 if role == 1 else 2 + num_data_blocks = 100 if role == 1 else 20 + for i in range(partition_num): + self._create_data_block(data_source[role], i, + xs[role], ys[role], num_data_blocks) + #x[role], y if role == 0 else None) + + manifest_manager._finish_partition('join_example_rep', + dj_pb.JoinExampleState.UnJoined, dj_pb.JoinExampleState.Joined, + -1, i) + + #@unittest.skip("demonstrating skipping") + def test_remote_cluster(self): + parser = flt.trainer_worker.create_argument_parser() + parser.add_argument('--local-worker', + action='store_true', + help='is local worker') + num_worker = 2 + leader_master_address = "0.0.0.0:4051" + leader_cluster_spec = { + "clusterSpec": { + "Master": ["0.0.0.0:4050"], + "PS": ["0.0.0.0:4060"], + "Worker": ["0.0.0.0:4070", "0.0.0.0:4071", + "0.0.0.0:4080", "0.0.0.0:5081"] + } + } + leader_cluster_spec_str = json.dumps(leader_cluster_spec) + follower_master_address = "0.0.0.0:5051" + follower_cluster_spec = { + "clusterSpec": { + "Master": ["0.0.0.0:5050"], + "PS": ["0.0.0.0:5060"], + "Worker": ["0.0.0.0:5070", "0.0.0.0:5071"] + } + } + follower_cluster_spec_str = json.dumps(follower_cluster_spec) + + self.sche.bye() + # launch leader/follower master + ckpt_path, exp_path = make_ckpt_dir("leader", "remote") + args = parser.parse_args(( + "--master", + "--application-id", self.app_id, + "--master-addr", leader_master_address, + "--data-source", self.data_source[0].data_source_meta.name, + "--local-data-source", self.data_source[1].data_source_meta.name, + "--cluster-spec", leader_cluster_spec_str, + "--checkpoint-path", ckpt_path, + "--export-path", exp_path, + "--shuffle-in-day", 'true', + )) + child_env['ETCD_BASE_DIR'] = self._etcd_base_dirs[0] + tml = _Task(name="RunLeaderMaster", target=run_lm, args=(args,), + weight=1, force_quit=True, + kwargs={'env' : child_env}, daemon=True) + self.sche.submit(tml) + + ckpt_path, exp_path = make_ckpt_dir("follower", "remote") + args = parser.parse_args(( + "--master", + "--application-id", self.app_id, + "--master-addr", follower_master_address, + "--data-source", self.data_source[2].data_source_meta.name, + "--cluster-spec", follower_cluster_spec_str, + "--checkpoint-path", ckpt_path, + "--export-path", exp_path, + )) + child_env['ETCD_BASE_DIR'] = self._etcd_base_dirs[2] + tml = _Task(name="RunFollowerMaster", target=run_fm, args=(args,), + weight=1, force_quit=True, + kwargs={'env' : child_env}, daemon=True) + self.sche.submit(tml) + + # launch leader/follower PS + for i, addr in enumerate(leader_cluster_spec["clusterSpec"]["PS"]): + psl = _Task(name="RunLeaderPS_%d"%i, target=run_ps, args=(addr, ), + weight=1, force_quit=True, + kwargs={'env' : child_env}, daemon=True) + self.sche.submit(psl) + for i, addr in enumerate(follower_cluster_spec["clusterSpec"]["PS"]): + psl = _Task(name="RunFollowerPS_%d"%i, target=run_ps, args=(addr, ), + weight=1, force_quit=True, + kwargs={'env' : child_env}, daemon=True) + self.sche.submit(psl) + + # launch leader/follower worker + for i in range(num_worker): + _, leader_worker_port = \ + leader_cluster_spec["clusterSpec"]["Worker"][i].split(':') + leader_worker_port = int(leader_worker_port) + 10000 + _, follower_worker_port = \ + follower_cluster_spec["clusterSpec"]["Worker"][i].split(':') + follower_worker_port = int(follower_worker_port) + 10000 + + # leader worker + args = parser.parse_args(( + "--worker", + "--application-id", self.app_id, + "--master-addr", leader_master_address, + "--local-addr", "0.0.0.0:%d"%leader_worker_port, + "--peer-addr", "0.0.0.0:%d"%follower_worker_port, + "--cluster-spec", leader_cluster_spec_str, + "--worker-rank", str(i), + )) + ftm = _Task(name="RunLeaderWorker_%d"%i, target=run_lm, args=(args, ), + weight=1, force_quit=True, + kwargs={'env' : child_env}, daemon=True) + self.sche.submit(ftm) + + # follower worker + args = parser.parse_args(( + "--worker", + "--application-id", self.app_id, + "--master-addr", follower_master_address, + "--local-addr", "0.0.0.0:%d"%follower_worker_port, + "--peer-addr", "0.0.0.0:%d"%leader_worker_port, + "--cluster-spec", follower_cluster_spec_str, + "--worker-rank", str(i), + )) + ftm = _Task(name="RunLeaderWorker_%d"%i, target=run_fm, args=(args, ), + weight=1, force_quit=True, + kwargs={'env' : child_env}, daemon=True) + self.sche.submit(ftm) + + # leader local worker + local_worker_rank = i + num_worker + args = parser.parse_args(( + "--worker", + "--local-worker", + "--application-id", self.app_id, + "--master-addr", leader_master_address, + "--cluster-spec", leader_cluster_spec_str, + "--worker-rank", str(local_worker_rank), + )) + ftm = _Task(name="RunLeaderWorker_%d"%local_worker_rank, + target=run_lm, + args=(args, ), + weight=1, force_quit=True, + kwargs={'env' : child_env}, daemon=True) + self.sche.submit(ftm) + + self.sche.run() + + def tearDown(self): + self.sche.bye() + if not debug_mode and gfile.Exists(output_path): + gfile.DeleteRecursively(output_path) + +if __name__ == '__main__': + unittest.main() diff --git a/test/tree_model/test_filter_files.py b/test/tree_model/test_filter_files.py new file mode 100644 index 000000000..3f7127a7a --- /dev/null +++ b/test/tree_model/test_filter_files.py @@ -0,0 +1,36 @@ +import tempfile +import unittest +from pathlib import Path +from fedlearner.model.tree.trainer import filter_files + +class TestFilterFiles(unittest.TestCase): + + def test_filter_files(self): + path = tempfile.mkdtemp() + path = Path(path, 'test').resolve() + path.mkdir() + path.joinpath('test1').mkdir() + path.joinpath('test2').mkdir() + path.joinpath('3.csv').touch() + path.joinpath('3.tfrecord').touch() + path.joinpath('test1').joinpath('1.csv').touch() + path.joinpath('test1').joinpath('2.tfrecord').touch() + path.joinpath('test2').joinpath('2.csv').touch() + path.joinpath('test2').joinpath('1.tfrecord').touch() + path.joinpath('test1/test').mkdir() + path.joinpath('test1/test').joinpath('4.csv').touch() + path.joinpath('test2/test').mkdir() + path.joinpath('test2/test').joinpath('4.tfrecord').touch() + + files = filter_files(path, '.csv', '') + self.assertEqual(len(files), 4) + files = filter_files(path, '', '*tfr*') + self.assertEqual(len(files), 4) + files = filter_files(path, '', '') + self.assertEqual(len(files), 8) + files = filter_files(path, '.csv', '*1.*') + self.assertEqual(len(files), 1) + + +if __name__ == '__main__': + unittest.main() diff --git a/test/tree_model/test_secret_sharing.py b/test/tree_model/test_secret_sharing.py new file mode 100644 index 000000000..77678353c --- /dev/null +++ b/test/tree_model/test_secret_sharing.py @@ -0,0 +1,99 @@ +import os +import tempfile +import unittest +import numpy as np +import pandas as pd +import threading +from fedlearner.trainer.bridge import Bridge +from fedlearner.model.crypto.secret_sharing import SecretSharing, MultiTriplets + + +def make_data(path: str): + size = 1000000 + x = np.random.randint(10000, size=size).reshape(-1, 1) + y = np.random.randint(10000, size=size).reshape(-1, 1) + z = x * y + follower_x = np.random.randint(10000, size=size).reshape(-1, 1) + follower_y = np.random.randint(10000, size=size).reshape(-1, 1) + follower_z = np.random.randint(10000, size=size).reshape(-1, 1) + leader_x = x - follower_x + leader_y = y - follower_y + leader_z = z - follower_z + alice_beaver_triplets = np.concatenate([leader_x, leader_y, leader_z], axis=1) + bob_beaver_triplets = np.concatenate([follower_x, follower_y, follower_z], axis=1) + pd.DataFrame(alice_beaver_triplets).to_csv(os.path.join(path, 'alice_beaver.csv'), header=None, index=False) + pd.DataFrame(bob_beaver_triplets).to_csv(os.path.join(path, 'bob_beaver.csv'), header=None, index=False) + + +class TestSecretSharing(unittest.TestCase): + + def leader_test_reveal(self, data: np.ndarray, expected_data: np.ndarray): + bridge = Bridge('leader', 50051, 'localhost:50052') + bridge.connect() + revealed_data = SecretSharing(data, 'leader', bridge).reveal() + bridge.terminate() + np.testing.assert_almost_equal(revealed_data, expected_data) + + def follower_test_reveal(self, data: np.ndarray, expected_data: np.ndarray): + bridge = Bridge('follower', 50052, 'localhost:50051') + bridge.connect() + revealed_data = SecretSharing(data, 'follower', bridge).reveal() + bridge.terminate() + np.testing.assert_almost_equal(revealed_data, expected_data) + + def leader_test_mul(self, a: np.ndarray, b: np.ndarray, expected_c: np.ndarray, path: str): + bridge = Bridge('leader', 50053, 'localhost:50054') + bridge.connect() + role = 'leader' + multi_triplets = MultiTriplets(path) + ss_a = SecretSharing(a, role, bridge, multi_triplets) + ss_b = SecretSharing(b, role, bridge, multi_triplets) + ss_c = ss_a * ss_b + c = SecretSharing(ss_c, role, bridge).reveal() + bridge.terminate() + np.testing.assert_almost_equal(c, expected_c) + + def follower_test_mul(self, a: np.ndarray, b: np.ndarray, expected_c: np.ndarray, path: str): + bridge = Bridge('leader', 50054, 'localhost:50053') + bridge.connect() + role = 'follower' + multi_triplets = MultiTriplets(path) + ss_a = SecretSharing(a, role, bridge, multi_triplets) + ss_b = SecretSharing(b, role, bridge, multi_triplets) + ss_c = ss_a * ss_b + c = SecretSharing(ss_c, role, bridge).reveal() + bridge.terminate() + np.testing.assert_almost_equal(c, expected_c) + + def test_reveal(self): + data = np.random.randint(100, size=100) + follower_data = np.random.randint(100, size=100) + leader_data = data - follower_data + + thread = threading.Thread(target=self.follower_test_reveal, args=(follower_data, data)) + thread.start() + self.leader_test_reveal(leader_data, data) + thread.join() + + def test_ss_mul(self): + size = 100 + a = np.random.randint(10000, size=size) + b = np.random.randint(10000, size=size) + follower_a = np.random.randint(10000, size=size) + follower_b = np.random.randint(10000, size=size) + leader_a = a - follower_a + leader_b = b - follower_b + expected_c = a * b + + with tempfile.TemporaryDirectory() as temp_dir: + make_data(temp_dir) + leader_path = os.path.join(temp_dir, 'alice_beaver.csv') + follower_path = os.path.join(temp_dir, 'bob_beaver.csv') + thread = threading.Thread(target=self.follower_test_mul, args=(follower_a, follower_b, expected_c, follower_path)) + thread.start() + self.leader_test_mul(leader_a, leader_b, expected_c, leader_path) + thread.join() + + +if __name__ == '__main__': + unittest.main() diff --git a/test/tree_model/test_trainer.py b/test/tree_model/test_trainer.py new file mode 100644 index 000000000..86f9752f5 --- /dev/null +++ b/test/tree_model/test_trainer.py @@ -0,0 +1,156 @@ +import os +import tempfile +import unittest +import shutil +import random +from pathlib import Path +from threading import Thread + +from fedlearner.trainer.bridge import Bridge +from tensorflow.train import Feature, FloatList, Features, Example, Int64List +from fedlearner.model.tree.trainer import read_data_dir +from fedlearner.model.tree.trainer import DataBlockLoader, DataBlockInfo +import tensorflow as tf +import numpy as np +import csv + +class DataBlockLoaderTest(unittest.TestCase): + + def _make_data(self, path: str): + Path(os.path.join(path, '0')).mkdir() + Path(os.path.join(path, '0', '_SUCCESS')).touch() + Path(os.path.join(path, '0', 'part-r-00000')).touch() + Path(os.path.join(path, '0', 'part-r-00001')).touch() + + def setUp(self): + self._leader_data_path = tempfile.mkdtemp() + self._follower_data_path = tempfile.mkdtemp() + self._make_data(path=self._leader_data_path) + self._make_data(path=self._follower_data_path) + + def tearDown(self): + shutil.rmtree(self._leader_data_path) + shutil.rmtree(self._follower_data_path) + + def test_get_next_block(self): + leader_bridge = Bridge(role='leader', listen_port=50051, remote_address='localhost:50052') + follower_bridge = Bridge(role='follower', listen_port=50052, remote_address='localhost:50051') + follower_connect = Thread(target=follower_bridge.connect) + follower_connect.start() + leader_bridge.connect() + leader_loader = DataBlockLoader(role='leader', bridge=leader_bridge, data_path=self._leader_data_path, ext=None, + file_wildcard='**/part*') + + follower_loader = DataBlockLoader(role='follower', bridge=follower_bridge, data_path=self._follower_data_path, + ext=None, file_wildcard='**/part*') + data_block = follower_loader.get_next_block() + self.assertEqual(data_block, + DataBlockInfo(block_id='0/part-r-00000', + data_path=os.path.join(self._follower_data_path, '0/part-r-00000'))) + data_block = follower_loader.get_next_block() + self.assertEqual(data_block, + DataBlockInfo(block_id='0/part-r-00001', + data_path=os.path.join(self._follower_data_path, '0/part-r-00001'))) + data_block = follower_loader.get_next_block() + self.assertIsNone(data_block) + data_block = leader_loader.get_next_block() + self.assertEqual(data_block, + DataBlockInfo(block_id='0/part-r-00000', data_path=os.path.join(self._leader_data_path, + '0/part-r-00000'))) + data_block = leader_loader.get_next_block() + self.assertEqual(data_block, + DataBlockInfo(block_id='0/part-r-00001', data_path=os.path.join(self._leader_data_path, + '0/part-r-00001'))) + data_block = leader_loader.get_next_block() + self.assertIsNone(data_block) + + +class MultiprocessingDataReadTest(unittest.TestCase): + + def _make_data(self): + root = tempfile.mkdtemp() + record_root = os.path.join(root, 'tfrecord_test') + csv_root = os.path.join(root, 'csv_test') + os.mkdir(record_root) + os.mkdir(csv_root) + + for i in range(5): + file_name = 'part-' + str(i).zfill(4) + '.tfrecord' + file_path = os.path.join(record_root, file_name) + writer = tf.io.TFRecordWriter(file_path) + for _ in range(5): + features = { + 'f_' + str(j): Feature( + float_list=FloatList(value=[random.random()]) + ) for j in range(3) + } + features['i_0'] = Feature( + int64_list=Int64List(value=[random.randint(0, 100)]) + ) + features['label'] = Feature( + int64_list=Int64List(value=[random.randint(0, 1)]) + ) + writer.write(Example( + features=Features(feature=features) + ).SerializeToString() + ) + writer.close() + + for i in range(5): + file_name = 'part-' + str(i).zfill(4) + '.csv' + file_path = os.path.join(csv_root, file_name) + with open(file_path, 'w') as file: + csv_writer = csv.writer(file) + csv_writer.writerow(['f_0', 'f_1', 'f_2', 'i_0', 'label']) + for _ in range(5): + csv_writer.writerow([ + random.random(), random.random(), random.random(), + random.randint(0, 100), random.randint(0, 1) + ]) + return record_root, csv_root + + def test_multiprocessing_data_read(self): + record_root, csv_root = self._make_data() + + record_1 = read_data_dir( + '.tfrecord', '*tfrecord', 'tfrecord', + record_root, False, True, '', 'i_0', 'label', 1) + record_4 = read_data_dir( + '.tfrecord', '*tfrecord', 'tfrecord', + record_root, False, True, '', 'i_0', 'label', 4) + # result shape: + # features, cat_features, cont_columns, + # cat_columns, labels, example_ids, raw_ids + np.testing.assert_almost_equal(record_1[0], record_4[0]) + np.testing.assert_almost_equal(record_1[1], record_4[1]) + np.testing.assert_almost_equal(record_1[4], record_4[4]) + + test_file = os.path.join(record_root, 'part-0000.tfrecord') + read_data_dir('.tfrecord', '*tfrecord', 'tfrecord', test_file, + False, True, '', 'i_0', 'label', 1) + read_data_dir('.tfrecord', '*tfrecord', 'tfrecord', test_file, + False, True, '', 'i_0', 'label', 4) + np.testing.assert_almost_equal(record_1[0], record_4[0]) + np.testing.assert_almost_equal(record_1[1], record_4[1]) + np.testing.assert_almost_equal(record_1[4], record_4[4]) + + csv_1 = read_data_dir('.csv', '*csv', 'csv', csv_root, + False, True, '', 'i_0', 'label', 1) + csv_4 = read_data_dir('.csv', '*csv', 'csv', csv_root, + False, True, '', 'i_0', 'label', 4) + np.testing.assert_almost_equal(csv_1[0], csv_4[0]) + np.testing.assert_almost_equal(csv_1[1], csv_4[1]) + np.testing.assert_almost_equal(csv_1[4], csv_4[4]) + + test_file = os.path.join(csv_root, 'part-0000.csv') + csv_1 = read_data_dir('.csv', '*csv', 'csv', test_file, + False, True, '', 'i_0', 'label', 1) + csv_4 = read_data_dir('.csv', '*csv', 'csv', test_file, + False, True, '', 'i_0', 'label', 4) + np.testing.assert_almost_equal(csv_1[0], csv_4[0]) + np.testing.assert_almost_equal(csv_1[1], csv_4[1]) + np.testing.assert_almost_equal(csv_1[4], csv_4[4]) + + +if __name__ == '__main__': + unittest.main() diff --git a/web_console_v2/README.md b/web_console_v2/README.md index 7167f3a66..e91af9910 100644 --- a/web_console_v2/README.md +++ b/web_console_v2/README.md @@ -2,7 +2,7 @@ ### Docker ```shell -docker build -t fedlearner_webconsole_v2 . +docker build --memory 4G --tag fedlearner_webconsole_v2 . docker run --rm -it -p 1989:1989 -p 1990:1990 fedlearner_webconsole_v2 ``` Then visiting http://localhost:1989/ for the UI. diff --git a/web_console_v2/api/.gitignore b/web_console_v2/api/.gitignore index 1b9602cf7..b42ddd478 100644 --- a/web_console_v2/api/.gitignore +++ b/web_console_v2/api/.gitignore @@ -8,3 +8,5 @@ fedlearner_webconsole/proto/*.pyi # Coverage generated .coverage_html_report/ .coverage* + +root.log.* \ No newline at end of file diff --git a/web_console_v2/api/command.py b/web_console_v2/api/command.py index 6acc42f67..ca3fdc337 100644 --- a/web_console_v2/api/command.py +++ b/web_console_v2/api/command.py @@ -15,8 +15,11 @@ # coding: utf-8 from config import Config from fedlearner_webconsole.app import create_app -from fedlearner_webconsole.db import db +from fedlearner_webconsole.db import db_handler as db from fedlearner_webconsole.initial_db import initial_db +from flask_migrate import Migrate + +from fedlearner_webconsole.utils.hooks import pre_start_hook class CliConfig(Config): @@ -25,7 +28,10 @@ class CliConfig(Config): START_COMPOSER = False +pre_start_hook() +migrate = Migrate() app = create_app(CliConfig()) +migrate.init_app(app, db) @app.cli.command('create-initial-data') @@ -36,4 +42,3 @@ def create_initial_data(): @app.cli.command('create-db') def create_db(): db.create_all() - db.session.commit() diff --git a/web_console_v2/api/config.py b/web_console_v2/api/config.py index ef77e080a..e58492b6e 100644 --- a/web_console_v2/api/config.py +++ b/web_console_v2/api/config.py @@ -20,8 +20,6 @@ from fedlearner_webconsole.db import get_database_uri from envs import Envs -BASE_DIR = os.path.abspath(os.path.dirname(__file__)) - class Config(object): SQLALCHEMY_DATABASE_URI = get_database_uri() diff --git a/web_console_v2/api/envs.py b/web_console_v2/api/envs.py index 123620e7a..6f6f5f39d 100644 --- a/web_console_v2/api/envs.py +++ b/web_console_v2/api/envs.py @@ -6,9 +6,9 @@ class Envs(object): TZ = pytz.timezone(os.environ.get('TZ', 'UTC')) - HDFS_SERVER = os.environ.get('HDFS_SERVER', None) ES_HOST = os.environ.get('ES_HOST', 'fedlearner-stack-elasticsearch-client') + ES_READ_HOST = os.environ.get('ES_READ_HOST', ES_HOST) ES_PORT = os.environ.get('ES_PORT', 9200) ES_USERNAME = os.environ.get('ES_USERNAME', 'elastic') ES_PASSWORD = os.environ.get('ES_PASSWORD', 'Fedlearner123') @@ -38,6 +38,16 @@ class Envs(object): GRPC_CLIENT_TIMEOUT = os.environ.get('GRPC_CLIENT_TIMEOUT', 5) # storage filesystem STORAGE_ROOT = os.getenv('STORAGE_ROOT', '/data') + # BASE_DIR + BASE_DIR = os.path.abspath(os.path.dirname(__file__)) + # spark on k8s image url + SPARKAPP_IMAGE_URL = os.getenv('SPARKAPP_IMAGE_URL', None) + SPARKAPP_FILES_PATH = os.getenv('SPARKAPP_FILES_PATH', None) + SPARKAPP_VOLUMES = os.getenv('SPARKAPP_VOLUMES', None) + SPARKAPP_VOLUME_MOUNTS = os.getenv('SPARKAPP_VOLUME_MOUNTS', None) + + # Hooks + PRE_START_HOOK = os.environ.get('PRE_START_HOOK', None) class Features(object): diff --git a/web_console_v2/api/fedlearner_webconsole/app.py b/web_console_v2/api/fedlearner_webconsole/app.py index 82452d657..618b13b30 100644 --- a/web_console_v2/api/fedlearner_webconsole/app.py +++ b/web_console_v2/api/fedlearner_webconsole/app.py @@ -14,7 +14,6 @@ # coding: utf-8 # pylint: disable=wrong-import-position, global-statement -import importlib import logging import logging.config import os @@ -22,13 +21,11 @@ from http import HTTPStatus from flask import Flask, jsonify -from flask_migrate import Migrate from flask_restful import Api from flask_jwt_extended import JWTManager from envs import Envs from fedlearner_webconsole.utils import metrics -migrate = Migrate() jwt = JWTManager() from fedlearner_webconsole.auth.apis import initialize_auth_apis @@ -113,6 +110,8 @@ def user_lookup_callback(jwt_header, jwt_data): @jwt.token_in_blocklist_loader def check_if_token_invalid(jwt_header, jwt_data): + del jwt_header # unused by check_if_token_invalid + jti = jwt_data['jti'] session = Session.query.filter_by(jti=jti).first() return session is None @@ -122,18 +121,9 @@ def create_app(config): # format logging logging.config.dictConfig(LOGGING_CONFIG) - before_hook_path = os.getenv('FEDLEARNER_WEBCONSOLE_BEFORE_APP_START') - if before_hook_path: - module_path, func_name = before_hook_path.split(':') - module = importlib.import_module(module_path) - # Dynamically run the function - getattr(module, func_name)() - app = Flask('fedlearner_webconsole') app.config.from_object(config) - db.init_app(app) - migrate.init_app(app, db) jwt.init_app(app) # Error handlers @@ -142,6 +132,9 @@ def create_app(config): app.register_error_handler(WebConsoleApiException, make_response) app.register_error_handler(Exception, _handle_uncaught_exception) + # TODO(wangsen.0914): This will be removed sooner! + db.init_app(app) + api = Api(prefix='/api/v2') initialize_auth_apis(api) initialize_project_apis(api) @@ -152,7 +145,7 @@ def create_app(config): initialize_setting_apis(api) initialize_mmgr_apis(api) initialize_sparkapps_apis(api) - if os.environ.get('FLASK_ENV') != 'production': + if os.environ.get('FLASK_ENV') != 'production' or Envs.DEBUG: initialize_debug_apis(api) # A hack that use our customized error handlers # Ref: https://github.com/flask-restful/flask-restful/issues/280 diff --git a/web_console_v2/api/fedlearner_webconsole/auth/apis.py b/web_console_v2/api/fedlearner_webconsole/auth/apis.py index 01df1a17c..7206e3497 100644 --- a/web_console_v2/api/fedlearner_webconsole/auth/apis.py +++ b/web_console_v2/api/fedlearner_webconsole/auth/apis.py @@ -14,12 +14,15 @@ # coding: utf-8 # pylint: disable=cyclic-import +import re import datetime from http import HTTPStatus from flask import request from flask_restful import Resource, reqparse from flask_jwt_extended.utils import get_current_user from flask_jwt_extended import create_access_token, decode_token, get_jwt + +from fedlearner_webconsole.utils.base64 import base64decode from fedlearner_webconsole.utils.decorators import jwt_required from fedlearner_webconsole.utils.decorators import admin_required @@ -32,6 +35,28 @@ UnauthorizedException, NoAccessException) +# rule: password must have a letter, a num and a special character +PASSWORD_FORMAT_L = re.compile(r'.*[A-Za-z]') +PASSWORD_FORMAT_N = re.compile(r'.*[0-9]') +PASSWORD_FORMAT_S = re.compile(r'.*[`!@#$%^&*()\-_=+|{}\[\];:\'\",<.>/?~]') + + +def check_password_format(password: str): + if not 8 <= len(password) <= 20: + raise InvalidArgumentException( + 'Password is not legal: 8 <= length <= 20') + required_chars = [] + if PASSWORD_FORMAT_L.match(password) is None: + required_chars.append('a letter') + if PASSWORD_FORMAT_N.match(password) is None: + required_chars.append('a num') + if PASSWORD_FORMAT_S.match(password) is None: + required_chars.append('a special character') + if required_chars: + tip = ', '.join(required_chars) + raise InvalidArgumentException( + f'Password is not legal: must have {tip}.') + class SigninApi(Resource): def post(self): @@ -44,11 +69,11 @@ def post(self): help='password is empty') data = parser.parse_args() username = data['username'] - password = data['password'] + password = base64decode(data['password']) user = User.query.filter_by(username=username).filter_by( state=State.ACTIVE).first() if user is None: - raise NotFoundException() + raise NotFoundException(f'Failed to find user: {username}') if not user.verify_password(password): raise UnauthorizedException('Invalid password') token = create_access_token(identity=username) @@ -61,11 +86,11 @@ def post(self): db.session.commit() return { - 'data': { - 'user': user.to_dict(), - 'access_token': token - } - }, HTTPStatus.OK + 'data': { + 'user': user.to_dict(), + 'access_token': token + } + }, HTTPStatus.OK @jwt_required() def delete(self): @@ -105,11 +130,13 @@ def post(self): data = parser.parse_args() username = data['username'] - password = data['password'] + password = base64decode(data['password']) role = data['role'] name = data['name'] email = data['email'] + check_password_format(password) + if User.query.filter_by(username=username).first() is not None: raise ResourceConflictException( 'user {} already exists'.format(username)) @@ -129,7 +156,8 @@ class UserApi(Resource): def _find_user(self, user_id) -> User: user = User.query.filter_by(id=user_id).first() if user is None or user.state == State.DELETED: - raise NotFoundException() + raise NotFoundException( + f'Failed to find user_id: {user_id}') return user def _check_current_user(self, user_id, msg): @@ -158,7 +186,9 @@ def patch(self, user_id): if k not in mutable_attrs: raise InvalidArgumentException(f'cannot edit {k} attribute!') if k == 'password': - user.set_password(v) + password = base64decode(v) + check_password_format(password) + user.set_password(password) else: setattr(user, k, v) diff --git a/web_console_v2/api/fedlearner_webconsole/composer/composer.py b/web_console_v2/api/fedlearner_webconsole/composer/composer.py index 1094d3340..e0040ba99 100644 --- a/web_console_v2/api/fedlearner_webconsole/composer/composer.py +++ b/web_console_v2/api/fedlearner_webconsole/composer/composer.py @@ -407,4 +407,4 @@ def _build_pipeline(name: str, items: List[IItem], composer = Composer(config=ComposerConfig( - runner_fn=global_runner_fn, name='scheduler for fedlearner webconsole')) + runner_fn=global_runner_fn(), name='scheduler for fedlearner webconsole')) diff --git a/web_console_v2/api/fedlearner_webconsole/composer/interface.py b/web_console_v2/api/fedlearner_webconsole/composer/interface.py index 358eb9f5b..f9acdeb88 100644 --- a/web_console_v2/api/fedlearner_webconsole/composer/interface.py +++ b/web_console_v2/api/fedlearner_webconsole/composer/interface.py @@ -22,10 +22,13 @@ from fedlearner_webconsole.composer.models import Context, RunnerStatus +# NOTE: remember to register new item in `global_runner_fn` \ +# which defined in `runner.py` class ItemType(enum.Enum): - TASK = 'task' + TASK = 'task' # test only MEMORY = 'memory' WORKFLOW_CRON_JOB = 'workflow_cron_job' + DATA_PIPELINE = 'data_pipeline' # item interface diff --git a/web_console_v2/api/fedlearner_webconsole/composer/runner.py b/web_console_v2/api/fedlearner_webconsole/composer/runner.py index e9140e79c..46d87ec20 100644 --- a/web_console_v2/api/fedlearner_webconsole/composer/runner.py +++ b/web_console_v2/api/fedlearner_webconsole/composer/runner.py @@ -16,12 +16,14 @@ import datetime import logging import random +import sys import time from typing import Tuple from fedlearner_webconsole.composer.interface import IItem, IRunner, ItemType from fedlearner_webconsole.composer.models import Context, RunnerStatus, \ SchedulerRunner +from fedlearner_webconsole.dataset.data_pipeline import DataPipelineRunner from fedlearner_webconsole.db import get_session from fedlearner_webconsole.workflow.cronjob import WorkflowCronJob @@ -77,8 +79,16 @@ def result(self, context: Context) -> Tuple[RunnerStatus, dict]: return RunnerStatus.DONE, {} -# register runner_fn -global_runner_fn = { - ItemType.MEMORY.value: MemoryRunner, - ItemType.WORKFLOW_CRON_JOB.value: WorkflowCronJob, -} +def global_runner_fn(): + # register runner_fn + runner_fn = { + ItemType.MEMORY.value: MemoryRunner, + ItemType.WORKFLOW_CRON_JOB.value: WorkflowCronJob, + ItemType.DATA_PIPELINE.value: DataPipelineRunner, + } + for item in ItemType: + if item.value in runner_fn or item == ItemType.TASK: + continue + logging.error(f'failed to find item, {item.value}') + sys.exit(-1) + return runner_fn diff --git a/web_console_v2/api/fedlearner_webconsole/composer/runner_cache.py b/web_console_v2/api/fedlearner_webconsole/composer/runner_cache.py index fd487a74a..bd93e8bac 100644 --- a/web_console_v2/api/fedlearner_webconsole/composer/runner_cache.py +++ b/web_console_v2/api/fedlearner_webconsole/composer/runner_cache.py @@ -13,6 +13,7 @@ # limitations under the License. # coding: utf-8 +import logging import threading from fedlearner_webconsole.composer.interface import IRunner @@ -37,6 +38,11 @@ def find_runner(self, runner_id: int, runner_name: str) -> IRunner: if obj: return obj item_type, item_id = runner_name.rsplit('_', 1) + if item_type not in self.runner_fn: + logging.error( + f'failed to find item_type {item_type} in runner_fn, ' + f'please register it in global_runner_fn') + raise ValueError(f'unknown item_type {item_type} in runner') obj = self.runner_fn[item_type](int(item_id)) self._cache[key] = obj return obj diff --git a/web_console_v2/api/fedlearner_webconsole/dataset/apis.py b/web_console_v2/api/fedlearner_webconsole/dataset/apis.py index 4bc5eaef8..865f41a26 100644 --- a/web_console_v2/api/fedlearner_webconsole/dataset/apis.py +++ b/web_console_v2/api/fedlearner_webconsole/dataset/apis.py @@ -25,9 +25,10 @@ from fedlearner_webconsole.dataset.models import (Dataset, DatasetType, BatchState, DataBatch) +from fedlearner_webconsole.dataset.services import DatasetService from fedlearner_webconsole.exceptions import (InvalidArgumentException, NotFoundException) -from fedlearner_webconsole.db import db +from fedlearner_webconsole.db import db_handler as db from fedlearner_webconsole.proto import dataset_pb2 from fedlearner_webconsole.scheduler.scheduler import scheduler from fedlearner_webconsole.utils.decorators import jwt_required @@ -47,10 +48,12 @@ def _get_dataset_path(dataset_name): class DatasetApi(Resource): @jwt_required() def get(self, dataset_id): - dataset = Dataset.query.get(dataset_id) - if dataset is None: - raise NotFoundException() - return {'data': dataset.to_dict()} + with db.session_scope() as session: + dataset = session.query(Dataset).get(dataset_id) + if dataset is None: + raise NotFoundException( + f'Failed to find dataset: {dataset_id}') + return {'data': dataset.to_dict()} @jwt_required() def patch(self, dataset_id: int): @@ -65,22 +68,53 @@ def patch(self, dataset_id: int): help='dataset comment') parser.add_argument('comment') data = parser.parse_args() - dataset = db.session.query(Dataset).filter_by(id=dataset_id).first() - if not dataset: - raise NotFoundException() - if data['name']: - dataset.name = data['name'] - if data['comment']: - dataset.comment = data['comment'] - db.session.commit() - return {'data': dataset.to_dict()}, HTTPStatus.OK + with db.session_scope() as session: + dataset = session.query(Dataset).filter_by(id=dataset_id).first() + if not dataset: + raise NotFoundException( + f'Failed to find dataset: {dataset_id}') + if data['name']: + dataset.name = data['name'] + if data['comment']: + dataset.comment = data['comment'] + session.commit() + return {'data': dataset.to_dict()}, HTTPStatus.OK + + +class DatasetPreviewApi(Resource): + def get(self, dataset_id: int): + if dataset_id <= 0: + raise NotFoundException(f'Failed to find dataset: {dataset_id}') + with db.session_scope() as session: + data = DatasetService(session).get_dataset_preview(dataset_id) + return {'data': data} + + +class DatasetMetricsApi(Resource): + def get(self, dataset_id: int): + if dataset_id <= 0: + raise NotFoundException(f'Failed to find dataset: {dataset_id}') + name = request.args.get('name', None) + if not name: + raise InvalidArgumentException(f'required params name') + with db.session_scope() as session: + data = DatasetService(session).feature_metrics(name, dataset_id) + return {'data': data} class DatasetsApi(Resource): @jwt_required() def get(self): - datasets = Dataset.query.order_by(Dataset.created_at.desc()).all() - return {'data': [d.to_dict() for d in datasets]} + parser = reqparse.RequestParser() + parser.add_argument('project', + type=int, + required=False, + help='project') + data = parser.parse_args() + with db.session_scope() as session: + datasets = DatasetService(session).get_datasets( + project_id=int(data['project'] or 0)) + return {'data': [d.to_dict() for d in datasets]} @jwt_required() def post(self): @@ -104,22 +138,23 @@ def post(self): comment = body.get('comment') project_id = body.get('project_id') - try: - # Create dataset - dataset = Dataset( - name=name, - dataset_type=dataset_type, - comment=comment, - path=_get_dataset_path(name), - project_id=project_id, - ) - db.session.add(dataset) - # TODO: scan cronjob - db.session.commit() - return {'data': dataset.to_dict()} - except Exception as e: - db.session.rollback() - raise InvalidArgumentException(details=str(e)) + with db.session_scope() as session: + try: + # Create dataset + dataset = Dataset( + name=name, + dataset_type=dataset_type, + comment=comment, + path=_get_dataset_path(name), + project_id=project_id, + ) + session.add(dataset) + # TODO: scan cronjob + session.commit() + return {'data': dataset.to_dict()} + except Exception as e: + session.rollback() + raise InvalidArgumentException(details=str(e)) class BatchesApi(Resource): @@ -139,40 +174,40 @@ def post(self, dataset_id: int): files = body.get('files') move = body.get('move', False) comment = body.get('comment') - - dataset = Dataset.query.filter_by(id=dataset_id).first() - if dataset is None: - raise NotFoundException() - if event_time is None and dataset.type == DatasetType.STREAMING: - raise InvalidArgumentException( - details='data_batch.event_time is empty') - # TODO: PSI dataset should not allow multi batches - - # Use current timestamp to fill when type is PSI - event_time = datetime.fromtimestamp(event_time - or datetime.utcnow().timestamp(), - tz=timezone.utc) - batch_folder_name = event_time.strftime('%Y%m%d_%H%M%S') - batch_path = f'{dataset.path}/batch/{batch_folder_name}' - # Create batch - batch = DataBatch(dataset_id=dataset.id, - event_time=event_time, - comment=comment, - state=BatchState.NEW, - move=move, - path=batch_path) - batch_details = dataset_pb2.DataBatch() - for file_path in files: - file = batch_details.files.add() - file.source_path = file_path - file_name = file_path.split('/')[-1] - file.destination_path = f'{batch_path}/{file_name}' - batch.set_details(batch_details) - db.session.add(batch) - db.session.commit() - db.session.refresh(batch) - scheduler.wakeup(data_batch_ids=[batch.id]) - return {'data': batch.to_dict()} + with db.session_scope() as session: + dataset = session.query(Dataset).filter_by(id=dataset_id).first() + if dataset is None: + raise NotFoundException( + f'Failed to find dataset: {dataset_id}') + if event_time is None and dataset.type == DatasetType.STREAMING: + raise InvalidArgumentException( + details='data_batch.event_time is empty') + # TODO: PSI dataset should not allow multi batches + + # Use current timestamp to fill when type is PSI + event_time = datetime.fromtimestamp( + event_time or datetime.utcnow().timestamp(), tz=timezone.utc) + batch_folder_name = event_time.strftime('%Y%m%d_%H%M%S') + batch_path = f'{dataset.path}/batch/{batch_folder_name}' + # Create batch + batch = DataBatch(dataset_id=dataset.id, + event_time=event_time, + comment=comment, + state=BatchState.NEW, + move=move, + path=batch_path) + batch_details = dataset_pb2.DataBatch() + for file_path in files: + file = batch_details.files.add() + file.source_path = file_path + file_name = file_path.split('/')[-1] + file.destination_path = f'{batch_path}/{file_name}' + batch.set_details(batch_details) + session.add(batch) + session.commit() + session.refresh(batch) + scheduler.wakeup(data_batch_ids=[batch.id]) + return {'data': batch.to_dict()} class FilesApi(Resource): @@ -195,4 +230,7 @@ def initialize_dataset_apis(api: Api): api.add_resource(DatasetsApi, '/datasets') api.add_resource(DatasetApi, '/datasets/') api.add_resource(BatchesApi, '/datasets//batches') + api.add_resource(DatasetPreviewApi, '/datasets//preview') + api.add_resource(DatasetMetricsApi, + '/datasets//feature_metrics') api.add_resource(FilesApi, '/files') diff --git a/web_console_v2/api/fedlearner_webconsole/dataset/data_pipeline.py b/web_console_v2/api/fedlearner_webconsole/dataset/data_pipeline.py new file mode 100644 index 000000000..70b6d4588 --- /dev/null +++ b/web_console_v2/api/fedlearner_webconsole/dataset/data_pipeline.py @@ -0,0 +1,185 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +import io +import logging +import os +import tarfile +import traceback + +from enum import Enum +from copy import deepcopy +from typing import Tuple, Optional, List +from uuid import uuid4 + +from envs import Envs + +from fedlearner_webconsole.composer.interface import IItem, IRunner, ItemType +from fedlearner_webconsole.composer.models import Context, RunnerStatus +from fedlearner_webconsole.sparkapp.service import SparkAppService +from fedlearner_webconsole.sparkapp.schema import SparkAppConfig + + +class DataPipelineType(Enum): + ANALYZER = 'analyzer' + CONVERTER = 'converter' + TRANSFORMER = 'transformer' + + +class DataPipelineItem(IItem): + def __init__(self, task_id: int): + self.id = task_id + + def type(self) -> ItemType: + return ItemType.DATA_PIPELINE + + def get_id(self) -> int: + return self.id + + +class DataPipelineRunner(IRunner): + TYPE_PARAMS_MAPPER = { + DataPipelineType.ANALYZER: { + 'files_dir': 'fedlearner_webconsole/dataset/sparkapp/pipeline', + 'main_application': 'pipeline/analyzer.py', + }, + DataPipelineType.CONVERTER: { + 'files_dir': 'fedlearner_webconsole/dataset/sparkapp/pipeline', + 'main_application': 'pipeline/converter.py', + }, + DataPipelineType.TRANSFORMER: { + 'files_dir': 'fedlearner_webconsole/dataset/sparkapp/pipeline', + 'main_application': 'pipeline/transformer.py', + } + } + + SPARKAPP_STATE_TO_RUNNER_STATUS = { + '': RunnerStatus.RUNNING, + 'SUBMITTED': RunnerStatus.RUNNING, + 'PENDING_RERUN': RunnerStatus.RUNNING, + 'RUNNING': RunnerStatus.RUNNING, + 'COMPLETED': RunnerStatus.DONE, + 'SUCCEEDING': RunnerStatus.DONE, + 'FAILED': RunnerStatus.FAILED, + 'SUBMISSION_FAILED': RunnerStatus.FAILED, + 'INVALIDATING': RunnerStatus.FAILED, + 'FAILING': RunnerStatus.FAILED, + 'UNKNOWN': RunnerStatus.FAILED + } + + def __init__(self, task_id: int) -> None: + self.task_id = task_id + self.task_type = None + self.files_dir = None + self.files_path = None + self.main_application = None + self.command = [] + self.sparkapp_name = None + self.args = {} + self.started = False + self.error_msg = False + + self.spark_service = SparkAppService() + + def start(self, context: Context): + try: + self.started = True + self.args = deepcopy(context.data.get(str(self.task_id), {})) + self.task_type = DataPipelineType(self.args.pop('task_type')) + name = self.args.pop('sparkapp_name') + job_id = uuid4().hex + self.sparkapp_name = f'pipe-{self.task_type.value}-{job_id}-{name}' + + params = self.__class__.TYPE_PARAMS_MAPPER[self.task_type] + self.files_dir = os.path.join(Envs.BASE_DIR, params['files_dir']) + self.files_path = Envs.SPARKAPP_FILES_PATH + self.main_application = params['main_application'] + self.command = self.args.pop('input') + + files = None + if self.files_path is None: + files_obj = io.BytesIO() + with tarfile.open(fileobj=files_obj, mode='w') as f: + f.add(self.files_dir) + files = files_obj.getvalue() + + config = { + 'name': self.sparkapp_name, + 'files': files, + 'files_path': self.files_path, + 'image_url': Envs.SPARKAPP_IMAGE_URL, + 'volumes': gen_sparkapp_volumes(Envs.SPARKAPP_VOLUMES), + 'driver_config': { + 'cores': + 1, + 'memory': + '4g', + 'volume_mounts': + gen_sparkapp_volume_mounts(Envs.SPARKAPP_VOLUME_MOUNTS), + }, + 'executor_config': { + 'cores': + 2, + 'memory': + '4g', + 'instances': + 1, + 'volume_mounts': + gen_sparkapp_volume_mounts(Envs.SPARKAPP_VOLUME_MOUNTS), + }, + 'main_application': f'${{prefix}}/{self.main_application}', + 'command': self.command, + } + config_dict = SparkAppConfig.from_dict(config) + resp = self.spark_service.submit_sparkapp(config=config_dict) + logging.info( + f'created spark app, name: {name}, ' + f'config: {config_dict.__dict__}, resp: {resp.__dict__}') + except Exception as e: # pylint: disable=broad-except + self.error_msg = f'[composer] failed to run this item, err: {e}, \ + trace: {traceback.format_exc()}' + + def result(self, context: Context) -> Tuple[RunnerStatus, dict]: + if self.error_msg: + context.set_data(f'failed_{self.task_id}', + {'error': self.error_msg}) + return RunnerStatus.FAILED, {} + if not self.started: + return RunnerStatus.RUNNING, {} + resp = self.spark_service.get_sparkapp_info(self.sparkapp_name) + logging.info(f'sparkapp resp: {resp.__dict__}') + if not resp.state: + return RunnerStatus.RUNNING, {} + return self.__class__.SPARKAPP_STATE_TO_RUNNER_STATUS.get( + resp.state, RunnerStatus.FAILED), resp.to_dict() + + +def gen_sparkapp_volumes(value: str) -> Optional[List[dict]]: + if value != 'data': + return None + # TODO: better to read from conf + return [{ + 'name': 'data', + 'persistentVolumeClaim': { + 'claimName': 'pvc-fedlearner-default' + } + }] + + +def gen_sparkapp_volume_mounts(value: str) -> Optional[List[dict]]: + if value != 'data': + return None + # TODO: better to read from conf + return [{'name': 'data', 'mountPath': '/data'}] diff --git a/web_console_v2/api/fedlearner_webconsole/dataset/services.py b/web_console_v2/api/fedlearner_webconsole/dataset/services.py new file mode 100644 index 000000000..a21b7cbeb --- /dev/null +++ b/web_console_v2/api/fedlearner_webconsole/dataset/services.py @@ -0,0 +1,124 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +import json +import logging +from typing import List + +from sqlalchemy.orm import Session + +from fedlearner_webconsole.dataset.models import Dataset +from fedlearner_webconsole.dataset.sparkapp.pipeline.util import \ + dataset_meta_path, dataset_features_path, dataset_hist_path +from fedlearner_webconsole.exceptions import NotFoundException +from fedlearner_webconsole.utils.file_manager import FileManager + + +class DatasetService(object): + def __init__(self, session: Session): + self._session = session + self._file_manager = FileManager() + + def get_dataset_preview(self, dataset_id: int = 0) -> dict: + dataset = self._session.query(Dataset).filter( + Dataset.id == dataset_id).first() + if not dataset: + raise NotFoundException(f'Failed to find dataset: {dataset_id}') + dataset_path = dataset.path + # meta is generated from sparkapp/pipeline/analyzer.py + meta_path = dataset_meta_path(dataset_path) + # data format: + # { + # 'dtypes': { + # 'f01': 'bigint' + # }, + # 'samples': [ + # [1], + # [0], + # ], + # 'metrics': { + # 'f01': { + # 'count': '2', + # 'mean': '0.0015716767309123998', + # 'stddev': '0.03961485047808605', + # 'min': '0', + # 'max': '1', + # 'missing_count': '0' + # } + # } + # } + val = {} + try: + val = json.loads(self._file_manager.read(meta_path)) + except Exception as e: # pylint: disable=broad-except + logging.info( + f'failed to read meta file, path: {meta_path}, err: {e}') + return {} + # feature is generated from sparkapp/pipeline/analyzer.py + feature_path = dataset_features_path(dataset_path) + try: + val['metrics'] = json.loads(self._file_manager.read(feature_path)) + except Exception as e: # pylint: disable=broad-except + logging.info( + f'failed to read feature file, path: {feature_path}, err: {e}') + return val + + def feature_metrics(self, name: str, dataset_id: int = 0) -> dict: + dataset = self._session.query(Dataset).filter( + Dataset.id == dataset_id).first() + if not dataset: + raise NotFoundException(f'Failed to find dataset: {dataset_id}') + dataset_path = dataset.path + feature_path = dataset_features_path(dataset_path) + # data format: + # { + # 'name': 'f01', + # 'metrics': { + # 'count': '2', + # 'mean': '0.0015716767309123998', + # 'stddev': '0.03961485047808605', + # 'min': '0', + # 'max': '1', + # 'missing_count': '0' + # }, + # 'hist': { + # 'x': [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, + # 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], + # 'y': [12070, 0, 0, 0, 0, 0, 0, 0, 0, 19] + # } + # } + val = {} + try: + feature_data = json.loads(self._file_manager.read(feature_path)) + val['name'] = name + val['metrics'] = feature_data.get(name, {}) + except Exception as e: # pylint: disable=broad-except + logging.info( + f'failed to read feature file, path: {feature_path}, err: {e}') + # hist is generated from sparkapp/pipeline/analyzer.py + hist_path = dataset_hist_path(dataset_path) + try: + hist_data = json.loads(self._file_manager.read(hist_path)) + val['hist'] = hist_data.get(name, {}) + except Exception as e: # pylint: disable=broad-except + logging.info( + f'failed to read hist file, path: {hist_path}, err: {e}') + return val + + def get_datasets(self, project_id: int = 0) -> List[Dataset]: + q = self._session.query(Dataset).order_by(Dataset.created_at.desc()) + if project_id > 0: + q = q.filter(Dataset.project_id == project_id) + return q.all() diff --git a/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/analyzer.py b/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/analyzer.py new file mode 100644 index 000000000..5759b334e --- /dev/null +++ b/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/analyzer.py @@ -0,0 +1,92 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 + +import os +import sys +import json +import logging + +import fsspec +import pandas + +from pyspark.sql import SparkSession +from pyspark.sql.functions import col, lit, sum +from util import dataset_features_path, dataset_meta_path, dataset_hist_path + + +def analyze(dataset_path: str, wildcard: str): + # for example: + # dataset_path: /data/fl_v2_fish_fooding/dataset/20210527_221741_pipeline/ + # wildcard: rds/** + spark = SparkSession.builder.getOrCreate() + files = os.path.join(dataset_path, wildcard) + logging.info(f'### loading df..., input files path: {files}') + df = spark.read.format('tfrecords').load(files) + # df_stats + df_missing = df.select(*(sum(col(c).isNull().cast('int')).alias(c) + for c in df.columns)).withColumn( + 'summary', lit('missing_count')) + df_stats = df.describe().unionByName(df_missing) + df_stats = df_stats.toPandas().set_index('summary').transpose() + features_path = dataset_features_path(dataset_path) + logging.info(f'### writing features, features path is {features_path}') + content = json.dumps(df_stats.to_dict(orient='index')) + with fsspec.open(features_path, mode='w') as f: + f.write(content) + # meta + meta = {} + # dtypes + logging.info('### loading dtypes...') + dtypes = {} + for d in df.dtypes: + k, v = d # (feature, type) + dtypes[k] = v + meta['dtypes'] = dtypes + # sample count + logging.info('### loading count...') + meta['count'] = df.count() + # sample + logging.info('### loading sample...') + meta['sample'] = df.head(20) + # meta + meta_path = dataset_meta_path(dataset_path) + logging.info(f'### writing meta, path is {meta_path}') + with fsspec.open(meta_path, mode='w') as f: + f.write(json.dumps(meta)) + # feature histogram + logging.info('### loading hist...') + hist = {} + for c in df.columns: + # TODO: histogram is too slow and needs optimization + x, y = df.select(c).rdd.flatMap(lambda x: x).histogram(10) + hist[c] = {'x': x, 'y': y} + hist_path = dataset_hist_path(dataset_path) + logging.info(f'### writing hist, path is {hist_path}') + with fsspec.open(hist_path, mode='w') as f: + f.write(json.dumps(hist)) + + spark.stop() + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + if len(sys.argv) != 3: + logging.error( + f'spark-submit {sys.argv[0]} [dataset_path] [file_wildcard]') + sys.exit(-1) + + dataset_path, wildcard = sys.argv[1], sys.argv[2] + analyze(dataset_path, wildcard) diff --git a/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/converter.py b/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/converter.py new file mode 100644 index 000000000..248210d4d --- /dev/null +++ b/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/converter.py @@ -0,0 +1,56 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 + +import sys +import os +import logging + +from pyspark.sql import SparkSession +from util import dataset_rds_path + + +def convert(dataset_path: str, wildcard: str): + # for example: + # dataset_path: /data/fl_v2_fish_fooding/dataset/20210527_221741_pipeline/ + # wildcard: batch/**/*.csv + files = os.path.join(dataset_path, wildcard) + logging.info(f'### input files path: {files}') + spark = SparkSession.builder.getOrCreate() + if wildcard.endswith('*.csv'): + df = spark.read.format('csv').option('header', 'true').option( + 'inferSchema', 'true').load(files) + elif wildcard.endswith('*.rd') or wildcard.endswith('*.tfrecords'): + df = spark.read.format('tfrecords').load(files) + else: + logging.error(f'### no valid file wildcard, wildcard: {wildcard}') + return + + df.printSchema() + save_path = dataset_rds_path(dataset_path) + logging.info(f'### saving to {save_path}, in tfrecords') + df.write.format('tfrecords').save(save_path, mode='overwrite') + spark.stop() + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + if len(sys.argv) != 3: + logging.error( + f'spark-submit {sys.argv[0]} [dataset_path] [file_wildcard]') + sys.exit(-1) + + dataset_path, wildcard = sys.argv[1], sys.argv[2] + convert(dataset_path, wildcard) diff --git a/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/transformer.py b/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/transformer.py new file mode 100644 index 000000000..4c6620de0 --- /dev/null +++ b/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/transformer.py @@ -0,0 +1,50 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +import os +import json +import sys +import logging + +from pyspark.sql import SparkSession +from util import dataset_transformer_path + + +def transform(dataset_path: str, wildcard: str, conf: str): + # for example: + # dataset_path: /data/fl_v2_fish_fooding/dataset/20210527_221741_pipeline/ + # wildcard: rds/** or data_block/**/*.data + # conf: {"f00001": 0.0, "f00002": 1.0} + spark = SparkSession.builder.getOrCreate() + files = os.path.join(dataset_path, wildcard) + conf_dict = json.loads(conf) + logging.info(f'### input files path: {files}, config: {conf_dict}') + df = spark.read.format('tfrecords').load(files) + filled_df = df.fillna(conf_dict) + save_path = dataset_transformer_path(dataset_path) + logging.info(f'### saving to {save_path}') + filled_df.write.format('tfrecords').save(save_path, mode='overwrite') + spark.stop() + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + if len(sys.argv) != 4: + logging.error( + f'spark-submit {sys.argv[0]} [dataset_path] [wildcard] [config]') + sys.exit(-1) + + dataset_path, wildcard, conf = sys.argv[1], sys.argv[2], sys.argv[3] + transform(dataset_path, wildcard, conf) diff --git a/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/util.py b/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/util.py new file mode 100644 index 000000000..14085e93e --- /dev/null +++ b/web_console_v2/api/fedlearner_webconsole/dataset/sparkapp/pipeline/util.py @@ -0,0 +1,36 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +import os + + +def dataset_rds_path(dataset_path: str) -> str: + return os.path.join(dataset_path, 'rds/') + + +def dataset_features_path(dataset_path: str) -> str: + return os.path.join(dataset_path, '_FEATURES') + + +def dataset_meta_path(dataset_path: str) -> str: + return os.path.join(dataset_path, '_META') + + +def dataset_hist_path(dataset_path: str) -> str: + return os.path.join(dataset_path, '_HIST') + + +def dataset_transformer_path(dataset_path: str) -> str: + return os.path.join(dataset_path, 'fe/') diff --git a/web_console_v2/api/fedlearner_webconsole/db.py b/web_console_v2/api/fedlearner_webconsole/db.py index b7afe0f6e..b40ff033b 100644 --- a/web_console_v2/api/fedlearner_webconsole/db.py +++ b/web_console_v2/api/fedlearner_webconsole/db.py @@ -15,26 +15,29 @@ # coding: utf-8 import os from contextlib import contextmanager -from typing import Generator, Callable +from typing import ContextManager, Callable + +import sqlalchemy as sa -from flask_sqlalchemy import SQLAlchemy from sqlalchemy.engine import Engine, create_engine +from sqlalchemy.ext.declarative.api import DeclarativeMeta, declarative_base from sqlalchemy.orm import sessionmaker from sqlalchemy.orm.session import Session +from flask_sqlalchemy import SQLAlchemy -BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '../')) +from envs import Envs +BASE_DIR = Envs.BASE_DIR # Explicitly set autocommit and autoflush # Disables autocommit to make developers to commit manually # Enables autoflush to make changes visible in the same session -# Enables expire_on_commit to make it possible that one session commit twice +# Disable expire_on_commit to make it possible that object can detach SESSION_OPTIONS = { 'autocommit': False, 'autoflush': True, - 'expire_on_commit': True + 'expire_on_commit': False } ENGINE_OPTIONS = {} -db = SQLAlchemy(session_options=SESSION_OPTIONS, engine_options=ENGINE_OPTIONS) def default_table_args(comment: str) -> dict: @@ -102,7 +105,8 @@ def get_database_uri() -> str: if 'SQLALCHEMY_DATABASE_URI' in os.environ: uri = os.getenv('SQLALCHEMY_DATABASE_URI') else: - uri = 'sqlite:///{}'.format(os.path.join(BASE_DIR, 'app.db')) + uri = 'sqlite:///{}?check_same_thread=False'.format( + os.path.join(BASE_DIR, 'app.db')) return _turn_db_timezone_to_utc(uri) @@ -119,7 +123,7 @@ def get_engine(database_uri: str) -> Engine: @contextmanager -def get_session(db_engine: Engine) -> Generator[Session, None, None]: +def get_session(db_engine: Engine) -> ContextManager[Session]: """Get session from database engine. Example: @@ -128,25 +132,27 @@ def get_session(db_engine: Engine) -> Generator[Session, None, None]: session.query(MODEL).filter_by(field=value).first() """ try: - session = sessionmaker(bind=db_engine, **SESSION_OPTIONS)() + session: Session = sessionmaker(bind=db_engine, **SESSION_OPTIONS)() except Exception: raise Exception('unknown db engine') - else: + + try: yield session + except Exception: + session.rollback() + raise finally: session.close() -def make_session_context() -> Callable[[], Generator[Session, None, None]]: +def make_session_context() -> Callable[[], ContextManager[Session]]: """A functional closure that will store engine Call it n times if you want to n connection pools Returns: - Callable[[], Generator[Session, None, None]]: - a function that yield a context + Callable[[], Callable[[], ContextManager[Session]]] + a function that return a contextmanager - Yields: - Generator[Session, None, None]: a session context Examples: # First initialize a connection pool, @@ -159,12 +165,47 @@ def make_session_context() -> Callable[[], Generator[Session, None, None]]: """ engine = None - @contextmanager def wrapper_get_session(): nonlocal engine if engine is None: engine = get_engine(get_database_uri()) - with get_session(engine) as session: - yield session + return get_session(engine) return wrapper_get_session + + +class DBHandler(object): + def __init__(self) -> None: + super().__init__() + + self.engine: Engine = get_engine(get_database_uri()) + self.Model: DeclarativeMeta = declarative_base(bind=self.engine) + for module in sa, sa.orm: + for key in module.__all__: + if not hasattr(self, key): + setattr(self, key, getattr(module, key)) + + def session_scope(self) -> ContextManager[Session]: + return get_session(self.engine) + + @property + def metadata(self) -> DeclarativeMeta: + return self.Model.metadata + + def rebind(self, database_uri: str): + self.engine = get_engine(database_uri) + self.Model = declarative_base(bind=self.engine, metadata=self.metadata) + + def create_all(self): + return self.metadata.create_all() + + def drop_all(self): + return self.metadata.drop_all() + + +# now db_handler and db are alive at the same time +# db will be replaced by db_handler in the near future +db_handler = DBHandler() +db = SQLAlchemy(session_options=SESSION_OPTIONS, + engine_options=ENGINE_OPTIONS, + metadata=db_handler.metadata) diff --git a/web_console_v2/api/fedlearner_webconsole/debug/apis.py b/web_console_v2/api/fedlearner_webconsole/debug/apis.py index 84d9f085c..4c74e9a80 100644 --- a/web_console_v2/api/fedlearner_webconsole/debug/apis.py +++ b/web_console_v2/api/fedlearner_webconsole/debug/apis.py @@ -13,10 +13,14 @@ # limitations under the License. # coding: utf-8 +import json + from flask_restful import Resource, Api, request from fedlearner_webconsole.composer.composer import composer from fedlearner_webconsole.composer.runner import MemoryItem +from fedlearner_webconsole.dataset.data_pipeline import DataPipelineItem, \ + DataPipelineType class ComposerApi(Resource): @@ -42,5 +46,47 @@ def get(self, name): return {'data': {'name': name}} +class DataPipelineApi(Resource): + def get(self, name: str): + # '/data/fl_v2_fish_fooding/dataset/20210527_221741_pipeline' + input_dir = request.args.get('input_dir', None) + if not input_dir: + return {'msg': 'no input dir'} + if 'pipe' in name: + composer.collect( + name, + [DataPipelineItem(1), DataPipelineItem(2)], + { # meta data + 1: { # convertor + 'sparkapp_name': '1', + 'task_type': DataPipelineType.CONVERTER.value, + 'input': [input_dir, 'batch/**/*.csv'], + }, + 2: { # analyzer + 'sparkapp_name': '2', + 'task_type': DataPipelineType.ANALYZER.value, + 'input': [input_dir, 'rds/**'], + }, + }, + ) + elif 'fe' in name: + composer.collect( + name, + [DataPipelineItem(1)], + { # meta data + 1: { # transformer + 'sparkapp_name': '1', + 'task_type': DataPipelineType.TRANSFORMER.value, + 'input': [input_dir, 'rds/**', json.dumps({ + 'f00000': 1.0, + 'f00010': 0.0, + })], + }, + }, + ) + return {'data': {'name': name}} + + def initialize_debug_apis(api: Api): api.add_resource(ComposerApi, '/debug/composer/') + api.add_resource(DataPipelineApi, '/debug/pipeline/') diff --git a/web_console_v2/api/fedlearner_webconsole/exceptions.py b/web_console_v2/api/fedlearner_webconsole/exceptions.py index a8834fe82..3de880de0 100644 --- a/web_console_v2/api/fedlearner_webconsole/exceptions.py +++ b/web_console_v2/api/fedlearner_webconsole/exceptions.py @@ -26,8 +26,8 @@ def __init__(self, status_code, error_code, message, details=None): self.details = details def __repr__(self): - return '%s(%d %s: %s)'%( - type(self).__name__, self.error_code, self.message, self.details) + return f'{type(self).__name__}({self.error_code} ' \ + f'{self.message}: {self.details})' def to_dict(self): dic = { @@ -38,15 +38,18 @@ def to_dict(self): dic['details'] = self.details return dic + class InvalidArgumentException(WebConsoleApiException): def __init__(self, details): WebConsoleApiException.__init__(self, HTTPStatus.BAD_REQUEST, 400, 'Invalid argument or payload.', details) + class NotFoundException(WebConsoleApiException): - def __init__(self): + def __init__(self, message=None): WebConsoleApiException.__init__( - self, HTTPStatus.NOT_FOUND, 404, 'Resource not existing') + self, HTTPStatus.NOT_FOUND, 404, + message if message else 'Resource not found.') class UnauthorizedException(WebConsoleApiException): diff --git a/web_console_v2/api/fedlearner_webconsole/initial_db.py b/web_console_v2/api/fedlearner_webconsole/initial_db.py index 0dc01a62b..da9997ba0 100644 --- a/web_console_v2/api/fedlearner_webconsole/initial_db.py +++ b/web_console_v2/api/fedlearner_webconsole/initial_db.py @@ -13,7 +13,7 @@ # limitations under the License. from fedlearner_webconsole.auth.models import User, Role, State -from fedlearner_webconsole.db import db +from fedlearner_webconsole.db import db_handler as db INITIAL_USER_INFO = [{ 'username': 'ada', @@ -33,20 +33,22 @@ def initial_db(): - # initial user info first - for u_info in INITIAL_USER_INFO: - username = u_info['username'] - password = u_info['password'] - name = u_info['name'] - email = u_info['email'] - role = u_info['role'] - state = u_info['state'] - if User.query.filter_by(username=username).first() is None: - user = User(username=username, - name=name, - email=email, - role=role, - state=state) - user.set_password(password=password) - db.session.add(user) - db.session.commit() + with db.session_scope() as session: + # initial user info first + for u_info in INITIAL_USER_INFO: + username = u_info['username'] + password = u_info['password'] + name = u_info['name'] + email = u_info['email'] + role = u_info['role'] + state = u_info['state'] + if session.query(User).filter_by( + username=username).first() is None: + user = User(username=username, + name=name, + email=email, + role=role, + state=state) + user.set_password(password=password) + session.add(user) + session.commit() diff --git a/web_console_v2/api/fedlearner_webconsole/job/apis.py b/web_console_v2/api/fedlearner_webconsole/job/apis.py index f84aafbaa..d9a073dbe 100644 --- a/web_console_v2/api/fedlearner_webconsole/job/apis.py +++ b/web_console_v2/api/fedlearner_webconsole/job/apis.py @@ -36,7 +36,7 @@ def _get_job(job_id): result = Job.query.filter_by(id=job_id).first() if result is None: - raise NotFoundException() + raise NotFoundException(f'Failed to find job_id: {job_id}') return result @@ -115,7 +115,8 @@ class PeerJobMetricsApi(Resource): def get(self, workflow_uuid, participant_id, job_name): workflow = Workflow.query.filter_by(uuid=workflow_uuid).first() if workflow is None: - raise NotFoundException() + raise NotFoundException( + f'Failed to find workflow: {workflow_uuid}') project_config = workflow.project.get_config() party = project_config.participants[participant_id] client = RpcClient(project_config, party) @@ -147,7 +148,7 @@ def get(self, job_id): job = _get_job(job_id) if start_time is None: start_time = job.workflow.start_at - return {'data': es.query_events('filebeat-*', job.name, + return {'data': es.query_events(Envs.ES_INDEX, job.name, 'fedlearner-operator', start_time, int(time.time() * 1000 @@ -171,7 +172,8 @@ def get(self, workflow_uuid, participant_id, job_name): max_lines = data['max_lines'] workflow = Workflow.query.filter_by(uuid=workflow_uuid).first() if workflow is None: - raise NotFoundException() + raise NotFoundException( + f'Failed to find workflow: {workflow_uuid}') if start_time is None: start_time = workflow.start_at project_config = workflow.project.get_config() @@ -306,7 +308,8 @@ def get(self, workflow_uuid, participant_id, job_name): args = parser.parse_args() workflow = Workflow.query.filter_by(uuid=workflow_uuid).first() if workflow is None: - raise NotFoundException() + raise NotFoundException( + f'Failed to find workflow: {workflow_uuid}') project_config = workflow.project.get_config() party = project_config.participants[participant_id] client = RpcClient(project_config, party) diff --git a/web_console_v2/api/fedlearner_webconsole/job/models.py b/web_console_v2/api/fedlearner_webconsole/job/models.py index 165c8b816..c9b00aff6 100644 --- a/web_console_v2/api/fedlearner_webconsole/job/models.py +++ b/web_console_v2/api/fedlearner_webconsole/job/models.py @@ -14,8 +14,10 @@ # coding: utf-8 import datetime +import logging import enum import json + from sqlalchemy.sql import func from sqlalchemy.sql.schema import Index from fedlearner_webconsole.utils.mixins import to_dict_mixin @@ -26,10 +28,20 @@ class JobState(enum.Enum): - INVALID = 0 - STOPPED = 1 - WAITING = 2 - STARTED = 3 + # VALID TRANSITION: + # 1. NEW : init by workflow + # 2. NEW/STOPPED/COMPLTED/FAILED -> WAITING: triggered by user, run workflow + # 3. WAITING -> STARTED: triggered by scheduler + # 4. WAITING -> NEW: triggered by user, stop workflow + # 4. STARTED -> STOPPED: triggered by user, stop workflow + # 5. STARTED -> COMPLETED/FAILED: triggered by k8s_watcher + INVALID = 0 # INVALID STATE + STOPPED = 1 # STOPPED BY USER + WAITING = 2 # SCHEDULED, WAITING FOR RUNNING + STARTED = 3 # RUNNING + NEW = 4 # BEFORE SCHEDULE + COMPLETED = 5 # SUCCEEDED JOB + FAILED = 6 # FAILED JOB # must be consistent with JobType in proto @@ -161,23 +173,14 @@ def get_pods_for_frontend(self, include_private_info=True): return [pod.to_dict(include_private_info) for pod in result.values()] def get_state_for_frontend(self): - if self.state == JobState.STARTED: - if self.is_complete(): - return 'COMPLETED' - if self.is_failed(): - return 'FAILED' - return 'RUNNING' - if self.state == JobState.STOPPED: - if self.get_flapp_details()['flapp'] is None: - return 'NEW' return self.state.name - def is_failed(self): + def is_flapp_failed(self): # TODO: make the getter more efficient flapp = FlApp.from_json(self.get_flapp_details()['flapp']) return flapp.state in [FlAppState.FAILED, FlAppState.SHUTDOWN] - def is_complete(self): + def is_flapp_complete(self): # TODO: make the getter more efficient flapp = FlApp.from_json(self.get_flapp_details()['flapp']) return flapp.state == FlAppState.COMPLETED @@ -188,20 +191,48 @@ def get_complete_at(self): return flapp.completed_at def stop(self): + if self.state not in [JobState.WAITING, JobState.STARTED, + JobState.COMPLETED, JobState.FAILED]: + logging.warning('illegal job state, name: %s, state: %s', + self.name, self.state) + return if self.state == JobState.STARTED: self._set_snapshot_flapp() k8s_client.delete_flapp(self.name) - self.state = JobState.STOPPED + # state change: + # WAITING -> NEW + # STARTED -> STOPPED + # COMPLETED/FAILED unchanged + if self.state == JobState.STARTED: + self.state = JobState.STOPPED + if self.state == JobState.WAITING: + self.state = JobState.NEW def schedule(self): - assert self.state == JobState.STOPPED + # COMPLETED/FAILED Job State can be scheduled since stop action + # will not change the state of completed or failed job + assert self.state in [JobState.NEW, JobState.STOPPED, + JobState.COMPLETED, JobState.FAILED] self.pods_snapshot = None self.flapp_snapshot = None self.state = JobState.WAITING def start(self): + assert self.state == JobState.WAITING self.state = JobState.STARTED + def complete(self): + assert self.state == JobState.STARTED, 'Job State is not STARTED' + self._set_snapshot_flapp() + k8s_client.delete_flapp(self.name) + self.state = JobState.COMPLETED + + def fail(self): + assert self.state == JobState.STARTED, 'Job State is not STARTED' + self._set_snapshot_flapp() + k8s_client.delete_flapp(self.name) + self.state = JobState.FAILED + class JobDependency(db.Model): __tablename__ = 'job_dependency_v2' diff --git a/web_console_v2/api/fedlearner_webconsole/job/service.py b/web_console_v2/api/fedlearner_webconsole/job/service.py index 991aa4b42..fc015dfb6 100644 --- a/web_console_v2/api/fedlearner_webconsole/job/service.py +++ b/web_console_v2/api/fedlearner_webconsole/job/service.py @@ -14,9 +14,10 @@ # coding: utf-8 +import logging from sqlalchemy.orm.session import Session from fedlearner_webconsole.rpc.client import RpcClient -from fedlearner_webconsole.job.models import Job, JobDependency +from fedlearner_webconsole.job.models import Job, JobDependency, JobState from fedlearner_webconsole.proto import common_pb2 from fedlearner_webconsole.utils.metrics import emit_counter @@ -33,7 +34,7 @@ def is_ready(self, job: Job) -> bool: src_job = self._session.query(Job).get(dep.src_job_id) assert src_job is not None, 'Job {} not found'.format( dep.src_job_id) - if not src_job.is_complete(): + if not src_job.state == JobState.COMPLETED: return False return True @@ -49,3 +50,20 @@ def is_peer_ready(job: Job) -> bool: if not resp.is_ready: return False return True + + def update_running_state(self, job_name): + job = self._session.query(Job).filter_by(name=job_name).first() + if job is None: + emit_counter('[JobService]job_not_found', 1) + return + if not job.state == JobState.STARTED: + emit_counter('[JobService]wrong_job_state', 1) + return + if job.is_flapp_complete(): + job.complete() + logging.debug('[JobService]change job %s state to %s', + job.name, JobState(job.state)) + elif job.is_flapp_failed(): + job.fail() + logging.debug('[JobService]change job %s state to %s', + job.name, JobState(job.state)) diff --git a/web_console_v2/api/fedlearner_webconsole/mmgr/apis.py b/web_console_v2/api/fedlearner_webconsole/mmgr/apis.py index ccac400a2..cbae04a07 100644 --- a/web_console_v2/api/fedlearner_webconsole/mmgr/apis.py +++ b/web_console_v2/api/fedlearner_webconsole/mmgr/apis.py @@ -17,11 +17,10 @@ from http import HTTPStatus from flask import request from flask_restful import Resource -from fedlearner_webconsole.db import db +from fedlearner_webconsole.db import db_handler from fedlearner_webconsole.exceptions import NotFoundException from fedlearner_webconsole.mmgr.models import Model, ModelType, ModelGroup from fedlearner_webconsole.mmgr.service import ModelService -from fedlearner_webconsole.db import make_session_context from fedlearner_webconsole.utils.decorators import jwt_required @@ -29,26 +28,32 @@ class ModelApi(Resource): @jwt_required() def get(self, model_id): detail_level = request.args.get('detail_level', '') - model_json = ModelService(db.session).query(model_id, detail_level) + with db_handler.session_scope() as session: + model_json = ModelService(session).query(model_id, detail_level) if not model_json: - raise NotFoundException() + raise NotFoundException( + f'Failed to find model: {model_id}') return {'data': model_json}, HTTPStatus.OK @jwt_required() def put(self, model_id): - model = db.session.query(Model).filter_by(id=model_id).one_or_none() - if not model: - raise NotFoundException() - model.extra = request.args.get('extra', model.extra) - db.session.commit() - return {'data': model.to_dict()}, HTTPStatus.OK + with db_handler.session_scope() as session: + model = session.query(Model).filter_by(id=model_id).one_or_none() + if not model: + raise NotFoundException( + f'Failed to find model: {model_id}') + model.extra = request.args.get('extra', model.extra) + session.commit() + return {'data': model.to_dict()}, HTTPStatus.OK @jwt_required() def delete(self, model_id): - model = ModelService(db.session).drop(model_id) - if not model: - raise NotFoundException() - return {'data': model.to_dict()}, HTTPStatus.OK + with db_handler.session_scope() as session: + model = ModelService(session).drop(model_id) + if not model: + raise NotFoundException( + f'Failed to find model: {model_id}') + return {'data': model.to_dict()}, HTTPStatus.OK class ModelListApi(Resource): @@ -56,13 +61,14 @@ class ModelListApi(Resource): def get(self): detail_level = request.args.get('detail_level', '') # TODO serialized query may incur performance penalty - model_list = [ - ModelService(db.session).query(m.id, detail_level) - for m in Model.query.filter( - Model.type.in_([ - ModelType.NN_MODEL.value, ModelType.TREE_MODEL.value - ])).all() - ] + with db_handler.session_scope() as session: + model_list = [ + ModelService(session).query(m.id, detail_level) + for m in Model.query.filter( + Model.type.in_([ + ModelType.NN_MODEL.value, ModelType.TREE_MODEL.value + ])).all() + ] return {'data': model_list}, HTTPStatus.OK @@ -78,8 +84,9 @@ def post(self): group.name = request.args.get('name', group.name) group.extra = request.args.get('extra', group.extra) - db.session.add(group) - db.session.commit() + with db_handler.session_scope() as session: + session.add(group) + session.commit() return {'data': group.to_dict()}, HTTPStatus.OK @@ -89,12 +96,14 @@ class GroupApi(Resource): def patch(self, group_id): group = ModelGroup.query.filter_by(id=group_id).one_or_none() if not group: - raise NotFoundException() + raise NotFoundException( + f'Failed to find group: {group_id}') group.name = request.args.get('name', group.name) group.extra = request.args.get('extra', group.extra) - db.session.add(group) - db.session.commit() + with db_handler.session_scope() as session: + session.add(group) + session.commit() return {'data': group.to_dict()}, HTTPStatus.OK diff --git a/web_console_v2/api/fedlearner_webconsole/mmgr/service.py b/web_console_v2/api/fedlearner_webconsole/mmgr/service.py index 705f31d7a..2f811c169 100644 --- a/web_console_v2/api/fedlearner_webconsole/mmgr/service.py +++ b/web_console_v2/api/fedlearner_webconsole/mmgr/service.py @@ -37,6 +37,14 @@ def __init__(self, session): JobType.TREE_MODEL_EVALUATION: ModelType.TREE_EVALUATION.value } + job_state_map = { + JobState.STARTED: ModelState.RUNNING.value, + JobState.COMPLETED: ModelState.SUCCEEDED.value, + JobState.FAILED: ModelState.FAILED.value, + JobState.STOPPED: ModelState.PAUSED.value, + JobState.WAITING: ModelState.WAITING.value + } + @staticmethod def is_model_related_job(job): job_type = job.job_type @@ -69,8 +77,8 @@ def plot_metrics(self, model, job=None): except Exception as e: return repr(e) - def is_model_quiescence(self, model): - return model.state in [ + def is_model_quiescence(self, state): + return state in [ ModelState.SUCCEEDED.value, ModelState.FAILED.value, ModelState.PAUSED.value ] @@ -79,17 +87,8 @@ def on_job_update(self, job: Job): logging.info('[ModelService][on_job_update] job name: %s', job.name) model = self._session.query(Model).filter_by(job_name=job.name).one() # see also `fedlearner_webconsole.job.models.Job.stop` - if job.state == JobState.STARTED: - if job.is_complete(): - state = ModelState.SUCCEEDED.value - elif job.is_failed(): - state = ModelState.FAILED.value - else: - state = ModelState.RUNNING.value - elif job.state == JobState.STOPPED: - state = ModelState.PAUSED.value - elif job.state == JobState.WAITING: - state = ModelState.WAITING.value + if job.state in self.job_state_map: + state = self.job_state_map[job.state] else: return logging.warning( '[ModelService][on_job_update] job state is %s', job.state) @@ -101,8 +100,8 @@ def on_job_update(self, job: Job): logging.info( '[ModelService][on_job_update] updating model(%d).state from %s to %s', model.id, model.state, state) - if self.is_model_quiescence(model): - model.metrics = self.plot_metrics(model, job) + if self.is_model_quiescence(state): + model.metrics = json.dumps(self.plot_metrics(model, job)) model.state = state self._session.add(model) @@ -137,8 +136,9 @@ def query(self, model_id, detail_level=''): model_json = model.to_dict() model_json['detail_level'] = detail_level if 'metrics' in detail_level: - if not self.is_model_quiescence(model) or not model.metrics: - model_json['metrics'] = self.plot_metrics(model) + if self.is_model_quiescence(model) and model.metrics: + model_json['metrics'] = json.loads(model.metrics) + else: model_json['metrics'] = self.plot_metrics(model) return model_json def drop(self, model_id): diff --git a/web_console_v2/api/fedlearner_webconsole/project/apis.py b/web_console_v2/api/fedlearner_webconsole/project/apis.py index af0a0e86e..c13a6a3ea 100644 --- a/web_console_v2/api/fedlearner_webconsole/project/apis.py +++ b/web_console_v2/api/fedlearner_webconsole/project/apis.py @@ -194,14 +194,16 @@ class ProjectApi(Resource): def get(self, project_id): project = Project.query.filter_by(id=project_id).first() if project is None: - raise NotFoundException() + raise NotFoundException( + f'Failed to find project: {project_id}') return {'data': project.to_dict()} @jwt_required() def patch(self, project_id): project = Project.query.filter_by(id=project_id).first() if project is None: - raise NotFoundException() + raise NotFoundException( + f'Failed to find project: {project_id}') config = project.get_config() if request.json.get('token') is not None: new_token = request.json.get('token') @@ -223,6 +225,9 @@ def patch(self, project_id): if variable.name == 'EGRESS_HOST': egress_host = variable.value + if request.json.get('participant_name'): + config.participants[0].name = request.json.get('participant_name') + if request.json.get('comment'): project.comment = request.json.get('comment') @@ -248,7 +253,8 @@ class CheckConnectionApi(Resource): def post(self, project_id): project = Project.query.filter_by(id=project_id).first() if project is None: - raise NotFoundException() + raise NotFoundException( + f'Failed to find project: {project_id}') success = True details = [] # TODO: Concurrently check diff --git a/web_console_v2/api/fedlearner_webconsole/rpc/client.py b/web_console_v2/api/fedlearner_webconsole/rpc/client.py index c55dca6c2..726568ad6 100644 --- a/web_console_v2/api/fedlearner_webconsole/rpc/client.py +++ b/web_console_v2/api/fedlearner_webconsole/rpc/client.py @@ -101,7 +101,8 @@ def check_connection(self): @catch_and_fallback(resp_class=service_pb2.UpdateWorkflowStateResponse) @retry_fn(retry_times=3, needed_exceptions=[grpc.RpcError]) def update_workflow_state(self, name, state, target_state, - transaction_state, uuid, forked_from_uuid): + transaction_state, uuid, forked_from_uuid, + extra=''): msg = service_pb2.UpdateWorkflowStateRequest( auth_info=self._auth_info, workflow_name=name, @@ -109,7 +110,9 @@ def update_workflow_state(self, name, state, target_state, target_state=target_state.value, transaction_state=transaction_state.value, uuid=uuid, - forked_from_uuid=forked_from_uuid) + forked_from_uuid=forked_from_uuid, + extra=extra + ) response = self._client.UpdateWorkflowState( request=msg, metadata=self._get_metadata(), timeout=Envs.GRPC_CLIENT_TIMEOUT) diff --git a/web_console_v2/api/fedlearner_webconsole/rpc/server.py b/web_console_v2/api/fedlearner_webconsole/rpc/server.py index e00335db8..19b9ac285 100644 --- a/web_console_v2/api/fedlearner_webconsole/rpc/server.py +++ b/web_console_v2/api/fedlearner_webconsole/rpc/server.py @@ -23,6 +23,7 @@ import traceback from concurrent import futures import grpc +from grpc_reflection.v1alpha import reflection from fedlearner_webconsole.proto import ( service_pb2, service_pb2_grpc, common_pb2, workflow_definition_pb2 @@ -76,6 +77,11 @@ def CheckConnection(self, request, context): self._server.check_connection, request, context, service_pb2.CheckConnectionResponse) + def Ping(self, request, context): + return self._try_handle_request( + self._server.ping, request, context, + service_pb2.PingResponse) + def UpdateWorkflowState(self, request, context): return self._try_handle_request( self._server.update_workflow_state, request, context, @@ -129,6 +135,10 @@ def start(self, app): futures.ThreadPoolExecutor(max_workers=20)) service_pb2_grpc.add_WebConsoleV2ServiceServicer_to_server( RPCServerServicer(self), self._server) + # reflection support server find the proto file path automatically + # when using grpcurl + reflection.enable_server_reflection( + service_pb2.DESCRIPTOR.services_by_name, self._server) self._server.add_insecure_port('[::]:%d' % listen_port) self._server.start() self._started = True @@ -177,6 +187,12 @@ def check_connection(self, request, context): status=common_pb2.Status( code=common_pb2.STATUS_SUCCESS)) + def ping(self, request, context): + return service_pb2.PingResponse( + status=common_pb2.Status( + code=common_pb2.STATUS_SUCCESS), + msg='Pong!') + def update_workflow_state(self, request, context): with self._app.app_context(): project, party = self.check_auth_info(request.auth_info, context) @@ -203,7 +219,8 @@ def update_workflow_state(self, request, context): state=state, target_state=target_state, transaction_state=transaction_state, uuid=uuid, - forked_from=forked_from + forked_from=forked_from, + extra=request.extra ) db.session.add(workflow) db.session.commit() diff --git a/web_console_v2/api/fedlearner_webconsole/scheduler/transaction.py b/web_console_v2/api/fedlearner_webconsole/scheduler/transaction.py index 909c50063..aa605e157 100644 --- a/web_console_v2/api/fedlearner_webconsole/scheduler/transaction.py +++ b/web_console_v2/api/fedlearner_webconsole/scheduler/transaction.py @@ -38,6 +38,12 @@ def project(self): return self._project def process(self): + # process local workflow + if self._workflow.is_local(): + self._workflow.update_local_state() + self._reload() + return self._workflow + # reload workflow and resolve -ing states self._workflow.update_state( self._workflow.state, self._workflow.target_state, @@ -117,7 +123,7 @@ def _broadcast_state( resp = client.update_workflow_state( self._workflow.name, state, target_state, transaction_state, self._workflow.uuid, - forked_from_uuid) + forked_from_uuid, self._workflow.extra) if resp.status.code == common_pb2.STATUS_SUCCESS: if resp.state == WorkflowState.INVALID: self._workflow.invalidate() diff --git a/web_console_v2/api/fedlearner_webconsole/setting/model.py b/web_console_v2/api/fedlearner_webconsole/setting/models.py similarity index 76% rename from web_console_v2/api/fedlearner_webconsole/setting/model.py rename to web_console_v2/api/fedlearner_webconsole/setting/models.py index d33a6bc48..7d46db01f 100644 --- a/web_console_v2/api/fedlearner_webconsole/setting/model.py +++ b/web_console_v2/api/fedlearner_webconsole/setting/models.py @@ -16,16 +16,13 @@ # pylint: disable=raise-missing-from from sqlalchemy import UniqueConstraint -from fedlearner_webconsole.db import db +from fedlearner_webconsole.db import db, default_table_args class Setting(db.Model): __tablename__ = 'settings_v2' - __table_args__ = (UniqueConstraint('key', name='uniq_key'), { - 'comment': 'workflow_v2', - 'mysql_engine': 'innodb', - 'mysql_charset': 'utf8mb4', - }) + __table_args__ = (UniqueConstraint('key', name='uniq_key'), + default_table_args('this is webconsole settings table')) id = db.Column(db.Integer, primary_key=True, comment='id') key = db.Column(db.String(255), nullable=False, comment='key') value = db.Column(db.Text, comment='value') diff --git a/web_console_v2/api/fedlearner_webconsole/sparkapp/apis.py b/web_console_v2/api/fedlearner_webconsole/sparkapp/apis.py index eea215f82..70dfc6339 100644 --- a/web_console_v2/api/fedlearner_webconsole/sparkapp/apis.py +++ b/web_console_v2/api/fedlearner_webconsole/sparkapp/apis.py @@ -34,7 +34,8 @@ def post(self): try: config = SparkAppConfig.from_dict(data) - config.files = base64.b64decode(config.files) + if config.files: + config.files = base64.b64decode(config.files) except ValueError as err: raise InvalidArgumentException(details=err) diff --git a/web_console_v2/api/fedlearner_webconsole/sparkapp/schema.py b/web_console_v2/api/fedlearner_webconsole/sparkapp/schema.py index bf25ae7b2..31d91f44a 100644 --- a/web_console_v2/api/fedlearner_webconsole/sparkapp/schema.py +++ b/web_console_v2/api/fedlearner_webconsole/sparkapp/schema.py @@ -18,7 +18,7 @@ from fedlearner_webconsole.utils.mixins import from_dict_mixin, to_dict_mixin SPARK_POD_CONFIG_SERILIZE_FIELDS = [ - 'cores', 'memory', 'instances', 'core_limit', 'envs' + 'cores', 'memory', 'instances', 'core_limit', 'envs', 'volume_mounts' ] @@ -31,6 +31,7 @@ def __init__(self): self.memory = None self.instances = None self.core_limit = None + self.volume_mounts = [] self.envs = {} def build_config(self) -> dict: @@ -48,18 +49,20 @@ def build_config(self) -> dict: config['instances'] = self.instances if self.core_limit: config['coreLimit'] = self.core_limit - if len(self.envs) > 0: + if self.envs and len(self.envs) > 0: config['env'] = [{ 'name': k, 'value': v } for k, v in self.envs.items()] + if self.volume_mounts and len(self.volume_mounts) > 0: + config['volumeMounts'] = self.volume_mounts return config SPARK_APP_CONFIG_SERILIZE_FIELDS = [ - 'name', 'files', 'image_url', 'driver_config', 'executor_config', - 'command', 'main_application' + 'name', 'files', 'files_path', 'volumes', 'image_url', 'driver_config', + 'executor_config', 'command', 'main_application', 'py_files' ] SPARK_APP_CONFIG_REQUIRED_FIELDS = ['name', 'image_url'] @@ -71,10 +74,16 @@ def build_config(self) -> dict: class SparkAppConfig(object): def __init__(self): self.name = None + # local files should be compressed to submit spark self.files = None + # if nas/hdfs has those files, such as analyzer, only need files path \ + # to submit spark + self.files_path = None self.image_url = None + self.volumes = [] self.driver_config = SparkPodConfig() self.executor_config = SparkPodConfig() + self.py_files = [] self.command = [] self.main_application = None @@ -107,6 +116,8 @@ def build_config(self, sparkapp_path: str) -> dict: self.image_url, 'imagePullPolicy': 'Always', + 'volumes': + self.volumes, 'mainApplicationFile': self._replace_placeholder_with_real_path( self.main_application, sparkapp_path), @@ -114,6 +125,12 @@ def build_config(self, sparkapp_path: str) -> dict: self._replace_placeholder_with_real_path(c, sparkapp_path) for c in self.command ], + 'deps': { + 'pyFiles': [ + self._replace_placeholder_with_real_path( + f, sparkapp_path) for f in self.py_files + ] + }, 'sparkConf': { 'spark.shuffle.service.enabled': 'false', }, @@ -144,7 +161,7 @@ def build_config(self, sparkapp_path: str) -> dict: SPARK_APP_INFO_SERILIZE_FIELDS = [ 'name', 'namespace', 'command', 'driver', 'executor', 'image_url', - 'main_application', 'spark_version', 'type' + 'main_application', 'spark_version', 'type', 'state' ] @@ -159,6 +176,14 @@ def from_k8s_resp(cls, resp): elif 'name' in resp['details']: sparkapp_info.name = resp['details']['name'] sparkapp_info.namespace = resp['metadata'].get('namespace', None) + sparkapp_info.state = None + if 'status' in resp: + if isinstance(resp['status'], str): + sparkapp_info.state = None + elif isinstance(resp['status'], dict): + sparkapp_info.state = resp.get('status', + {}).get('applicationState', + {}).get('state', None) sparkapp_info.command = resp.get('spec', {}).get('arguments', None) sparkapp_info.executor = SparkPodConfig.from_dict( resp.get('spec', {}).get('executor', {})) @@ -175,6 +200,7 @@ def from_k8s_resp(cls, resp): def __init__(self): self.name = None + self.state = None self.namespace = None self.command = None self.driver = SparkPodConfig() diff --git a/web_console_v2/api/fedlearner_webconsole/sparkapp/service.py b/web_console_v2/api/fedlearner_webconsole/sparkapp/service.py index 50554be46..21e612777 100644 --- a/web_console_v2/api/fedlearner_webconsole/sparkapp/service.py +++ b/web_console_v2/api/fedlearner_webconsole/sparkapp/service.py @@ -18,7 +18,6 @@ import tempfile from typing import Tuple -from pathlib import Path from envs import Envs from fedlearner_webconsole.utils.file_manager import FileManager @@ -87,12 +86,18 @@ def _copy_files_to_target_filesystem(self, source_filesystem_path: str, os.makedirs(temp_path) TarCli.untar_file(source_filesystem_path, temp_path) - for root, _, res in os.walk(temp_path): - for file in res: - file_path = os.path.join(root, file) - remote_file_path = os.path.join(target_filesystem_path, file) - if Path(file_path).is_file(): - self._file_client.copy(file_path, remote_file_path) + for root, dirs, files in os.walk(temp_path): + relative_path = os.path.relpath(root, temp_path) + for f in files: + file_path = os.path.join(root, f) + remote_file_path = os.path.join(target_filesystem_path, + relative_path, f) + self._file_client.copy(file_path, remote_file_path) + for d in dirs: + remote_dir_path = os.path.join(target_filesystem_path, + relative_path, d) + self._file_client.mkdir(remote_dir_path) + return True def submit_sparkapp(self, config: SparkAppConfig) -> SparkAppInfo: @@ -107,19 +112,22 @@ def submit_sparkapp(self, config: SparkAppConfig) -> SparkAppInfo: Returns: SparkAppInfo: resp of sparkapp """ - _, sparkapp_path = self._get_sparkapp_upload_path(config.name) - self._clear_and_make_an_empty_dir(sparkapp_path) - - with tempfile.TemporaryDirectory() as temp_dir: - tar_path = os.path.join(temp_dir, 'files.tar') - with open(tar_path, 'wb') as fwrite: - fwrite.write(config.files) - self._copy_files_to_target_filesystem( - source_filesystem_path=tar_path, - target_filesystem_path=sparkapp_path) - - resp = k8s_client.create_sparkapplication( - config.build_config(sparkapp_path)) + sparkapp_path = config.files_path + if config.files_path is None: + _, sparkapp_path = self._get_sparkapp_upload_path(config.name) + self._clear_and_make_an_empty_dir(sparkapp_path) + + with tempfile.TemporaryDirectory() as temp_dir: + tar_path = os.path.join(temp_dir, 'files.tar') + with open(tar_path, 'wb') as fwrite: + fwrite.write(config.files) + self._copy_files_to_target_filesystem( + source_filesystem_path=tar_path, + target_filesystem_path=sparkapp_path) + + config_dict = config.build_config(sparkapp_path) + logging.info(f'submit sparkapp, config: {config_dict}') + resp = k8s_client.create_sparkapplication(config_dict) return SparkAppInfo.from_k8s_resp(resp) def get_sparkapp_info(self, name: str) -> SparkAppInfo: diff --git a/web_console_v2/api/fedlearner_webconsole/utils/base64.py b/web_console_v2/api/fedlearner_webconsole/utils/base64.py new file mode 100644 index 000000000..06272b638 --- /dev/null +++ b/web_console_v2/api/fedlearner_webconsole/utils/base64.py @@ -0,0 +1,24 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +from base64 import b64encode, b64decode + + +def base64encode(s: str) -> str: + return b64encode(s.encode('UTF-8')).decode('UTF-8') + + +def base64decode(s: str) -> str: + return b64decode(s).decode('UTF-8') diff --git a/web_console_v2/api/fedlearner_webconsole/utils/es.py b/web_console_v2/api/fedlearner_webconsole/utils/es.py index b4ee70892..058d7fbf6 100644 --- a/web_console_v2/api/fedlearner_webconsole/utils/es.py +++ b/web_console_v2/api/fedlearner_webconsole/utils/es.py @@ -26,7 +26,7 @@ class ElasticSearchClient(object): def __init__(self): self._es_client = None self._es_client = Elasticsearch([{ - 'host': Envs.ES_HOST, + 'host': Envs.ES_READ_HOST or Envs.ES_HOST, 'port': Envs.ES_PORT }], http_auth=(Envs.ES_USERNAME, diff --git a/web_console_v2/api/fedlearner_webconsole/utils/file_manager.py b/web_console_v2/api/fedlearner_webconsole/utils/file_manager.py index 8767fc301..be9e51110 100644 --- a/web_console_v2/api/fedlearner_webconsole/utils/file_manager.py +++ b/web_console_v2/api/fedlearner_webconsole/utils/file_manager.py @@ -16,22 +16,20 @@ import importlib import logging import os -import shutil +import re from collections import namedtuple -from pathlib import Path from typing import List -from pyarrow import fs -from pyarrow.fs import FileSystem from tensorflow.io import gfile -from envs import Envs - # path: absolute path of the file # size: file size in bytes # mtime: time of last modification, unix timestamp in seconds. File = namedtuple('File', ['path', 'size', 'mtime']) +# Currently the supported format '/' or 'hdfs://' +# TODO(chenyikan): Add oss format when verified. +SUPPORTED_FILE_PREFIXES = r'\.+\/|^\/|^hdfs:\/\/' class FileManagerBase(object): @@ -42,12 +40,16 @@ def can_handle(self, path: str) -> bool: raise NotImplementedError() def ls(self, path: str, recursive=False) -> List[str]: - """Lists files under a path.""" + """Lists files under a path. + Raises: + ValueError: When the path does not exist. + """ raise NotImplementedError() def move(self, source: str, destination: str) -> bool: """Moves a file from source to destination, if destination - is a folder then move into that folder.""" + is a folder then move into that folder. Files that already exist + will be overwritten.""" raise NotImplementedError() def remove(self, path: str) -> bool: @@ -56,136 +58,25 @@ def remove(self, path: str) -> bool: def copy(self, source: str, destination: str) -> bool: """Copies a file from source to destination, if destination - is a folder then move into that folder.""" + is a folder then move into that folder. Files that already exist + will be overwritten.""" raise NotImplementedError() def mkdir(self, path: str) -> bool: """Creates a directory. If already exists, return False""" raise NotImplementedError() - -class DefaultFileManager(FileManagerBase): - """Default file manager for native file system or NFS.""" - def can_handle(self, path): - return path.startswith('/') - - def ls(self, path: str, recursive=False) -> List[File]: - def _get_file_stats(path: str): - stat = os.stat(path) - return File(path=path, size=stat.st_size, mtime=int(stat.st_mtime)) - - if not Path(path).exists(): - raise ValueError( - f'cannot access {path}: No such file or directory') - # If it is a file - if Path(path).is_file(): - return [_get_file_stats(path)] - - files = [] - if recursive: - for root, _, res in os.walk(path): - for file in res: - if Path(os.path.join(root, file)).is_file(): - files.append(_get_file_stats(os.path.join(root, file))) - else: - for file in os.listdir(path): - if Path(os.path.join(path, file)).is_file(): - files.append(_get_file_stats(os.path.join(path, file))) - # Files only - return files - - def move(self, source: str, destination: str) -> bool: - return shutil.move(source, destination) - - def remove(self, path: str) -> bool: - if os.path.isfile(path): - return os.remove(path) - return shutil.rmtree(path) - - def copy(self, source: str, destination: str) -> bool: - return shutil.copy(source, destination) - - def mkdir(self, path: str) -> bool: - return os.makedirs(path, exist_ok=True) - - -class HdfsFileManager(FileManagerBase): - """A wrapper of snakebite client.""" - def can_handle(self, path): - return path.startswith('hdfs://') - - def __init__(self): - self._client, _ = FileSystem.from_uri(Envs.HDFS_SERVER) - - def _unwrap_path(self, path): - if path.startswith('hdfs://'): - return path[7:] - return path - - def _wrap_path(self, path): - if not path.startswith('hdfs://'): - return f'hdfs://{path}' - return path - - def ls(self, path: str, recursive=False) -> List[File]: - path = self._unwrap_path(path) - files = [] - try: - curr_path_info = self._client.get_file_info(path) - res_files = [] - if curr_path_info.type == fs.FileType.File: - res_files = [curr_path_info] - elif curr_path_info.type == fs.FileType.Directory: - res_files = self._client.get_file_info( - fs.FileSelector(path, recursive=recursive)) - else: - raise ValueError( - f'cannot access {path}: No such file or directory') - - for file in res_files: - if file.type == fs.FileType.File: - files.append( - File( - path=self._wrap_path(file.path), - size=file.size, - # ns to second - mtime=int(file.mtime_ns / 1e9))) - except RuntimeError as error: - # This is a hack that snakebite can not handle generator - if str(error) == 'generator raised StopIteration': - pass - else: - raise - return files - - def move(self, source: str, destination: str) -> bool: - source = self._unwrap_path(source) - destination = self._unwrap_path(destination) - return len(list(self._client.move(source, destination))) > 0 - - def remove(self, path: str) -> bool: - path = self._unwrap_path(path) - if self._client.get_file_info(path).is_file: - return self._client.delete_file(path) - return self._client.delete_dir(path) - - def copy(self, source: str, destination: str) -> bool: - return gfile.copy(source, destination) - - def mkdir(self, path: str) -> bool: - path = self._unwrap_path(path) - return self._client.create_dir(path) + def read(self, path: str) -> str: + raise NotImplementedError() class GFileFileManager(FileManagerBase): - """Gfile file manager for all FS supported by TF.""" + """Gfile file manager for all FS supported by TF, + currently it covers all file types we have.""" def can_handle(self, path): - # TODO: List tf support if path.startswith('fake://'): return False - if not Envs.HDFS_SERVER and path.startswith('hdfs://'): - return False - return True + return re.match(SUPPORTED_FILE_PREFIXES, path) def ls(self, path: str, recursive=False) -> List[File]: def _get_file_stats(path: str): @@ -225,18 +116,28 @@ def remove(self, path: str) -> bool: return gfile.rmtree(path) def copy(self, source: str, destination: str) -> bool: - return gfile.copy(source, destination) + if gfile.isdir(destination): + # gfile requires a file name for copy destination. + return gfile.copy(source, + os.path.join(destination, + os.path.basename(source)), + overwrite=True) + return gfile.copy(source, destination, overwrite=True) def mkdir(self, path: str) -> bool: return gfile.makedirs(path) + def read(self, path: str) -> str: + return gfile.GFile(path).read() + class FileManager(FileManagerBase): """A centralized manager to handle files. Please extend `FileManagerBase` and put the class path into `CUSTOMIZED_FILE_MANAGER`. For example, - 'fedlearner_webconsole.utils.file_manager:HdfsFileManager'""" + 'fedlearner_webconsole.utils.file_manager:HdfsFileManager' + """ def __init__(self): self._file_managers = [] cfm_path = os.environ.get('CUSTOMIZED_FILE_MANAGER') @@ -246,9 +147,6 @@ def __init__(self): # Dynamically construct a file manager customized_file_manager = getattr(module, class_name) self._file_managers.append(customized_file_manager()) - if Envs.HDFS_SERVER: - self._file_managers.append(HdfsFileManager()) - self._file_managers.append(DefaultFileManager()) self._file_managers.append(GFileFileManager()) def can_handle(self, path): @@ -268,6 +166,7 @@ def move(self, source: str, destination: str) -> bool: for fm in self._file_managers: if fm.can_handle(source) and fm.can_handle(destination): return fm.move(source, destination) + # TODO(chenyikan): Support cross FileManager move by using buffers. raise RuntimeError( f'move is not supported for {source} and {destination}') @@ -283,6 +182,7 @@ def copy(self, source: str, destination: str) -> bool: for fm in self._file_managers: if fm.can_handle(source) and fm.can_handle(destination): return fm.copy(source, destination) + # TODO(chenyikan): Support cross FileManager move by using buffers. raise RuntimeError( f'copy is not supported for {source} and {destination}') @@ -292,3 +192,10 @@ def mkdir(self, path: str) -> bool: if fm.can_handle(path): return fm.mkdir(path) raise RuntimeError(f'mkdir is not supported for {path}') + + def read(self, path: str) -> str: + logging.info(f'Read file from [{path}]') + for fm in self._file_managers: + if fm.can_handle(path): + return fm.read(path) + raise RuntimeError(f'read is not supported for {path}') diff --git a/web_console_v2/api/fedlearner_webconsole/utils/hooks.py b/web_console_v2/api/fedlearner_webconsole/utils/hooks.py new file mode 100644 index 000000000..25d0b9a6b --- /dev/null +++ b/web_console_v2/api/fedlearner_webconsole/utils/hooks.py @@ -0,0 +1,31 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +import importlib + +from envs import Envs +from fedlearner_webconsole.db import db_handler as db, get_database_uri + + +def pre_start_hook(): + before_hook_path = Envs.PRE_START_HOOK + if before_hook_path: + module_path, func_name = before_hook_path.split(':') + module = importlib.import_module(module_path) + # Dynamically run the function + getattr(module, func_name)() + + # explicit rebind db engine to make hook work + db.rebind(get_database_uri()) diff --git a/web_console_v2/api/fedlearner_webconsole/utils/k8s_watcher.py b/web_console_v2/api/fedlearner_webconsole/utils/k8s_watcher.py index 30810cb22..22372a1ab 100644 --- a/web_console_v2/api/fedlearner_webconsole/utils/k8s_watcher.py +++ b/web_console_v2/api/fedlearner_webconsole/utils/k8s_watcher.py @@ -27,9 +27,10 @@ FEDLEARNER_CUSTOM_VERSION) from fedlearner_webconsole.mmgr.service import ModelService from fedlearner_webconsole.db import make_session_context +from fedlearner_webconsole.job.service import JobService -session_context = make_session_context() +session_context = make_session_context() class K8sWatcher(object): def __init__(self): @@ -77,6 +78,8 @@ def _event_consumer(self): try: event = self._queue.get() k8s_cache.update_cache(event) + # job state must be updated before model service + self._update_hook(event) if Features.FEATURE_MODEL_K8S_HOOK: with session_context() as session: ModelService(session).k8s_watcher_hook(event) @@ -85,6 +88,14 @@ def _event_consumer(self): logging.error(f'K8s event_consumer : {str(e)}. ' f'traceback:{traceback.format_exc()}') + def _update_hook(self, event: Event): + if event.obj_type == ObjectType.FLAPP: + logging.debug('[k8s_watcher][_update_hook]receive event %s', + event.flapp_name) + with session_context() as session: + JobService(session).update_running_state(event.flapp_name) + session.commit() + def _k8s_flapp_watcher(self): resource_version = '0' watcher = watch.Watch() diff --git a/web_console_v2/api/fedlearner_webconsole/workflow/apis.py b/web_console_v2/api/fedlearner_webconsole/workflow/apis.py index 237285f15..abc5c19a5 100644 --- a/web_console_v2/api/fedlearner_webconsole/workflow/apis.py +++ b/web_console_v2/api/fedlearner_webconsole/workflow/apis.py @@ -166,6 +166,10 @@ def post(self): type=int, required=False, help='interval for workflow cronjob in minute') + parser.add_argument('extra', + type=str, + required=False, + help='extra json string that needs send to peer') parser.add_argument('comment') data = parser.parse_args() @@ -188,7 +192,9 @@ def post(self): forked_from=data['forked_from'], state=WorkflowState.NEW, target_state=WorkflowState.READY, - transaction_state=TransactionState.READY) + transaction_state=TransactionState.READY, + extra=data['extra'] + ) workflow.set_config(template_proto) workflow.set_create_job_flags(data['create_job_flags']) diff --git a/web_console_v2/api/fedlearner_webconsole/workflow/models.py b/web_console_v2/api/fedlearner_webconsole/workflow/models.py index 58e9ce5d8..f988f93db 100644 --- a/web_console_v2/api/fedlearner_webconsole/workflow/models.py +++ b/web_console_v2/api/fedlearner_webconsole/workflow/models.py @@ -31,6 +31,7 @@ from fedlearner_webconsole.rpc.client import RpcClient from fedlearner_webconsole.mmgr.service import ModelService + class WorkflowState(enum.Enum): INVALID = 0 NEW = 1 @@ -201,6 +202,8 @@ class Workflow(db.Model): server_default=func.now(), comment='update_at') + extra = db.Column(db.Text(), comment='extra') # json string + owned_jobs = db.relationship( 'Job', primaryjoin='foreign(Job.workflow_id) == Workflow.id') project = db.relationship( @@ -208,12 +211,13 @@ class Workflow(db.Model): def get_state_for_frontend(self): if self.state == WorkflowState.RUNNING: - is_complete = all([ - job.is_disabled or job.is_complete() for job in self.owned_jobs - ]) + is_complete = all([job.is_disabled or + job.state == JobState.COMPLETED + for job in self.owned_jobs]) if is_complete: return 'COMPLETED' - is_failed = any([job.is_failed() for job in self.owned_jobs]) + is_failed = any([job.state == JobState.FAILED + for job in self.owned_jobs]) if is_failed: return 'FAILED' return self.state.name @@ -390,6 +394,17 @@ def prepare(self, target_state): def rollback(self): self.target_state = WorkflowState.INVALID + def start(self): + self.start_at = int(datetime.now().timestamp()) + for job in self.owned_jobs: + if not job.is_disabled: + job.schedule() + + def stop(self): + self.stop_at = int(datetime.now().timestamp()) + for job in self.owned_jobs: + job.stop() + # TODO: separate this method to another module def commit(self): assert self.transaction_state in [ @@ -398,23 +413,18 @@ def commit(self): 'Workflow not in prepare state' if self.target_state == WorkflowState.STOPPED: - self.stop_at = int(datetime.now().timestamp()) try: - for job in self.owned_jobs: - job.stop() + self.stop() except RuntimeError as e: # errors from k8s - logging.error('Stop workflow %d has Runtime error msg: %s', + logging.error('Stop workflow %d has error msg: %s', self.id, e.args) return elif self.target_state == WorkflowState.READY: self._setup_jobs() self.fork_proposal_config = None elif self.target_state == WorkflowState.RUNNING: - self.start_at = int(datetime.now().timestamp()) - for job in self.owned_jobs: - if not job.is_disabled: - job.schedule() + self.start() self.state = self.target_state self.target_state = WorkflowState.INVALID @@ -465,7 +475,7 @@ def _setup_jobs(self): config=job_def.SerializeToString(), workflow_id=self.id, project_id=self.project_id, - state=JobState.STOPPED, + state=JobState.NEW, is_disabled=(flag == common_pb2.CreateJobFlag.DISABLED)) db.session.add(job) jobs.append(job) @@ -522,3 +532,30 @@ def _prepare_for_ready(self): return True return bool(self.config) + + def is_local(self): + # since _setup_jobs has not been called, job_definitions is used + job_defs = self.get_config().job_definitions + flags = self.get_create_job_flags() + for i, (job_def, flag) in enumerate(zip(job_defs, flags)): + if flag != common_pb2.CreateJobFlag.REUSE and job_def.is_federated: + return False + return True + + def update_local_state(self): + if self.target_state == WorkflowState.INVALID: + return + if self.target_state == WorkflowState.READY: + self._setup_jobs() + elif self.target_state == WorkflowState.RUNNING: + self.start() + elif self.target_state == WorkflowState.STOPPED: + try: + self.stop() + except Exception as e: + # errors from k8s + logging.error('Stop workflow %d has error msg: %s', + self.id, e.args) + return + self.state = self.target_state + self.target_state = WorkflowState.INVALID diff --git a/web_console_v2/api/fedlearner_webconsole/workflow_template/apis.py b/web_console_v2/api/fedlearner_webconsole/workflow_template/apis.py index 0bbbaba5a..791f2ba89 100644 --- a/web_console_v2/api/fedlearner_webconsole/workflow_template/apis.py +++ b/web_console_v2/api/fedlearner_webconsole/workflow_template/apis.py @@ -146,7 +146,7 @@ def get(self, template_id): template = WorkflowTemplate.query.filter_by(id=template_id).first() if template is None: - raise NotFoundException() + raise NotFoundException(f'Failed to find template: {template_id}') result = template.to_dict() if download: @@ -164,7 +164,7 @@ def get(self, template_id): def delete(self, template_id): result = WorkflowTemplate.query.filter_by(id=template_id) if result.first() is None: - raise NotFoundException() + raise NotFoundException(f'Failed to find template: {template_id}') result.delete() db.session.commit() return {'data': {}}, HTTPStatus.OK @@ -192,7 +192,7 @@ def put(self, template_id): 'Workflow template {} already exists'.format(name)) template = WorkflowTemplate.query.filter_by(id=template_id).first() if template is None: - raise NotFoundException() + raise NotFoundException(f'Failed to find template: {template_id}') template_proto, editor_info_proto = _check_config_and_editor_info( config, editor_info) template_proto = _format_template_with_yaml_editor( diff --git a/web_console_v2/api/migrations/versions/b3290c1bf67a_add_completed_failed_jobstate.py b/web_console_v2/api/migrations/versions/b3290c1bf67a_add_completed_failed_jobstate.py new file mode 100644 index 000000000..90f4614e0 --- /dev/null +++ b/web_console_v2/api/migrations/versions/b3290c1bf67a_add_completed_failed_jobstate.py @@ -0,0 +1,38 @@ +"""add_completed_failed_jobstate + +Revision ID: b3290c1bf67a +Revises: fe30109949aa +Create Date: 2021-06-15 01:41:14.660466 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'b3290c1bf67a' +down_revision = 'fe30109949aa' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + bind = op.get_bind() + version = bind.execute('select version()') + # 'drop check' is invalid if mysql version is less than 8 + if version is not None and version.fetchall()[0][0] > '8.0.0': + op.execute('ALTER TABLE job_v2 drop check jobstate') + op.alter_column('job_v2', 'state', nullable=False, comment='state', type_=sa.Enum('INVALID', 'STOPPED', 'WAITING', 'STARTED', 'COMPLETED', 'FAILED', name='jobstate', native_enum=False)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + bind = op.get_bind() + version = bind.execute('select version()') + # 'drop check' is invalid if mysql version is less than 8 + if version is not None and version.fetchall()[0][0] > '8.0.0': + op.execute('ALTER TABLE job_v2 drop check jobstate') + op.alter_column('job_v2', 'state', nullable=False, comment='state', type_=sa.Enum('INVALID', 'STOPPED', 'WAITING', 'STARTED', name='jobstate', native_enum=False)) + # ### end Alembic commands ### diff --git a/web_console_v2/api/migrations/versions/fe30109949aa_add_extra_field_to_workflow.py b/web_console_v2/api/migrations/versions/fe30109949aa_add_extra_field_to_workflow.py new file mode 100644 index 000000000..11ece68f3 --- /dev/null +++ b/web_console_v2/api/migrations/versions/fe30109949aa_add_extra_field_to_workflow.py @@ -0,0 +1,24 @@ +"""add extra field to workflow + +Revision ID: fe30109949aa +Revises: 27a868485bf7 +Create Date: 2021-06-06 14:31:29.833200 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'fe30109949aa' +down_revision = '27a868485bf7' +branch_labels = None +depends_on = None + + +def upgrade(): + op.add_column('workflow_v2', sa.Column('extra', sa.Text(), nullable=True, comment='extra')) + + +def downgrade(): + op.drop_column('workflow_v2', 'extra') diff --git a/web_console_v2/api/protocols/fedlearner_webconsole/proto/service.proto b/web_console_v2/api/protocols/fedlearner_webconsole/proto/service.proto index 1f4283f78..0a3f89350 100644 --- a/web_console_v2/api/protocols/fedlearner_webconsole/proto/service.proto +++ b/web_console_v2/api/protocols/fedlearner_webconsole/proto/service.proto @@ -39,6 +39,13 @@ message CheckConnectionResponse { Status status = 1; } +message PingRequest {} + +message PingResponse { + Status status = 1; + string msg = 2; +} + message UpdateWorkflowStateRequest { ProjAuthInfo auth_info = 1; string workflow_name = 2; @@ -47,6 +54,8 @@ message UpdateWorkflowStateRequest { int64 transaction_state = 5; string forked_from_uuid = 6; string uuid = 7; + // json string + string extra = 8; } message UpdateWorkflowStateResponse { @@ -140,6 +149,7 @@ message GetJobKibanaResponse { service WebConsoleV2Service { rpc CheckConnection (CheckConnectionRequest) returns (CheckConnectionResponse) {} + rpc Ping (PingRequest) returns (PingResponse) {} rpc UpdateWorkflowState (UpdateWorkflowStateRequest) returns (UpdateWorkflowStateResponse) {} rpc GetWorkflow (GetWorkflowRequest) returns (GetWorkflowResponse) {} rpc UpdateWorkflow(UpdateWorkflowRequest) returns (UpdateWorkflowResponse) {} diff --git a/web_console_v2/api/requirements.txt b/web_console_v2/api/requirements.txt index 88beaa063..28ee70aaf 100644 --- a/web_console_v2/api/requirements.txt +++ b/web_console_v2/api/requirements.txt @@ -12,6 +12,7 @@ grpcio==1.32.0 # see details in https://github.com/grpc/grpc/issues/24897 grpcio-tools==1.32.0 grpcio-testing==1.32.0 +grpcio-reflection==1.32.0 kubernetes==12.0.1 elasticsearch==7.11.0 flatten-dict==0.3.0 @@ -23,7 +24,6 @@ mpld3==0.5.2 python-slugify==4.0.1 SQLAlchemy==1.3.20 prison==0.1.3 -pyarrow==3.0.0 tensorflow-io==0.8.1 pyspark==3.1.1 # Lint diff --git a/web_console_v2/api/server.py b/web_console_v2/api/server.py index 722f16cc8..bdb8e9e81 100644 --- a/web_console_v2/api/server.py +++ b/web_console_v2/api/server.py @@ -16,7 +16,9 @@ from config import Config from fedlearner_webconsole.app import create_app from fedlearner_webconsole.utils import middlewares +from fedlearner_webconsole.utils.hooks import pre_start_hook +pre_start_hook() app = create_app(Config()) # Middlewares app = middlewares.init_app(app) diff --git a/web_console_v2/api/test/auth_test.py b/web_console_v2/api/test/auth_test.py index aca9917d5..995a90458 100644 --- a/web_console_v2/api/test/auth_test.py +++ b/web_console_v2/api/test/auth_test.py @@ -17,9 +17,10 @@ import unittest from http import HTTPStatus +from fedlearner_webconsole.utils.base64 import base64encode from testing.common import BaseTestCase from fedlearner_webconsole.auth.models import State, User -from fedlearner_webconsole.db import db +from fedlearner_webconsole.db import db_handler as db class AuthApiTest(BaseTestCase): @@ -27,8 +28,9 @@ def test_get_all_users(self): deleted_user = User(username='deleted_one', email='who.knows@hhh.com', state=State.DELETED) - db.session.add(deleted_user) - db.session.commit() + with db.session_scope() as session: + session.add(deleted_user) + session.commit() resp = self.get_helper('/api/v2/auth/users') self.assertEqual(resp.status_code, HTTPStatus.UNAUTHORIZED) @@ -74,6 +76,12 @@ def test_partial_update_user_info(self): self.assertEqual(resp.status_code, HTTPStatus.OK) self.assertEqual(self.get_response_data(resp).get('role'), 'ADMIN') + resp = self.patch_helper(f'/api/v2/auth/users/{user_id}', + data={ + 'password': base64encode('fl@1234.'), + }) + self.assertEqual(resp.status_code, HTTPStatus.OK) + def test_create_new_user(self): new_user = { 'username': 'fedlearner', @@ -86,11 +94,27 @@ def test_create_new_user(self): self.assertEqual(resp.status_code, HTTPStatus.UNAUTHORIZED) self.signin_as_admin() + illegal_cases = ['aaaaaaaa', '11111111', '!@#$%^[]', + 'aaaA1111', 'AAAa!@#$', '1111!@#-', + 'aa11!@', 'fl@123.', + 'fl@1234567890abcdefg.'] + legal_case = 'fl@1234.' + + for case in illegal_cases: + new_user['password'] = base64encode(case) + resp = self.post_helper(f'/api/v2/auth/users', data=new_user) + self.assertEqual(resp.status_code, HTTPStatus.BAD_REQUEST) + + new_user['password'] = base64encode(legal_case) resp = self.post_helper(f'/api/v2/auth/users', data=new_user) self.assertEqual(resp.status_code, HTTPStatus.CREATED) self.assertEqual( self.get_response_data(resp).get('username'), 'fedlearner') + # test_repeat_create + resp = self.post_helper(f'/api/v2/auth/users', data=new_user) + self.assertEqual(resp.status_code, HTTPStatus.CONFLICT) + def test_delete_user(self): self.signin_as_admin() resp = self.get_helper('/api/v2/auth/users') @@ -132,7 +156,7 @@ def test_signout(self): self.signin_helper() resp = self.delete_helper(url='/api/v2/auth/signin') - self.assertEqual(resp.status_code, HTTPStatus.OK) + self.assertEqual(resp.status_code, HTTPStatus.OK, resp.json) resp = self.get_helper(url='/api/v2/auth/users/1') self.assertEqual(resp.status_code, HTTPStatus.UNAUTHORIZED) diff --git a/web_console_v2/api/test/fedlearner_webconsole/dataset/apis_test.py b/web_console_v2/api/test/fedlearner_webconsole/dataset/apis_test.py index d1a224454..23e2b4bed 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/dataset/apis_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/dataset/apis_test.py @@ -13,9 +13,8 @@ # limitations under the License. # coding: utf-8 -import stat -import time import json +import time import os import shutil import tempfile @@ -26,37 +25,42 @@ from unittest import mock from unittest.mock import patch, MagicMock +from collections import namedtuple from testing.common import BaseTestCase -from fedlearner_webconsole.db import db -from fedlearner_webconsole.dataset.models import (Dataset, DatasetType, - DataBatch) +from fedlearner_webconsole.db import db_handler as db +from fedlearner_webconsole.dataset.models import (Dataset, DatasetType) +from tensorflow.io import gfile + +FakeFileStatistics = namedtuple('FakeFileStatistics', ['length', 'mtime_nsec']) class DatasetApiTest(BaseTestCase): class Config(BaseTestCase.Config): - STORAGE_ROOT = '/tmp' + STORAGE_ROOT = tempfile.gettempdir() def setUp(self): super().setUp() - self.default_dataset1 = Dataset( - name='default dataset1', - dataset_type=DatasetType.STREAMING, - comment='test comment1', - path='/data/dataset/123', - project_id=1, - ) - db.session.add(self.default_dataset1) - db.session.commit() + with db.session_scope() as session: + self.default_dataset1 = Dataset( + name='default dataset1', + dataset_type=DatasetType.STREAMING, + comment='test comment1', + path='/data/dataset/123', + project_id=1, + ) + session.add(self.default_dataset1) + session.commit() time.sleep(1) - self.default_dataset2 = Dataset( - name='default dataset2', - dataset_type=DatasetType.STREAMING, - comment='test comment2', - path='123', - project_id=2, - ) - db.session.add(self.default_dataset2) - db.session.commit() + with db.session_scope() as session: + self.default_dataset2 = Dataset( + name='default dataset2', + dataset_type=DatasetType.STREAMING, + comment='test comment2', + path=os.path.join(tempfile.gettempdir(), 'dataset/123'), + project_id=2, + ) + session.add(self.default_dataset2) + session.commit() def test_get_dataset(self): get_response = self.get_helper( @@ -89,6 +93,74 @@ def test_get_datasets(self): self.assertEqual(datasets[0]['name'], 'default dataset2') self.assertEqual(datasets[1]['name'], 'default dataset1') + def test_get_datasets_with_project_id(self): + get_response = self.get_helper('/api/v2/datasets?project=1') + self.assertEqual(get_response.status_code, HTTPStatus.OK) + datasets = self.get_response_data(get_response) + self.assertEqual(len(datasets), 1) + self.assertEqual(datasets[0]['name'], 'default dataset1') + + def test_preview_dataset_and_feature_metrics(self): + # write data + gfile.makedirs(self.default_dataset2.path) + meta_path = os.path.join(self.default_dataset2.path, '_META') + meta_data = { + 'dtypes': { + 'f01': 'bigint' + }, + 'samples': [ + [1], + [0], + ], + } + with gfile.GFile(meta_path, 'w') as f: + f.write(json.dumps(meta_data)) + + features_path = os.path.join(self.default_dataset2.path, '_FEATURES') + features_data = { + 'f01': { + 'count': '2', + 'mean': '0.0015716767309123998', + 'stddev': '0.03961485047808605', + 'min': '0', + 'max': '1', + 'missing_count': '0' + } + } + with gfile.GFile(features_path, 'w') as f: + f.write(json.dumps(features_data)) + + hist_path = os.path.join(self.default_dataset2.path, '_HIST') + hist_data = { + "f01": { + "x": [ + 0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, + 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1 + ], + "y": [12070, 0, 0, 0, 0, 0, 0, 0, 0, 19] + } + } + with gfile.GFile(hist_path, 'w') as f: + f.write(json.dumps(hist_data)) + + response = self.client.get('/api/v2/datasets/2/preview') + self.assertEqual(response.status_code, 200) + preview_data = self.get_response_data(response) + meta_data['metrics'] = features_data + self.assertEqual(preview_data, meta_data, 'should has preview data') + + feat_name = 'f01' + feature_response = self.client.get( + f'/api/v2/datasets/2/feature_metrics?name={feat_name}') + self.assertEqual(response.status_code, 200) + feature_data = self.get_response_data(feature_response) + self.assertEqual( + feature_data, { + 'name': feat_name, + 'metrics': features_data.get(feat_name, {}), + 'hist': hist_data.get(feat_name, {}) + }, 'should has feature data') + @patch('fedlearner_webconsole.dataset.apis.datetime') def test_post_datasets(self, mock_datetime): mock_datetime.now = MagicMock( @@ -106,13 +178,15 @@ def test_post_datasets(self, mock_datetime): self.assertEqual(create_response.status_code, HTTPStatus.OK) created_dataset = self.get_response_data(create_response) + dataset_path = os.path.join( + tempfile.gettempdir(), 'dataset/20200608_060606_test-post-dataset') self.assertEqual( { 'id': 3, 'name': 'test post dataset', 'dataset_type': dataset_type, 'comment': comment, - 'path': '/tmp/dataset/20200608_060606_test-post-dataset', + 'path': dataset_path, 'created_at': mock.ANY, 'updated_at': mock.ANY, 'deleted_at': None, @@ -130,7 +204,7 @@ def test_post_datasets(self, mock_datetime): 'name': 'test post dataset', 'dataset_type': dataset_type, 'comment': updated_comment, - 'path': '/tmp/dataset/20200608_060606_test-post-dataset', + 'path': dataset_path, 'created_at': mock.ANY, 'updated_at': mock.ANY, 'deleted_at': None, @@ -216,7 +290,7 @@ def setUp(self): def fake_stat(path, *arg, **kwargs): return self._get_file_stat(self._orig_os_stat, path) - os.stat = fake_stat + gfile.stat = fake_stat def tearDown(self): os.stat = self._orig_os_stat @@ -229,11 +303,9 @@ def _get_temp_path(self, file_path: str = None) -> str: def _get_file_stat(self, orig_os_stat, path): if path == self._get_temp_path('f1.txt') or \ - path == self._get_temp_path('f2.txt') or \ - path == self._get_temp_path('s/s3.txt'): - faked = list(orig_os_stat(path)) - faked[stat.ST_MTIME] = 1613982390 - return os.stat_result(faked) + path == self._get_temp_path('f2.txt') or \ + path == self._get_temp_path('s/s3.txt'): + return FakeFileStatistics(2, 1613982390 * 1e9) else: return orig_os_stat(path) @@ -241,7 +313,7 @@ def test_get_default_storage_root(self): get_response = self.get_helper('/api/v2/files') self.assertEqual(get_response.status_code, HTTPStatus.OK) files = self.get_response_data(get_response) - self.assertEqual(sorted(files, key=lambda f: f['size']), [ + self.assertEqual(sorted(files, key=lambda f: f['path']), [ { 'path': self._get_temp_path('f1.txt'), 'size': 2, @@ -249,12 +321,12 @@ def test_get_default_storage_root(self): }, { 'path': self._get_temp_path('f2.txt'), - 'size': 4, + 'size': 2, 'mtime': 1613982390 }, { 'path': self._get_temp_path('s/s3.txt'), - 'size': 6, + 'size': 2, 'mtime': 1613982390 }, ]) @@ -267,7 +339,7 @@ def test_get_specified_directory(self): self.assertEqual(files, [ { 'path': self._get_temp_path('s/s3.txt'), - 'size': 6, + 'size': 2, 'mtime': 1613982390 }, ]) diff --git a/web_console_v2/api/test/fedlearner_webconsole/exceptions_test.py b/web_console_v2/api/test/fedlearner_webconsole/exceptions_test.py index bdcbff70d..6e7af1a3c 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/exceptions_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/exceptions_test.py @@ -16,7 +16,8 @@ import unittest from http import HTTPStatus -from fedlearner_webconsole.exceptions import InvalidArgumentException +from fedlearner_webconsole.exceptions import (InvalidArgumentException, + NotFoundException) class ExceptionsTest(unittest.TestCase): @@ -35,6 +36,22 @@ def test_invalid_argument_exception(self): ] }) + def test_not_found_exception(self): + exception1 = NotFoundException('User A not found.') + self.assertEqual(exception1.status_code, HTTPStatus.NOT_FOUND) + self.assertEqual( + exception1.to_dict(), { + 'code': 404, + 'message': 'User A not found.', + }) + exception2 = NotFoundException() + self.assertEqual(exception2.status_code, HTTPStatus.NOT_FOUND) + self.assertEqual( + exception2.to_dict(), { + 'code': 404, + 'message': 'Resource not found.', + }) + if __name__ == '__main__': unittest.main() diff --git a/web_console_v2/api/test/fedlearner_webconsole/job/service_test.py b/web_console_v2/api/test/fedlearner_webconsole/job/service_test.py index 5ac9d6f41..8161ea56c 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/job/service_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/job/service_test.py @@ -44,7 +44,7 @@ def setUp(self): job_1 = Job(id=1, name='raw_data_1', job_type=JobType.RAW_DATA, - state=JobState.WAITING, + state=JobState.COMPLETED, workflow_id=0, project_id=0, config=config) @@ -58,7 +58,7 @@ def setUp(self): job_3 = Job(id=3, name='data_join_1', job_type=JobType.DATA_JOIN, - state=JobState.STARTED, + state=JobState.COMPLETED, workflow_id=1, project_id=0, config=config) @@ -91,6 +91,22 @@ def test_is_ready(self): job_service = JobService(db.session) self.assertTrue(job_service.is_ready(job_0)) self.assertFalse(job_service.is_ready(job_2)) - with patch('fedlearner_webconsole.job.models.Job.is_complete', - return_value=True): - self.assertTrue(job_service.is_ready(job_4)) + self.assertTrue(job_service.is_ready(job_4)) + + @patch('fedlearner_webconsole.job.models.Job.is_flapp_failed') + @patch('fedlearner_webconsole.job.models.Job.is_flapp_complete') + def test_update_running_state(self, mock_is_complete, mock_is_failed): + job_0 = db.session.query(Job).get(0) + job_2 = db.session.query(Job).get(2) + mock_is_complete.return_value = True + job_service = JobService(db.session) + job_service.update_running_state(job_0.name) + self.assertEqual(job_0.state, JobState.COMPLETED) + self.assertTrue(job_service.is_ready(job_2)) + job_0.state = JobState.STARTED + mock_is_complete.return_value = False + mock_is_failed = True + job_service.update_running_state(job_0.name) + self.assertEqual(job_0.state, JobState.FAILED) + + diff --git a/web_console_v2/api/test/fedlearner_webconsole/job/yaml_formatter_test.py b/web_console_v2/api/test/fedlearner_webconsole/job/yaml_formatter_test.py index 7b76efb0b..8ad1e6269 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/job/yaml_formatter_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/job/yaml_formatter_test.py @@ -104,7 +104,7 @@ def test_generate_self_dict(self): } ] } - job = Job(name='aa', project_id=1, workflow_id=1, state=JobState.STOPPED) + job = Job(name='aa', project_id=1, workflow_id=1, state=JobState.NEW) job.set_config(ParseDict(config, JobDefinition())) self.assertEqual(generate_self_dict(job), {'id': None, 'name': 'aa', diff --git a/web_console_v2/api/test/fedlearner_webconsole/mmgr/model_test.py b/web_console_v2/api/test/fedlearner_webconsole/mmgr/model_test.py index deaef699c..84c8644e2 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/mmgr/model_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/mmgr/model_test.py @@ -15,9 +15,10 @@ # coding: utf-8 import unittest -from unittest.mock import patch +from unittest.mock import MagicMock, patch + from testing.common import BaseTestCase -from fedlearner_webconsole.db import db, get_session, make_session_context +from fedlearner_webconsole.db import db, get_session from fedlearner_webconsole.mmgr.models import Model from fedlearner_webconsole.mmgr.models import ModelState from fedlearner_webconsole.mmgr.service import ModelService @@ -26,48 +27,80 @@ class ModelTest(BaseTestCase): - @patch( - 'fedlearner_webconsole.mmgr.service.ModelService.get_checkpoint_path' - ) + 'fedlearner_webconsole.mmgr.service.ModelService.get_checkpoint_path') def setUp(self, mock_get_checkpoint_path): super().setUp() self.model_service = ModelService(db.session) self.train_job = Job(name='train-job', - job_type=JobType.NN_MODEL_TRANINING) + job_type=JobType.NN_MODEL_TRANINING, + workflow_id=1, + project_id=1) self.eval_job = Job(name='eval-job', - job_type=JobType.NN_MODEL_EVALUATION) + job_type=JobType.NN_MODEL_EVALUATION, + workflow_id=1, + project_id=1) mock_get_checkpoint_path.return_value = 'output' self.model_service.create(job=self.train_job, parent_job_name=None) - model = db.session.query(Model).filter_by(job_name=self.train_job.name).one() - self.model_service.create(job=self.eval_job, parent_job_name=model.job_name) + model = db.session.query(Model).filter_by( + job_name=self.train_job.name).one() + self.model_service.create(job=self.eval_job, + parent_job_name=model.job_name) + db.session.add(self.train_job) + db.session.add(self.eval_job) db.session.commit() - @patch('fedlearner_webconsole.job.models.Job.is_complete') - @patch('fedlearner_webconsole.job.models.Job.is_failed') - def test_on_job_update(self, mock_is_failed, mock_is_complete): - model = Model.query.filter_by(job_name=self.train_job.name).one() - self.assertEqual(model.state, ModelState.COMMITTED.value) - self.train_job.state = JobState.STARTED - - mock_is_failed.return_value = False - mock_is_complete.return_value = False - self.model_service.on_job_update(self.train_job) - self.assertEqual(model.state, ModelState.RUNNING.value) - - mock_is_failed.return_value = False - mock_is_complete.return_value = True - self.model_service.on_job_update(self.train_job) - self.assertEqual(model.state, ModelState.SUCCEEDED.value) - - mock_is_failed.return_value = True - mock_is_complete.return_value = False - self.model_service.on_job_update(self.train_job) - self.assertEqual(model.state, ModelState.FAILED.value) - - @patch('fedlearner_webconsole.job.models.Job.is_complete') - @patch('fedlearner_webconsole.job.models.Job.is_failed') - def test_hook(self, mock_is_failed, mock_is_complete): + @patch('fedlearner_webconsole.mmgr.service.ModelService.plot_metrics') + def test_on_job_update(self, mock_plot_metrics: MagicMock): + mock_plot_metrics.return_value = 'plot metrics return' + + # TODO: change get_session to db.session_scope + with get_session(db.engine) as session: + model = session.query(Model).filter_by( + job_name=self.train_job.name).one() + self.assertEqual(model.state, ModelState.COMMITTED.value) + + train_job = session.query(Job).filter_by(name='train-job').one() + train_job.state = JobState.STARTED + session.commit() + + # TODO: change get_session to db.session_scope + with get_session(db.engine) as session: + train_job = session.query(Job).filter_by(name='train-job').one() + train_job.state = JobState.STARTED + model = session.query(Model).filter_by( + job_name=self.train_job.name).one() + model_service = ModelService(session) + + model_service.on_job_update(train_job) + self.assertEqual(model.state, ModelState.RUNNING.value) + session.commit() + + # TODO: change get_session to db.session_scope + with get_session(db.engine) as session: + train_job = session.query(Job).filter_by(name='train-job').one() + train_job.state = JobState.COMPLETED + model = session.query(Model).filter_by( + job_name=self.train_job.name).one() + model_service = ModelService(session) + + model_service.on_job_update(train_job) + self.assertEqual(model.state, ModelState.SUCCEEDED.value) + session.commit() + + # TODO: change get_session to db.session_scope + with get_session(db.engine) as session: + train_job = session.query(Job).filter_by(name='train-job').one() + train_job.state = JobState.FAILED + model = session.query(Model).filter_by( + job_name=self.train_job.name).one() + model_service = ModelService(session) + + model_service.on_job_update(train_job) + self.assertEqual(model.state, ModelState.FAILED.value) + session.commit() + + def test_hook(self): train_job = Job(id=0, state=JobState.STARTED, name='nn-train', @@ -85,27 +118,23 @@ def test_hook(self, mock_is_failed, mock_is_complete): self.assertEqual(model.state, ModelState.COMMITTED.value) event.event_type = EventType.MODIFIED - mock_is_failed.return_value = False - mock_is_complete.return_value = False + train_job.state = JobState.STARTED self.model_service.k8s_watcher_hook(event) self.assertEqual(model.state, ModelState.RUNNING.value) - mock_is_failed.return_value = False - mock_is_complete.return_value = True + train_job.state = JobState.COMPLETED self.model_service.k8s_watcher_hook(event) self.assertEqual(model.state, ModelState.SUCCEEDED.value) - mock_is_failed.return_value = False - mock_is_complete.return_value = False + train_job.state = JobState.STARTED self.model_service.k8s_watcher_hook(event) self.assertEqual(model.state, ModelState.RUNNING.value) self.assertEqual(model.version, 2) train_job.state = JobState.STOPPED - db.session.add(train_job) - db.session.commit() self.model_service.k8s_watcher_hook(event) self.assertEqual(model.state, ModelState.PAUSED.value) + db.session.rollback() def test_api(self): resp = self.get_helper('/api/v2/models/1') diff --git a/web_console_v2/api/test/fedlearner_webconsole/project/apis_test.py b/web_console_v2/api/test/fedlearner_webconsole/project/apis_test.py index 48d577064..c91401d73 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/project/apis_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/project/apis_test.py @@ -155,14 +155,18 @@ def test_list_project(self): self.assertEqual(project, result) def test_update_project(self): + updated_name = 'updated name' updated_comment = 'updated comment' update_response = self.patch_helper( '/api/v2/projects/{}'.format(1), data={ + 'participant_name': updated_name, 'comment': updated_comment }) self.assertEqual(update_response.status_code, HTTPStatus.OK) queried_project = Project.query.filter_by(id=1).first() + participant = queried_project.get_config().participants[0] + self.assertEqual(participant.name, updated_name) self.assertEqual(queried_project.comment, updated_comment) def test_update_not_found_project(self): diff --git a/web_console_v2/api/test/fedlearner_webconsole/rpc/client_test.py b/web_console_v2/api/test/fedlearner_webconsole/rpc/client_test.py index 2cc3e9113..b2200e4ea 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/rpc/client_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/rpc/client_test.py @@ -20,14 +20,15 @@ from grpc import StatusCode from grpc.framework.foundation import logging_pool -from testing.common import create_test_db +from testing.common import NoWebServerTestCase from fedlearner_webconsole.proto.service_pb2 import DESCRIPTOR from fedlearner_webconsole.rpc.client import RpcClient from fedlearner_webconsole.project.models import Project as ProjectModel from fedlearner_webconsole.job.models import Job -from fedlearner_webconsole.proto.common_pb2 import (GrpcSpec, Status, StatusCode - as FedLearnerStatusCode) +from fedlearner_webconsole.proto.common_pb2 import (GrpcSpec, Status, + StatusCode as + FedLearnerStatusCode) from fedlearner_webconsole.proto.project_pb2 import Project, Participant from fedlearner_webconsole.proto.service_pb2 import (CheckConnectionRequest, ProjAuthInfo) @@ -37,7 +38,7 @@ TARGET_SERVICE = DESCRIPTOR.services_by_name['WebConsoleV2Service'] -class RpcClientTest(unittest.TestCase): +class RpcClientTest(NoWebServerTestCase): _TEST_PROJECT_NAME = 'test-project' _TEST_RECEIVER_NAME = 'test-receiver' _TEST_URL = 'localhost:123' @@ -46,10 +47,9 @@ class RpcClientTest(unittest.TestCase): _TEST_X_HOST = 'default.fedlearner.webconsole' _TEST_SELF_DOMAIN_NAME = 'fl-test-self.com' - _DB = create_test_db() - @classmethod def setUpClass(cls): + grpc_spec = GrpcSpec( authority=cls._TEST_AUTHORITY, extra_headers={cls._X_HOST_HEADER_KEY: cls._TEST_X_HOST}) @@ -71,16 +71,6 @@ def setUpClass(cls): cls._project.set_config(project_config) cls._job = job - # Inserts the project entity - cls._DB.create_all() - cls._DB.session.add(cls._project) - cls._DB.session.commit() - - @classmethod - def tearDownClass(cls): - cls._DB.session.remove() - cls._DB.drop_all() - def setUp(self): self._client_execution_thread_pool = logging_pool.pool(1) diff --git a/web_console_v2/api/test/fedlearner_webconsole/scheduler/scheduler_test.py b/web_console_v2/api/test/fedlearner_webconsole/scheduler/scheduler_test.py index 57771bded..95caafac4 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/scheduler/scheduler_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/scheduler/scheduler_test.py @@ -22,6 +22,7 @@ import logging from http import HTTPStatus +from envs import Envs from testing.common import BaseTestCase from fedlearner_webconsole.proto.common_pb2 import CreateJobFlag from fedlearner_webconsole.job.models import Job @@ -32,7 +33,7 @@ class LeaderConfig(object): - SQLALCHEMY_DATABASE_URI = 'sqlite://' + SQLALCHEMY_DATABASE_URI = f'sqlite:///{Envs.BASE_DIR}/leader.db' SQLALCHEMY_TRACK_MODIFICATIONS = False JWT_SECRET_KEY = secrets.token_urlsafe(64) PROPAGATE_EXCEPTIONS = True @@ -42,7 +43,7 @@ class LeaderConfig(object): class FollowerConfig(object): - SQLALCHEMY_DATABASE_URI = 'sqlite://' + SQLALCHEMY_DATABASE_URI = f'sqlite:///{Envs.BASE_DIR}/follower.db' SQLALCHEMY_TRACK_MODIFICATIONS = False JWT_SECRET_KEY = secrets.token_urlsafe(64) PROPAGATE_EXCEPTIONS = True @@ -65,6 +66,7 @@ def setUp(self): 'group_alias': 'test-template', 'job_definitions': [{ + 'is_federated': True, 'name': 'job1', 'variables': [{ @@ -73,6 +75,7 @@ def setUp(self): 'access_mode': 3 }] }, { + 'is_federated': True, 'name': 'job2', 'variables': [{ diff --git a/web_console_v2/api/test/fedlearner_webconsole/scheduler/workflow_commit_test.py b/web_console_v2/api/test/fedlearner_webconsole/scheduler/workflow_commit_test.py index fd06d65f9..b94468c09 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/scheduler/workflow_commit_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/scheduler/workflow_commit_test.py @@ -29,6 +29,7 @@ from fedlearner_webconsole.proto import project_pb2 from workflow_template_test import make_workflow_template + class WorkflowsCommitTest(BaseTestCase): class Config(BaseTestCase.Config): START_GRPC_SERVER = False @@ -42,61 +43,56 @@ def setUp(self): super().setUp() # Inserts project config = { - 'participants': [ - { - 'name': 'party_leader', - 'url': '127.0.0.1:5000', - 'domain_name': 'fl-leader.com', - 'grpc_spec': { - 'authority': 'fl-leader.com' - } - } - ], - 'variables': [ - { - 'name': 'namespace', - 'value': 'leader' - }, - { - 'name': 'basic_envs', - 'value': '{}' - }, - { - 'name': 'storage_root_dir', - 'value': '/' - }, - { - 'name': 'EGRESS_URL', - 'value': '127.0.0.1:1991' + 'participants': [{ + 'name': 'party_leader', + 'url': '127.0.0.1:5000', + 'domain_name': 'fl-leader.com', + 'grpc_spec': { + 'authority': 'fl-leader.com' } - ] + }], + 'variables': [{ + 'name': 'namespace', + 'value': 'leader' + }, { + 'name': 'basic_envs', + 'value': '{}' + }, { + 'name': 'storage_root_dir', + 'value': '/' + }, { + 'name': 'EGRESS_URL', + 'value': '127.0.0.1:1991' + }] } - project = Project(name='test', - config=ParseDict(config, - project_pb2.Project()).SerializeToString()) + project = Project( + name='test', + config=ParseDict(config, + project_pb2.Project()).SerializeToString()) db.session.add(project) db.session.commit() @staticmethod - def _wait_until(cond): - while True: - time.sleep(1) + def _wait_until(cond, retry_times: int = 5): + for _ in range(retry_times): + time.sleep(5) + db.session.expire_all() if cond(): return - - @patch('fedlearner_webconsole.workflow.models.Job.is_failed') - @patch('fedlearner_webconsole.workflow.models.Job.is_complete') - def test_workflow_commit(self, mock_is_complete, mock_is_failed): - mock_is_complete.return_value = False - mock_is_failed.return_value = False + def test_workflow_commit(self): # test the committing stage for workflow creating workflow_def = make_workflow_template() - workflow = Workflow(id=20, name='job_test1', comment='这是一个测试工作流', - config=workflow_def.SerializeToString(), - project_id=1, forkable=True, state=WorkflowState.NEW, - target_state=WorkflowState.READY, - transaction_state=TransactionState.PARTICIPANT_COMMITTING) + workflow = Workflow( + id=20, + name='job_test1', + comment='这是一个测试工作流', + config=workflow_def.SerializeToString(), + project_id=1, + forkable=True, + state=WorkflowState.NEW, + target_state=WorkflowState.READY, + transaction_state=TransactionState.PARTICIPANT_COMMITTING) db.session.add(workflow) db.session.commit() scheduler.wakeup(20) @@ -104,8 +100,8 @@ def test_workflow_commit(self, mock_is_complete, mock_is_failed): lambda: Workflow.query.get(20).state == WorkflowState.READY) workflow = Workflow.query.get(20) self.assertEqual(len(workflow.get_jobs()), 2) - self.assertEqual(workflow.get_jobs()[0].state, JobState.STOPPED) - self.assertEqual(workflow.get_jobs()[1].state, JobState.STOPPED) + self.assertEqual(workflow.get_jobs()[0].state, JobState.NEW) + self.assertEqual(workflow.get_jobs()[1].state, JobState.NEW) # test the committing stage for workflow running workflow.target_state = WorkflowState.RUNNING @@ -118,15 +114,17 @@ def test_workflow_commit(self, mock_is_complete, mock_is_failed): self._wait_until( lambda: workflow.get_jobs()[0].state == JobState.STARTED) self.assertEqual(workflow.get_jobs()[1].state, JobState.WAITING) - mock_is_complete.return_value = True workflow = Workflow.query.get(20) + for job in workflow.owned_jobs: + job.state = JobState.COMPLETED self.assertEqual(workflow.to_dict()['state'], 'COMPLETED') - mock_is_complete.return_value = False - mock_is_failed.return_value = True + workflow.get_jobs()[0].state = JobState.FAILED self.assertEqual(workflow.to_dict()['state'], 'FAILED') # test the committing stage for workflow stopping workflow.target_state = WorkflowState.STOPPED workflow.transaction_state = TransactionState.PARTICIPANT_COMMITTING + for job in workflow.owned_jobs: + job.state = JobState.STARTED db.session.commit() scheduler.wakeup(20) self._wait_until( diff --git a/web_console_v2/api/test/fedlearner_webconsole/sparkapp/apis_test.py b/web_console_v2/api/test/fedlearner_webconsole/sparkapp/apis_test.py index 1705677c0..711425562 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/sparkapp/apis_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/sparkapp/apis_test.py @@ -23,8 +23,9 @@ from fedlearner_webconsole.sparkapp.schema import SparkAppInfo from testing.common import BaseTestCase +from envs import Envs -BASE_DIR = os.path.abspath(os.path.join(dirname(__file__), '../../../')) +BASE_DIR = Envs.BASE_DIR class SparkAppApiTest(BaseTestCase): diff --git a/web_console_v2/api/test/fedlearner_webconsole/sparkapp/schema_test.py b/web_console_v2/api/test/fedlearner_webconsole/sparkapp/schema_test.py index 6db23febe..21a0f35ca 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/sparkapp/schema_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/sparkapp/schema_test.py @@ -120,6 +120,27 @@ def test_sparkapp_info(self): }, 'sparkVersion': '3.0.0', 'type': 'Python', + }, + 'status': { + 'applicationState': { + 'state': 'COMPLETED' + }, + 'driverInfo': { + 'podName': 'fl-transformer-yaml-driver', + 'webUIAddress': '11.249.131.12:4040', + 'webUIPort': 4040, + 'webUIServiceName': 'fl-transformer-yaml-ui-svc' + }, + 'executionAttempts': 1, + 'executorState': { + 'fl-transformer-yaml-bdc15979a314310b-exec-1': 'PENDING', + 'fl-transformer-yaml-bdc15979a314310b-exec-2': 'COMPLETED' + }, + 'lastSubmissionAttemptTime': '2021-05-18T10:31:13Z', + 'sparkApplicationId': 'spark-a380bfd520164d828a334bcb3a6404f9', + 'submissionAttempts': 1, + 'submissionID': '5bc7e2e7-cc0f-420c-8bc7-138b651a1dde', + 'terminationTime': '2021-05-18T10:32:08Z' } } diff --git a/web_console_v2/api/test/fedlearner_webconsole/sparkapp/service_test.py b/web_console_v2/api/test/fedlearner_webconsole/sparkapp/service_test.py index 698eed74b..d59b57520 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/sparkapp/service_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/sparkapp/service_test.py @@ -20,11 +20,12 @@ from unittest.mock import MagicMock, patch from os.path import dirname -from fedlearner_webconsole.sparkapp.schema import SparkAppConfig +from envs import Envs +from fedlearner_webconsole.sparkapp.schema import SparkAppConfig from fedlearner_webconsole.sparkapp.service import SparkAppService -BASE_DIR = os.path.abspath(os.path.join(dirname(__file__), '../../../')) +BASE_DIR = Envs.BASE_DIR class SparkAppServiceTest(unittest.TestCase): @@ -124,6 +125,27 @@ def test_submit_sparkapp(self, mock_create_sparkapp: MagicMock): }, 'sparkVersion': '3.0.0', 'type': 'Python', + }, + 'status': { + 'applicationState': { + 'state': 'COMPLETED' + }, + 'driverInfo': { + 'podName': 'fl-transformer-yaml-driver', + 'webUIAddress': '11.249.131.12:4040', + 'webUIPort': 4040, + 'webUIServiceName': 'fl-transformer-yaml-ui-svc' + }, + 'executionAttempts': 1, + 'executorState': { + 'fl-transformer-yaml-bdc15979a314310b-exec-1': 'PENDING', + 'fl-transformer-yaml-bdc15979a314310b-exec-2': 'COMPLETED' + }, + 'lastSubmissionAttemptTime': '2021-05-18T10:31:13Z', + 'sparkApplicationId': 'spark-a380bfd520164d828a334bcb3a6404f9', + 'submissionAttempts': 1, + 'submissionID': '5bc7e2e7-cc0f-420c-8bc7-138b651a1dde', + 'terminationTime': '2021-05-18T10:32:08Z' } } @@ -211,6 +233,27 @@ def test_get_sparkapp_info(self, mock_get_sparkapp: MagicMock): }, 'sparkVersion': '3.0.0', 'type': 'Python', + }, + 'status': { + 'applicationState': { + 'state': 'COMPLETED' + }, + 'driverInfo': { + 'podName': 'fl-transformer-yaml-driver', + 'webUIAddress': '11.249.131.12:4040', + 'webUIPort': 4040, + 'webUIServiceName': 'fl-transformer-yaml-ui-svc' + }, + 'executionAttempts': 1, + 'executorState': { + 'fl-transformer-yaml-bdc15979a314310b-exec-1': 'PENDING', + 'fl-transformer-yaml-bdc15979a314310b-exec-2': 'COMPLETED' + }, + 'lastSubmissionAttemptTime': '2021-05-18T10:31:13Z', + 'sparkApplicationId': 'spark-a380bfd520164d828a334bcb3a6404f9', + 'submissionAttempts': 1, + 'submissionID': '5bc7e2e7-cc0f-420c-8bc7-138b651a1dde', + 'terminationTime': '2021-05-18T10:32:08Z' } } diff --git a/web_console_v2/api/test/fedlearner_webconsole/test_data/dataset_metainfo/_FEATURES b/web_console_v2/api/test/fedlearner_webconsole/test_data/dataset_metainfo/_FEATURES new file mode 100644 index 000000000..c4b56a721 --- /dev/null +++ b/web_console_v2/api/test/fedlearner_webconsole/test_data/dataset_metainfo/_FEATURES @@ -0,0 +1 @@ +{"f00312": {"count": "12089", "mean": "0.0015716767309123998", "stddev": "0.03961485047808605", "min": "0", "max": "1", "missing_count": "0"}, "f00207": {"count": "12089", "mean": "7.969889982628836", "stddev": "6.298925249171136", "min": "0", "max": "17", "missing_count": "0"}, "f00197": {"count": "12089", "mean": "5.790387955993051E-4", "stddev": "0.02405725220983047", "min": "0", "max": "1", "missing_count": "0"}, "f00021": {"count": "12089", "mean": "22.46943502357515", "stddev": "62.78511338652187", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00380": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00129": {"count": "12089", "mean": "127.65687815369344", "stddev": "110.84802347935845", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00009": {"count": "12089", "mean": "50.4625692778559", "stddev": "88.88581381823657", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00333": {"count": "12089", "mean": "8.271982794275788E-5", "stddev": "0.009095044141880672", "min": "0", "max": "1", "missing_count": "0"}, "f00036": {"count": "12089", "mean": "40.138555711804116", "stddev": "81.46548446285466", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00000": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0.0", "max": "0.0", "missing_count": "0"}, "f00135": {"count": "12089", "mean": "26.622549425097194", "stddev": "68.94643988549662", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00213": {"count": "12089", "mean": "7.0170402845562085", "stddev": "6.28331287275781", "min": "0", "max": "17", "missing_count": "0"}, "f00389": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00108": {"count": "12089", "mean": "11.317561419472247", "stddev": "45.850510883253484", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00098": {"count": "12089", "mean": "98.65836711059642", "stddev": "113.51899823220415", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00120": {"count": "12089", "mean": "75.51890148068492", "stddev": "104.405877965072", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00306": {"count": "12089", "mean": "8.271982794275788E-5", "stddev": "0.009095044141880672", "min": "0", "max": "1", "missing_count": "0"}, "f00015": {"count": "12089", "mean": "146.97046902142444", "stddev": "107.57419770880752", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00234": {"count": "12089", "mean": "7.249234841591529", "stddev": "5.960881019889561", "min": "0", "max": "16", "missing_count": "0"}, "f00228": {"count": "12089", "mean": "0.30962031598974277", "stddev": "0.9148967149961357", "min": "0", "max": "4", "missing_count": "0"}, "f00114": {"count": "12089", "mean": "0.8296798742658615", "stddev": "11.826621946672537", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00296": {"count": "12089", "mean": "0.44412275622466707", "stddev": "1.2207702582037445", "min": "0", "max": "5", "missing_count": "0"}, "f00327": {"count": "12089", "mean": "0.004384150880966168", "stddev": "0.06607035037106973", "min": "0", "max": "1", "missing_count": "0"}, "f00315": {"count": "12089", "mean": "0.01091901728844404", "stddev": "0.1039263478660159", "min": "0", "max": "1", "missing_count": "0"}, "f00201": {"count": "12089", "mean": "1.6287534121929026", "stddev": "2.84809905187513", "min": "0", "max": "9", "missing_count": "0"}, "f00170": {"count": "12089", "mean": "1.573579286955083", "stddev": "16.69196932487125", "min": "0.0", "max": "255.0", "missing_count": "0"}, "raw_id": {"count": "12089", "mean": "6044.0", "stddev": "3489.938036699219", "min": "0", "max": "12088", "missing_count": "0"}, "f00278": {"count": "12089", "mean": "1.6543965588551577E-4", "stddev": "0.012861802735756753", "min": "0", "max": "1", "missing_count": "0"}, "f00117": {"count": "12089", "mean": "37.35991397137894", "stddev": "81.07098158275089", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00191": {"count": "12089", "mean": "22.46099760112499", "stddev": "62.86460287162058", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00216": {"count": "12089", "mean": "2.7689635205558774", "stddev": "4.064744417560437", "min": "0", "max": "13", "missing_count": "0"}, "f00185": {"count": "12089", "mean": "136.2555215485152", "stddev": "109.1495475656237", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00071": {"count": "12089", "mean": "115.2010091819009", "stddev": "113.15610412333592", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00284": {"count": "12089", "mean": "0.018198362147406732", "stddev": "0.13367370667048667", "min": "0", "max": "1", "missing_count": "0"}, "f00299": {"count": "12089", "mean": "0.06650674166597734", "stddev": "0.3520912962783987", "min": "0", "max": "2", "missing_count": "0"}, "f00179": {"count": "12089", "mean": "116.24807676400033", "stddev": "112.10561248326009", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00362": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00309": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00018": {"count": "12089", "mean": "121.69418479609563", "stddev": "110.4481389455011", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00383": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00377": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00086": {"count": "12089", "mean": "0.5124493341053851", "stddev": "9.554020953390804", "min": "0.0", "max": "254.0", "missing_count": "0"}, "f00300": {"count": "12089", "mean": "0.018446521631235006", "stddev": "0.13456502272330065", "min": "0", "max": "1", "missing_count": "0"}, "f00290": {"count": "12089", "mean": "0.8305070725452891", "stddev": "1.8063905280636319", "min": "0", "max": "7", "missing_count": "0"}, "f00003": {"count": "12089", "mean": "0.16982380676648193", "stddev": "5.260742308809774", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00092": {"count": "12089", "mean": "64.64372570105054", "stddev": "99.94772315175193", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00102": {"count": "12089", "mean": "124.01604764662089", "stddev": "111.03878118521327", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00344": {"count": "12089", "mean": "3.3087931177103153E-4", "stddev": "0.018187830935519945", "min": "0", "max": "1", "missing_count": "0"}, "f00095": {"count": "12089", "mean": "84.91827280999256", "stddev": "108.35978233028061", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00365": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00068": {"count": "12089", "mean": "101.33484986351229", "stddev": "110.4669075685077", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00272": {"count": "12089", "mean": "0.29133923401439327", "stddev": "0.9105375835637824", "min": "0", "max": "4", "missing_count": "0"}, "f00167": {"count": "12089", "mean": "0.020597237157746712", "stddev": "1.6019271796631058", "min": "0.0", "max": "128.0", "missing_count": "0"}, "f00371": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00194": {"count": "12089", "mean": "0.4916039374638101", "stddev": "8.90504079934277", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00080": {"count": "12089", "mean": "7.424269997518405", "stddev": "37.33719005251688", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00074": {"count": "12089", "mean": "122.3101166349574", "stddev": "111.195396244587", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00089": {"count": "12089", "mean": "24.765985606749936", "stddev": "66.94669354107191", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00293": {"count": "12089", "mean": "1.0765985606749937", "stddev": "2.2088405666718938", "min": "0", "max": "8", "missing_count": "0"}, "f00287": {"count": "12089", "mean": "0.2876995615849119", "stddev": "0.9106955529735481", "min": "0", "max": "4", "missing_count": "0"}, "f00152": {"count": "12089", "mean": "96.18181818181819", "stddev": "112.25217366871706", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00188": {"count": "12089", "mean": "85.78013069732815", "stddev": "106.30064004700931", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00251": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00350": {"count": "12089", "mean": "0.0010753577632558525", "stddev": "0.03277636700490423", "min": "0", "max": "1", "missing_count": "0"}, "f00173": {"count": "12089", "mean": "52.889486309868474", "stddev": "93.34585106719244", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00053": {"count": "12089", "mean": "2.0326743320373892", "stddev": "19.627575883927236", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00359": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00266": {"count": "12089", "mean": "3.797419141368186", "stddev": "4.630854277554116", "min": "0", "max": "13", "missing_count": "0"}, "f00386": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00353": {"count": "12089", "mean": "8.271982794275787E-4", "stddev": "0.028750346035965654", "min": "0", "max": "1", "missing_count": "0"}, "f00062": {"count": "12089", "mean": "25.966333030027297", "stddev": "68.53716697947962", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00248": {"count": "12089", "mean": "0.030854495822648688", "stddev": "0.1729305341578591", "min": "0", "max": "1", "missing_count": "0"}, "f00275": {"count": "12089", "mean": "0.023078831996029447", "stddev": "0.15016013013366547", "min": "0", "max": "1", "missing_count": "0"}, "f00347": {"count": "12089", "mean": "9.099181073703367E-4", "stddev": "0.030152369101126467", "min": "0", "max": "1", "missing_count": "0"}, "f00326": {"count": "12089", "mean": "0.0076102241707337245", "stddev": "0.08690761437388105", "min": "0", "max": "1", "missing_count": "0"}, "f00374": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00233": {"count": "12089", "mean": "7.51261477376127", "stddev": "6.336175108889156", "min": "0", "max": "17", "missing_count": "0"}, "f00077": {"count": "12089", "mean": "42.78674828356357", "stddev": "84.18417527697498", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00332": {"count": "12089", "mean": "8.271982794275788E-5", "stddev": "0.009095044141880672", "min": "0", "max": "1", "missing_count": "0"}, "f00155": {"count": "12089", "mean": "109.07047729340724", "stddev": "110.81584969724295", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00035": {"count": "12089", "mean": "24.930846223839854", "stddev": "66.37760252845683", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00161": {"count": "12089", "mean": "69.5351145669617", "stddev": "101.00911072125321", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00056": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0.0", "max": "0.0", "missing_count": "0"}, "f00083": {"count": "12089", "mean": "0.059144676979071886", "stddev": "3.061344888196", "min": "0.0", "max": "223.0", "missing_count": "0"}, "f00269": {"count": "12089", "mean": "1.6582016709405245", "stddev": "2.929709427278822", "min": "0", "max": "10", "missing_count": "0"}, "f00134": {"count": "12089", "mean": "43.70609645131938", "stddev": "85.1577461190761", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00182": {"count": "12089", "mean": "112.46033584250145", "stddev": "110.37074173570745", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00041": {"count": "12089", "mean": "122.2917528331541", "stddev": "110.3844621437854", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00368": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00176": {"count": "12089", "mean": "116.19058648358012", "stddev": "111.5950606075992", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00140": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0.0", "max": "0.0", "missing_count": "0"}, "f00260": {"count": "12089", "mean": "2.6654810157994873", "stddev": "3.8407366321952625", "min": "0", "max": "12", "missing_count": "0"}, "f00281": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00254": {"count": "12089", "mean": "0.004053271569195136", "stddev": "0.06353877960213003", "min": "0", "max": "1", "missing_count": "0"}, "f00149": {"count": "12089", "mean": "97.22565969062785", "stddev": "110.34982443353475", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00023": {"count": "12089", "mean": "4.017950202663578", "stddev": "26.91164598600779", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00158": {"count": "12089", "mean": "135.2027462982877", "stddev": "109.24927327835356", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00017": {"count": "12089", "mean": "143.10224170733724", "stddev": "107.52214831526439", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00050": {"count": "12089", "mean": "15.526759864339482", "stddev": "52.80830936027394", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00236": {"count": "12089", "mean": "7.231698238067665", "stddev": "5.998910757868576", "min": "0", "max": "16", "missing_count": "0"}, "f00143": {"count": "12089", "mean": "9.34130201009182", "stddev": "41.454427254989774", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00044": {"count": "12089", "mean": "135.7823641326826", "stddev": "109.00787635707023", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00038": {"count": "12089", "mean": "81.47365373480024", "stddev": "104.10037134701264", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00242": {"count": "12089", "mean": "3.188849367193316", "stddev": "4.430056635612022", "min": "0", "max": "13", "missing_count": "0"}, "f00116": {"count": "12089", "mean": "19.636032757051865", "stddev": "60.33937808755006", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00137": {"count": "12089", "mean": "5.4586814459425925", "stddev": "31.331337049123192", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00257": {"count": "12089", "mean": "0.3081313590867731", "stddev": "0.9153993013019526", "min": "0", "max": "4", "missing_count": "0"}, "f00320": {"count": "12089", "mean": "0.06278434940855324", "stddev": "0.3479336134540428", "min": "0", "max": "2", "missing_count": "0"}, "f00164": {"count": "12089", "mean": "13.817271900074449", "stddev": "49.910045947034355", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00215": {"count": "12089", "mean": "3.963685995533129", "stddev": "4.840533295725966", "min": "0", "max": "14", "missing_count": "0"}, "f00308": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00122": {"count": "12089", "mean": "82.65232856315659", "stddev": "108.00734853519677", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00341": {"count": "12089", "mean": "1.6543965588551577E-4", "stddev": "0.012861802735756756", "min": "0", "max": "1", "missing_count": "0"}, "f00335": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00329": {"count": "12089", "mean": "9.099181073703367E-4", "stddev": "0.03015236910112646", "min": "0", "max": "1", "missing_count": "0"}, "f00221": {"count": "12089", "mean": "0.018363801803292248", "stddev": "0.1342686257655253", "min": "0", "max": "1", "missing_count": "0"}, "f00356": {"count": "12089", "mean": "2.4815948382827364E-4", "stddev": "0.015751775297162093", "min": "0", "max": "1", "missing_count": "0"}, "f00059": {"count": "12089", "mean": "1.670609645131938", "stddev": "16.617605185022406", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00065": {"count": "12089", "mean": "67.83968897344694", "stddev": "99.88982320561412", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00314": {"count": "12089", "mean": "0.006783025891306146", "stddev": "0.08208272523502139", "min": "0", "max": "1", "missing_count": "0"}, "f00263": {"count": "12089", "mean": "4.683017619323352", "stddev": "5.112106252543775", "min": "0", "max": "14", "missing_count": "0"}, "f00323": {"count": "12089", "mean": "0.021672594921002566", "stddev": "0.14561815681841794", "min": "0", "max": "1", "missing_count": "0"}, "f00203": {"count": "12089", "mean": "5.274712548597899", "stddev": "5.491439999810407", "min": "0", "max": "15", "missing_count": "0"}, "f00026": {"count": "12089", "mean": "0.39308462238398545", "stddev": "7.996566426227542", "min": "0.0", "max": "254.0", "missing_count": "0"}, "f00391": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00125": {"count": "12089", "mean": "91.59459012325254", "stddev": "112.05550695302972", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00032": {"count": "12089", "mean": "2.2057242120936387", "stddev": "19.17599219583217", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00193": {"count": "12089", "mean": "3.351311109272893", "stddev": "23.793676933625665", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00047": {"count": "12089", "mean": "93.57473736454628", "stddev": "107.85198969607525", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00110": {"count": "12089", "mean": "0.9364711721399619", "stddev": "12.433034422804973", "min": "0.0", "max": "253.0", "missing_count": "0"}, "f00245": {"count": "12089", "mean": "0.6315658863429564", "stddev": "1.5311403179365195", "min": "0", "max": "6", "missing_count": "0"}, "f00146": {"count": "12089", "mean": "69.49028042021672", "stddev": "101.90158284684969", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00005": {"count": "12089", "mean": "2.562742989494582", "stddev": "20.401310971721", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00104": {"count": "12089", "mean": "81.10786665563735", "stddev": "104.36877459445203", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00218": {"count": "12089", "mean": "0.8396889734469353", "stddev": "1.8901700948075482", "min": "0", "max": "7", "missing_count": "0"}, "f00131": {"count": "12089", "mean": "116.78550748614443", "stddev": "109.83853395976982", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00317": {"count": "12089", "mean": "0.02109355612540326", "stddev": "0.1437022136462013", "min": "0", "max": "1", "missing_count": "0"}, "f00224": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00230": {"count": "12089", "mean": "2.335842501447597", "stddev": "3.590911567257245", "min": "0", "max": "11", "missing_count": "0"}, "f00239": {"count": "12089", "mean": "5.6979071883530485", "stddev": "5.581541304147346", "min": "0", "max": "15", "missing_count": "0"}, "f00094": {"count": "12089", "mean": "77.82893539581438", "stddev": "105.52048530589909", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00119": {"count": "12089", "mean": "68.77905533956489", "stddev": "101.61313020983097", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00302": {"count": "12089", "mean": "0.006038547439821325", "stddev": "0.0774763184270929", "min": "0", "max": "1", "missing_count": "0"}, "f00292": {"count": "12089", "mean": "1.0894201340061214", "stddev": "2.213914558722607", "min": "0", "max": "8", "missing_count": "0"}, "f00011": {"count": "12089", "mean": "100.26718504425511", "stddev": "109.47690624367854", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00338": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00020": {"count": "12089", "mean": "48.47075854082224", "stddev": "87.6721375293745", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00175": {"count": "12089", "mean": "100.43262470014062", "stddev": "110.3676589106749", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00206": {"count": "12089", "mean": "8.096451319381256", "stddev": "6.449682666545672", "min": "0", "max": "18", "missing_count": "0"}, "f00029": {"count": "12089", "mean": "0.01869468111506328", "stddev": "2.05547997606503", "min": "0.0", "max": "226.0", "missing_count": "0"}, "f00274": {"count": "12089", "mean": "0.07279344858962693", "stddev": "0.3603832071918777", "min": "0", "max": "2", "missing_count": "0"}, "f00128": {"count": "12089", "mean": "114.94449499545041", "stddev": "112.13157547309869", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00373": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00196": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00295": {"count": "12089", "mean": "0.6386797915460336", "stddev": "1.546000832656912", "min": "0", "max": "6", "missing_count": "0"}, "f00305": {"count": "12089", "mean": "4.135991397137894E-4", "stddev": "0.020333771833917866", "min": "0", "max": "1", "missing_count": "0"}, "f00289": {"count": "12089", "mean": "0.6302423690958723", "stddev": "1.4983772214095004", "min": "0", "max": "6", "missing_count": "0"}, "f00212": {"count": "12089", "mean": "6.817271900074448", "stddev": "5.974489070884012", "min": "0", "max": "16", "missing_count": "0"}, "f00181": {"count": "12089", "mean": "109.2416246174208", "stddev": "110.54913441390448", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00076": {"count": "12089", "mean": "70.24402349243114", "stddev": "100.58430391863487", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00280": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00014": {"count": "12089", "mean": "140.2613946562991", "stddev": "109.92329691158204", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00388": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00227": {"count": "12089", "mean": "0.07750847878236414", "stddev": "0.36544744196793927", "min": "0", "max": "2", "missing_count": "0"}, "f00082": {"count": "12089", "mean": "0.8301761932335181", "stddev": "11.676183114704884", "min": "0.0", "max": "254.0", "missing_count": "0"}, "f00008": {"count": "12089", "mean": "28.923153279841177", "stddev": "70.18855997812747", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00113": {"count": "12089", "mean": "0.020928116469517744", "stddev": "1.8185770446835063", "min": "0.0", "max": "197.0", "missing_count": "0"}, "f00107": {"count": "12089", "mean": "20.359665811895113", "stddev": "60.86079945589884", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00097": {"count": "12089", "mean": "95.71230043841508", "stddev": "112.9203359237509", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00311": {"count": "12089", "mean": "3.3087931177103153E-4", "stddev": "0.018187830935519955", "min": "0", "max": "1", "missing_count": "0"}, "f00184": {"count": "12089", "mean": "132.06774753908513", "stddev": "109.61468807022078", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00079": {"count": "12089", "mean": "13.677309951195301", "stddev": "50.07519014387303", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00101": {"count": "12089", "mean": "122.54561998511043", "stddev": "111.69458255685223", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00002": {"count": "12089", "mean": "0.007527504342790967", "stddev": "0.6438064000663923", "min": "0.0", "max": "69.0", "missing_count": "0"}, "f00070": {"count": "12089", "mean": "111.54016047646621", "stddev": "112.96571914608131", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00064": {"count": "12089", "mean": "53.12217718587145", "stddev": "92.07991097584222", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00209": {"count": "12089", "mean": "7.506162627181736", "stddev": "6.335218435677862", "min": "0", "max": "17", "missing_count": "0"}, "f00283": {"count": "12089", "mean": "0.00703118537513442", "stddev": "0.08356030986125715", "min": "0", "max": "1", "missing_count": "0"}, "f00277": {"count": "12089", "mean": "0.002233435354454463", "stddev": "0.047208383503186485", "min": "0", "max": "1", "missing_count": "0"}, "f00091": {"count": "12089", "mean": "54.057821159731986", "stddev": "93.49125294106308", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00163": {"count": "12089", "mean": "27.330465712631316", "stddev": "69.49360582065684", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00058": {"count": "12089", "mean": "0.32682604020183637", "stddev": "7.428200945373068", "min": "0.0", "max": "254.0", "missing_count": "0"}, "f00190": {"count": "12089", "mean": "39.01877740094301", "stddev": "80.64309515978327", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00200": {"count": "12089", "mean": "0.6344610803209529", "stddev": "1.5439106575916022", "min": "0", "max": "6", "missing_count": "0"}, "f00376": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00199": {"count": "12089", "mean": "0.16171726362809166", "stddev": "0.6209476669547512", "min": "0", "max": "3", "missing_count": "0"}, "f00085": {"count": "12089", "mean": "0.02034907767391844", "stddev": "1.4125452537479488", "min": "0.0", "max": "133.0", "missing_count": "0"}, "f00298": {"count": "12089", "mean": "0.09305980643560262", "stddev": "0.38333800268403145", "min": "0", "max": "2", "missing_count": "0"}, "f00157": {"count": "12089", "mean": "135.45338737695425", "stddev": "109.17069463834251", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00361": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00256": {"count": "12089", "mean": "0.09256348746794607", "stddev": "0.3823779459828604", "min": "0", "max": "2", "missing_count": "0"}, "f00262": {"count": "12089", "mean": "4.334270824716684", "stddev": "4.9958968239833395", "min": "0", "max": "14", "missing_count": "0"}, "f00355": {"count": "12089", "mean": "4.135991397137894E-4", "stddev": "0.020333771833917845", "min": "0", "max": "1", "missing_count": "0"}, "f00178": {"count": "12089", "mean": "120.58689717925387", "stddev": "112.42989836060832", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00382": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00364": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00358": {"count": "12089", "mean": "8.271982794275788E-5", "stddev": "0.009095044141880676", "min": "0", "max": "1", "missing_count": "0"}, "f00067": {"count": "12089", "mean": "92.11828935395815", "stddev": "107.880515215011", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00271": {"count": "12089", "mean": "0.4656299114897841", "stddev": "1.2226481099427282", "min": "0", "max": "5", "missing_count": "0"}, "f00286": {"count": "12089", "mean": "0.15824303085449581", "stddev": "0.616900267416377", "min": "0", "max": "3", "missing_count": "0"}, "f00244": {"count": "12089", "mean": "1.0981884357680536", "stddev": "2.2035418049877964", "min": "0", "max": "8", "missing_count": "0"}, "f00379": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00337": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00151": {"count": "12089", "mean": "96.78128877491935", "stddev": "111.93369626697235", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00259": {"count": "12089", "mean": "1.6998097443957316", "stddev": "2.9808512186328775", "min": "0", "max": "10", "missing_count": "0"}, "f00073": {"count": "12089", "mean": "126.48788154520639", "stddev": "110.94063872421407", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00172": {"count": "12089", "mean": "29.05037637521714", "stddev": "72.62815547455598", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00166": {"count": "12089", "mean": "0.6783025891306146", "stddev": "10.775627874334255", "min": "0.0", "max": "253.0", "missing_count": "0"}, "f00385": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00088": {"count": "12089", "mean": "11.935892133344362", "stddev": "47.22589878357941", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00139": {"count": "12089", "mean": "0.04020183638018033", "stddev": "2.305908122408037", "min": "0.0", "max": "153.0", "missing_count": "0"}, "f00343": {"count": "12089", "mean": "2.4815948382827364E-4", "stddev": "0.0157517752971621", "min": "0", "max": "1", "missing_count": "0"}, "f00052": {"count": "12089", "mean": "4.207378608652494", "stddev": "28.074171257801822", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00046": {"count": "12089", "mean": "122.67954338654975", "stddev": "110.99635048312369", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00187": {"count": "12089", "mean": "110.35875589378774", "stddev": "110.55640335116942", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00238": {"count": "12089", "mean": "6.148316651501365", "stddev": "5.678318834411271", "min": "0", "max": "15", "missing_count": "0"}, "f00250": {"count": "12089", "mean": "9.099181073703367E-4", "stddev": "0.030152369101126463", "min": "0", "max": "1", "missing_count": "0"}, "f00370": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00265": {"count": "12089", "mean": "4.134006121267268", "stddev": "4.719032514814078", "min": "0", "max": "13", "missing_count": "0"}, "f00145": {"count": "12089", "mean": "48.23409711307801", "stddev": "90.33569256677949", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00028": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0.0", "max": "0.0", "missing_count": "0"}, "f00169": {"count": "12089", "mean": "0.061295392505583586", "stddev": "3.047245179854696", "min": "0.0", "max": "185.0", "missing_count": "0"}, "f00232": {"count": "12089", "mean": "5.942426999751841", "stddev": "5.896385905213651", "min": "0", "max": "16", "missing_count": "0"}, "f00352": {"count": "12089", "mean": "9.926379353130945E-4", "stddev": "0.03149181864169439", "min": "0", "max": "1", "missing_count": "0"}, "f00127": {"count": "12089", "mean": "101.6755728348085", "stddev": "112.17723446501321", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00055": {"count": "12089", "mean": "0.05327156919513607", "stddev": "2.648309231570656", "min": "0.0", "max": "190.0", "missing_count": "0"}, "f00310": {"count": "12089", "mean": "1.6543965588551577E-4", "stddev": "0.012861802735756758", "min": "0", "max": "1", "missing_count": "0"}, "f00154": {"count": "12089", "mean": "99.49805608404334", "stddev": "110.42238643156286", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00049": {"count": "12089", "mean": "31.03631400446687", "stddev": "73.15778023500965", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00253": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00367": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00331": {"count": "12089", "mean": "8.271982794275788E-5", "stddev": "0.009095044141880676", "min": "0", "max": "1", "missing_count": "0"}, "f00325": {"count": "12089", "mean": "0.012573413847299198", "stddev": "0.11142867759187992", "min": "0", "max": "1", "missing_count": "0"}, "f00034": {"count": "12089", "mean": "13.855571180411944", "stddev": "49.713397507452996", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00247": {"count": "12089", "mean": "0.1573331127471255", "stddev": "0.6182713526833413", "min": "0", "max": "3", "missing_count": "0"}, "f00319": {"count": "12089", "mean": "0.029944577715278354", "stddev": "0.17044149441025006", "min": "0", "max": "1", "missing_count": "0"}, "f00160": {"count": "12089", "mean": "94.73463479195964", "stddev": "108.36629716102476", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00346": {"count": "12089", "mean": "8.271982794275787E-4", "stddev": "0.02875034603596567", "min": "0", "max": "1", "missing_count": "0"}, "f00040": {"count": "12089", "mean": "113.14327074199686", "stddev": "109.84226245861849", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00148": {"count": "12089", "mean": "93.87616841756969", "stddev": "109.01563028272538", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00226": {"count": "12089", "mean": "0.008437422450161304", "stddev": "0.09147089407626231", "min": "0", "max": "1", "missing_count": "0"}, "f00061": {"count": "12089", "mean": "14.143188022168914", "stddev": "50.65214934645993", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00268": {"count": "12089", "mean": "2.3289767557283483", "stddev": "3.5853110900424756", "min": "0", "max": "11", "missing_count": "0"}, "f00133": {"count": "12089", "mean": "65.5060799073538", "stddev": "99.12986246813963", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00022": {"count": "12089", "mean": "8.979650922326082", "stddev": "39.77712456709073", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00142": {"count": "12089", "mean": "1.3251716436429812", "stddev": "15.47932255385905", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00037": {"count": "12089", "mean": "59.9388700471503", "stddev": "94.72699453234434", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00241": {"count": "12089", "mean": "4.451567540739515", "stddev": "5.214539351483691", "min": "0", "max": "15", "missing_count": "0"}, "f00334": {"count": "12089", "mean": "8.271982794275788E-5", "stddev": "0.009095044141880672", "min": "0", "max": "1", "missing_count": "0"}, "f00229": {"count": "12089", "mean": "1.086442220200182", "stddev": "2.2141075688107272", "min": "0", "max": "8", "missing_count": "0"}, "f00043": {"count": "12089", "mean": "132.4968152866242", "stddev": "109.93326299918938", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00121": {"count": "12089", "mean": "78.94383323682686", "stddev": "105.7465897141154", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00001": {"count": "12089", "mean": "0.01323517247084126", "stddev": "1.057570263408246", "min": "0.0", "max": "99.0", "missing_count": "0"}, "f00115": {"count": "12089", "mean": "6.736785507486144", "stddev": "34.6562065366746", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00307": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00016": {"count": "12089", "mean": "149.63578459756803", "stddev": "106.31345045889744", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00220": {"count": "12089", "mean": "0.0876002977913806", "stddev": "0.3770193023195932", "min": "0", "max": "2", "missing_count": "0"}, "f00214": {"count": "12089", "mean": "5.902638762511374", "stddev": "5.87517974874268", "min": "0", "max": "16", "missing_count": "0"}, "f00109": {"count": "12089", "mean": "5.193977996525767", "stddev": "30.916493868435143", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00328": {"count": "12089", "mean": "0.0023988750103399784", "stddev": "0.048921553367709744", "min": "0", "max": "1", "missing_count": "0"}, "f00136": {"count": "12089", "mean": "14.2381503846472", "stddev": "50.832117307731565", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00340": {"count": "12089", "mean": "8.271982794275788E-5", "stddev": "0.009095044141880667", "min": "0", "max": "1", "missing_count": "0"}, "f00349": {"count": "12089", "mean": "9.926379353130945E-4", "stddev": "0.031491818641694355", "min": "0", "max": "1", "missing_count": "0"}, "f00100": {"count": "12089", "mean": "111.91397137893954", "stddev": "112.72662611143275", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00235": {"count": "12089", "mean": "7.245016130366449", "stddev": "5.975173808089956", "min": "0", "max": "16", "missing_count": "0"}, "f00313": {"count": "12089", "mean": "0.003556952601538589", "stddev": "0.05953649215335385", "min": "0", "max": "1", "missing_count": "0"}, "f00208": {"count": "12089", "mean": "7.521631235007031", "stddev": "6.319573669900177", "min": "0", "max": "17", "missing_count": "0"}, "f00186": {"count": "12089", "mean": "129.9644304739846", "stddev": "109.8452037535058", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00217": {"count": "12089", "mean": "1.6715195632393085", "stddev": "2.9719709285257014", "min": "0", "max": "10", "missing_count": "0"}, "f00025": {"count": "12089", "mean": "1.1352469186864091", "stddev": "14.074838590340523", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00390": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00384": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00093": {"count": "12089", "mean": "71.79386218876665", "stddev": "103.22560088342621", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00285": {"count": "12089", "mean": "0.06733393994540492", "stddev": "0.35404327285513265", "min": "0", "max": "2", "missing_count": "0"}, "f00103": {"count": "12089", "mean": "108.62867069236496", "stddev": "109.98131124810823", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00202": {"count": "12089", "mean": "3.416080734552072", "stddev": "4.423602482890862", "min": "0", "max": "13", "missing_count": "0"}, "f00192": {"count": "12089", "mean": "11.229299363057326", "stddev": "44.94778055349097", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00031": {"count": "12089", "mean": "0.5988088344776243", "stddev": "9.70173242684006", "min": "0.0", "max": "254.0", "missing_count": "0"}, "f00124": {"count": "12089", "mean": "88.7223922574241", "stddev": "111.03041701868655", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00130": {"count": "12089", "mean": "130.69021424435437", "stddev": "110.07541968527855", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00019": {"count": "12089", "mean": "85.66663909339069", "stddev": "105.4276935007043", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00087": {"count": "12089", "mean": "3.809744395731657", "stddev": "25.920786926965643", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00301": {"count": "12089", "mean": "0.009926379353130945", "stddev": "0.09913959537480871", "min": "0", "max": "1", "missing_count": "0"}, "f00010": {"count": "12089", "mean": "76.15460335842502", "stddev": "102.68836546035861", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00004": {"count": "12089", "mean": "0.7785590205972371", "stddev": "10.986462860696165", "min": "0.0", "max": "254.0", "missing_count": "0"}, "f00223": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00118": {"count": "12089", "mean": "55.26817768219042", "stddev": "94.35202600920245", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00291": {"count": "12089", "mean": "1.07858383654562", "stddev": "2.198672689278667", "min": "0", "max": "8", "missing_count": "0"}, "f00322": {"count": "12089", "mean": "0.026966663909339068", "stddev": "0.1619926962870867", "min": "0", "max": "1", "missing_count": "0"}, "f00316": {"count": "12089", "mean": "0.015551327653238481", "stddev": "0.12373661690904557", "min": "0", "max": "1", "missing_count": "0"}, "f00013": {"count": "12089", "mean": "131.31838861775168", "stddev": "110.71027810705532", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00189": {"count": "12089", "mean": "61.11332616428158", "stddev": "96.67351803163615", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00195": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0.0", "max": "0.0", "missing_count": "0"}, "f00112": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0.0", "max": "0.0", "missing_count": "0"}, "f00081": {"count": "12089", "mean": "3.595913640499628", "stddev": "25.670929304588366", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00007": {"count": "12089", "mean": "14.629415170816445", "stddev": "50.59485801451282", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00211": {"count": "12089", "mean": "6.821904210439242", "stddev": "5.978061865979983", "min": "0", "max": "16", "missing_count": "0"}, "f00180": {"count": "12089", "mean": "111.31235007031185", "stddev": "111.11268456059636", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00366": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00075": {"count": "12089", "mean": "100.55488460584002", "stddev": "109.45989244366011", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00069": {"count": "12089", "mean": "107.7127140375548", "stddev": "112.3468540877581", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00288": {"count": "12089", "mean": "0.4475969889982629", "stddev": "1.2037283759312305", "min": "0", "max": "5", "missing_count": "0"}, "f00174": {"count": "12089", "mean": "78.69972702456779", "stddev": "105.22183163444049", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00387": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00205": {"count": "12089", "mean": "8.0", "stddev": "6.331562444720613", "min": "0", "max": "17", "missing_count": "0"}, "f00060": {"count": "12089", "mean": "5.7965919430887585", "stddev": "32.18877971708031", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00304": {"count": "12089", "mean": "0.0015716767309123998", "stddev": "0.03961485047808601", "min": "0", "max": "1", "missing_count": "0"}, "f00273": {"count": "12089", "mean": "0.15973198775746547", "stddev": "0.6187933067584905", "min": "0", "max": "3", "missing_count": "0"}, "f00294": {"count": "12089", "mean": "0.8423360079411035", "stddev": "1.8570588236371768", "min": "0", "max": "7", "missing_count": "0"}, "f00168": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0.0", "max": "0.0", "missing_count": "0"}, "f00372": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00267": {"count": "12089", "mean": "3.1091074530564975", "stddev": "4.261348449492594", "min": "0", "max": "13", "missing_count": "0"}, "f00106": {"count": "12089", "mean": "34.45950864422202", "stddev": "76.81328321940498", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00096": {"count": "12089", "mean": "90.9721234179833", "stddev": "111.33220332628122", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00360": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00369": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00183": {"count": "12089", "mean": "120.96525767226404", "stddev": "110.18288051322584", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00141": {"count": "12089", "mean": "0.033005211349160395", "stddev": "1.9509163733029178", "min": "0.0", "max": "166.0", "missing_count": "0"}, "f00090": {"count": "12089", "mean": "40.18032922491521", "stddev": "83.35755041571151", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00354": {"count": "12089", "mean": "5.790387955993051E-4", "stddev": "0.024057252209830484", "min": "0", "max": "1", "missing_count": "0"}, "f00249": {"count": "12089", "mean": "0.009512780213417156", "stddev": "0.09707248168499928", "min": "0", "max": "1", "missing_count": "0"}, "f00084": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0.0", "max": "0.0", "missing_count": "0"}, "f00063": {"count": "12089", "mean": "38.99966912068823", "stddev": "82.02909344030543", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00198": {"count": "12089", "mean": "0.01166349573992886", "stddev": "0.10737044395610035", "min": "0", "max": "1", "missing_count": "0"}, "f00297": {"count": "12089", "mean": "0.18661593183886177", "stddev": "0.6334876659516991", "min": "0", "max": "3", "missing_count": "0"}, "f00156": {"count": "12089", "mean": "123.76226321449252", "stddev": "110.6793588639301", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00255": {"count": "12089", "mean": "0.02291339234014393", "stddev": "0.14963362224724616", "min": "0", "max": "1", "missing_count": "0"}, "f00078": {"count": "12089", "mean": "24.413847299197617", "stddev": "66.22492190582788", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00282": {"count": "12089", "mean": "0.0010753577632558525", "stddev": "0.032776367004904286", "min": "0", "max": "1", "missing_count": "0"}, "f00177": {"count": "12089", "mean": "122.51269749358922", "stddev": "111.89599689676162", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00042": {"count": "12089", "mean": "128.07585408222351", "stddev": "110.366261006918", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00381": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00240": {"count": "12089", "mean": "5.473571014972289", "stddev": "5.788460172878884", "min": "0", "max": "16", "missing_count": "0"}, "f00276": {"count": "12089", "mean": "0.009264620729588882", "stddev": "0.0958099517944918", "min": "0", "max": "1", "missing_count": "0"}, "f00099": {"count": "12089", "mean": "103.48225659690628", "stddev": "113.22365623216328", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00162": {"count": "12089", "mean": "46.30143105302341", "stddev": "87.10377794599654", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00348": {"count": "12089", "mean": "0.0012407974191413682", "stddev": "0.03520455028234003", "min": "0", "max": "1", "missing_count": "0"}, "f00057": {"count": "12089", "mean": "0.01646124576060882", "stddev": "1.2833803824909489", "min": "0.0", "max": "107.0", "missing_count": "0"}, "f00261": {"count": "12089", "mean": "3.9408553230209282", "stddev": "4.861386978193615", "min": "0", "max": "14", "missing_count": "0"}, "f00375": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00039": {"count": "12089", "mean": "99.77177599470593", "stddev": "108.31829419146803", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00237": {"count": "12089", "mean": "6.5093059806435605", "stddev": "5.6578573995671455", "min": "0", "max": "15", "missing_count": "0"}, "f00051": {"count": "12089", "mean": "7.6584498304243525", "stddev": "37.189378357535595", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00243": {"count": "12089", "mean": "2.0367276036065847", "stddev": "3.369183505988024", "min": "0", "max": "11", "missing_count": "0"}, "f00357": {"count": "12089", "mean": "1.6543965588551577E-4", "stddev": "0.012861802735756751", "min": "0", "max": "1", "missing_count": "0"}, "f00150": {"count": "12089", "mean": "97.63123500703118", "stddev": "111.40678708057216", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00270": {"count": "12089", "mean": "0.8702953097857556", "stddev": "1.8930413308456493", "min": "0", "max": "7", "missing_count": "0"}, "f00024": {"count": "12089", "mean": "2.2891885184878817", "stddev": "20.550395266526383", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00165": {"count": "12089", "mean": "4.835552982049798", "stddev": "29.151866610566092", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00159": {"count": "12089", "mean": "119.84432128381172", "stddev": "109.38668553919553", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00363": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00258": {"count": "12089", "mean": "0.8446521631235007", "stddev": "1.8386759859743027", "min": "0", "max": "7", "missing_count": "0"}, "f00123": {"count": "12089", "mean": "85.5991397137894", "stddev": "109.8586042350572", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00378": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00321": {"count": "12089", "mean": "0.06253618992472496", "stddev": "0.34809715324227564", "min": "0", "max": "2", "missing_count": "0"}, "f00336": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00342": {"count": "12089", "mean": "1.6543965588551577E-4", "stddev": "0.012861802735756756", "min": "0", "max": "1", "missing_count": "0"}, "f00045": {"count": "12089", "mean": "136.13441972040698", "stddev": "109.50079499209558", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00264": {"count": "12089", "mean": "4.694102076267681", "stddev": "5.135851246319809", "min": "0", "max": "14", "missing_count": "0"}, "f00072": {"count": "12089", "mean": "120.74977252047316", "stddev": "112.17942783302091", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00171": {"count": "12089", "mean": "10.538754239391181", "stddev": "43.87517272978043", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00222": {"count": "12089", "mean": "0.00272975432211101", "stddev": "0.05217784942384286", "min": "0", "max": "1", "missing_count": "0"}, "f00030": {"count": "12089", "mean": "0.10141450905782116", "stddev": "3.6217098742574323", "min": "0.0", "max": "254.0", "missing_count": "0"}, "f00066": {"count": "12089", "mean": "80.45983952353379", "stddev": "104.43754476777885", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00138": {"count": "12089", "mean": "0.6825213003556952", "stddev": "10.372143610013369", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00144": {"count": "12089", "mean": "26.195963272396394", "stddev": "68.96982859941298", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00279": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00153": {"count": "12089", "mean": "96.34485896269335", "stddev": "111.13053348852189", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00012": {"count": "12089", "mean": "118.59442468359666", "stddev": "111.38255919311455", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00111": {"count": "12089", "mean": "0.03391512945653073", "stddev": "1.5822396665547114", "min": "0.0", "max": "102.0", "missing_count": "0"}, "f00027": {"count": "12089", "mean": "0.011001737116386797", "stddev": "0.7069626758862559", "min": "0.0", "max": "52.0", "missing_count": "0"}, "f00033": {"count": "12089", "mean": "6.480602200347423", "stddev": "33.72465553421396", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00147": {"count": "12089", "mean": "85.32881131607246", "stddev": "107.40750641089546", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00246": {"count": "12089", "mean": "0.2963851435189015", "stddev": "0.9128581829116996", "min": "0", "max": "4", "missing_count": "0"}, "f00132": {"count": "12089", "mean": "90.81727190007445", "stddev": "107.22421003303963", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00345": {"count": "12089", "mean": "4.135991397137894E-4", "stddev": "0.02033377183391784", "min": "0", "max": "1", "missing_count": "0"}, "f00204": {"count": "12089", "mean": "6.807510960377202", "stddev": "5.992888723745428", "min": "0", "max": "16", "missing_count": "0"}, "f00048": {"count": "12089", "mean": "58.81553478368765", "stddev": "94.13977835736269", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00231": {"count": "12089", "mean": "4.466208950285384", "stddev": "5.257014839826631", "min": "0", "max": "15", "missing_count": "0"}, "f00303": {"count": "12089", "mean": "0.0038051120853668623", "stddev": "0.06157066504311279", "min": "0", "max": "1", "missing_count": "0"}, "f00126": {"count": "12089", "mean": "94.28621060468194", "stddev": "112.25243505297904", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00006": {"count": "12089", "mean": "6.519315079824634", "stddev": "33.39763014346889", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00330": {"count": "12089", "mean": "4.135991397137894E-4", "stddev": "0.02033377183391786", "min": "0", "max": "1", "missing_count": "0"}, "f00339": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00219": {"count": "12089", "mean": "0.3002729754322111", "stddev": "0.913988335427884", "min": "0", "max": "4", "missing_count": "0"}, "f00225": {"count": "12089", "mean": "2.4815948382827364E-4", "stddev": "0.015751775297162093", "min": "0", "max": "1", "missing_count": "0"}, "f00252": {"count": "12089", "mean": "0.0", "stddev": "0.0", "min": "0", "max": "0", "missing_count": "0"}, "f00324": {"count": "12089", "mean": "0.017371163867979156", "stddev": "0.13065534290273315", "min": "0", "max": "1", "missing_count": "0"}, "f00351": {"count": "12089", "mean": "9.926379353130945E-4", "stddev": "0.03149181864169435", "min": "0", "max": "1", "missing_count": "0"}, "f00210": {"count": "12089", "mean": "6.837786417404252", "stddev": "5.996903149368257", "min": "0", "max": "16", "missing_count": "0"}, "f00105": {"count": "12089", "mean": "54.79915625775499", "stddev": "92.83279267076065", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00054": {"count": "12089", "mean": "0.6340474811812391", "stddev": "10.467706738001793", "min": "0.0", "max": "255.0", "missing_count": "0"}, "f00318": {"count": "12089", "mean": "0.025891306146083218", "stddev": "0.15881760877519568", "min": "0", "max": "1", "missing_count": "0"}} \ No newline at end of file diff --git a/web_console_v2/api/test/fedlearner_webconsole/test_data/dataset_metainfo/_HIST b/web_console_v2/api/test/fedlearner_webconsole/test_data/dataset_metainfo/_HIST new file mode 100644 index 000000000..0f7948d5c --- /dev/null +++ b/web_console_v2/api/test/fedlearner_webconsole/test_data/dataset_metainfo/_HIST @@ -0,0 +1 @@ +{"f00312": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12070, 0, 0, 0, 0, 0, 0, 0, 0, 19]}, "f00207": {"x": [0.0, 1.7, 3.4, 5.1, 6.8, 8.5, 10.2, 11.9, 13.6, 15.299999999999999, 17], "y": [3415, 748, 754, 387, 748, 750, 394, 747, 3098, 1048]}, "f00197": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12082, 0, 0, 0, 0, 0, 0, 0, 0, 7]}, "f00021": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10427, 222, 162, 127, 117, 128, 110, 117, 132, 547]}, "f00380": {"x": [0, 0], "y": [12089]}, "f00129": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4384, 406, 404, 360, 370, 388, 402, 482, 598, 4295]}, "f00009": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8594, 338, 291, 261, 227, 265, 226, 228, 283, 1376]}, "f00333": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12088, 0, 0, 0, 0, 0, 0, 0, 0, 1]}, "f00036": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9249, 339, 243, 199, 187, 209, 167, 185, 224, 1087]}, "f00000": {"x": [0.0, 0.0], "y": [12089]}, "f00135": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10241, 171, 147, 137, 133, 139, 135, 123, 173, 690]}, "f00213": {"x": [0.0, 1.7, 3.4, 5.1, 6.8, 8.5, 10.2, 11.9, 13.6, 15.299999999999999, 17], "y": [4165, 766, 751, 366, 770, 744, 397, 740, 2591, 799]}, "f00389": {"x": [0, 0], "y": [12089]}, "f00108": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11250, 108, 61, 67, 63, 76, 77, 56, 69, 262]}, "f00098": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6319, 316, 277, 240, 225, 246, 208, 264, 399, 3595]}, "f00120": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7339, 319, 340, 269, 231, 263, 256, 279, 326, 2467]}, "f00306": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12088, 0, 0, 0, 0, 0, 0, 0, 0, 1]}, "f00015": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [3377, 401, 401, 370, 404, 445, 467, 562, 593, 5069]}, "f00234": {"x": [0.0, 1.6, 3.2, 4.800000000000001, 6.4, 8.0, 9.600000000000001, 11.200000000000001, 12.8, 14.4, 16], "y": [3781, 753, 387, 759, 375, 752, 749, 384, 3120, 1029]}, "f00228": {"x": [0.0, 0.4, 0.8, 1.2000000000000002, 1.6, 2.0, 2.4000000000000004, 2.8000000000000003, 3.2, 3.6, 4], "y": [10609, 0, 346, 0, 0, 380, 0, 379, 0, 375]}, "f00114": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [12015, 13, 6, 11, 11, 9, 5, 3, 1, 15]}, "f00296": {"x": [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5], "y": [10485, 0, 93, 0, 377, 0, 390, 0, 368, 376]}, "f00327": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12036, 0, 0, 0, 0, 0, 0, 0, 0, 53]}, "f00315": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11957, 0, 0, 0, 0, 0, 0, 0, 0, 132]}, "f00201": {"x": [0.0, 0.9, 1.8, 2.7, 3.6, 4.5, 5.4, 6.3, 7.2, 8.1, 9], "y": [8544, 145, 385, 373, 376, 380, 381, 394, 791, 320]}, "f00170": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11961, 16, 9, 17, 15, 16, 7, 13, 9, 26]}, "raw_id": {"x": [0.0, 1208.8, 2417.6, 3626.3999999999996, 4835.2, 6044.0, 7252.799999999999, 8461.6, 9670.4, 10879.199999999999, 12088], "y": [1209, 1209, 1209, 1209, 1208, 1209, 1209, 1209, 1209, 1209]}, "f00278": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12087, 0, 0, 0, 0, 0, 0, 0, 0, 2]}, "f00117": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9624, 207, 204, 128, 135, 162, 156, 178, 208, 1087]}, "f00191": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10446, 183, 142, 135, 152, 136, 104, 129, 115, 547]}, "f00216": {"x": [0.0, 1.3, 2.6, 3.9000000000000004, 5.2, 6.5, 7.800000000000001, 9.1, 10.4, 11.700000000000001, 13], "y": [7562, 378, 377, 757, 374, 385, 765, 407, 694, 390]}, "f00185": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [3845, 467, 409, 375, 370, 470, 464, 475, 601, 4613]}, "f00071": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5239, 390, 338, 305, 269, 302, 333, 397, 497, 4019]}, "f00284": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11869, 0, 0, 0, 0, 0, 0, 0, 0, 220]}, "f00299": {"x": [0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2], "y": [11659, 0, 0, 0, 0, 56, 0, 0, 0, 374]}, "f00179": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5063, 410, 380, 296, 336, 387, 333, 423, 475, 3986]}, "f00362": {"x": [0, 0], "y": [12089]}, "f00309": {"x": [0, 0], "y": [12089]}, "f00018": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4620, 464, 405, 320, 377, 439, 395, 519, 580, 3970]}, "f00383": {"x": [0, 0], "y": [12089]}, "f00377": {"x": [0, 0], "y": [12089]}, "f00086": {"x": [0.0, 25.4, 50.8, 76.19999999999999, 101.6, 127.0, 152.39999999999998, 177.79999999999998, 203.2, 228.6, 254.0], "y": [12045, 4, 11, 2, 3, 5, 6, 0, 4, 9]}, "f00300": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11866, 0, 0, 0, 0, 0, 0, 0, 0, 223]}, "f00290": {"x": [0.0, 0.7, 1.4, 2.0999999999999996, 2.8, 3.5, 4.199999999999999, 4.8999999999999995, 5.6, 6.3, 7], "y": [9557, 265, 387, 0, 377, 372, 0, 580, 375, 176]}, "f00003": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [12073, 5, 2, 0, 2, 1, 1, 3, 0, 2]}, "f00092": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8001, 311, 258, 211, 212, 234, 217, 264, 296, 2085]}, "f00102": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4550, 452, 386, 348, 341, 422, 415, 453, 546, 4176]}, "f00344": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12085, 0, 0, 0, 0, 0, 0, 0, 0, 4]}, "f00095": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6925, 292, 291, 274, 213, 238, 304, 337, 369, 2846]}, "f00365": {"x": [0, 0], "y": [12089]}, "f00068": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5826, 394, 362, 364, 291, 326, 312, 407, 432, 3375]}, "f00272": {"x": [0.0, 0.4, 0.8, 1.2000000000000002, 1.6, 2.0, 2.4000000000000004, 2.8000000000000003, 3.2, 3.6, 4], "y": [10828, 0, 128, 0, 0, 379, 0, 380, 0, 374]}, "f00167": {"x": [0.0, 12.8, 25.6, 38.400000000000006, 51.2, 64.0, 76.80000000000001, 89.60000000000001, 102.4, 115.2, 128.0], "y": [12087, 0, 0, 0, 0, 0, 0, 0, 0, 2]}, "f00371": {"x": [0, 0], "y": [12089]}, "f00194": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [12044, 7, 5, 4, 6, 8, 4, 5, 1, 5]}, "f00080": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11529, 73, 56, 43, 37, 54, 35, 43, 61, 158]}, "f00074": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4684, 413, 369, 345, 357, 379, 395, 475, 601, 4071]}, "f00089": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10356, 175, 151, 124, 121, 128, 120, 112, 138, 664]}, "f00293": {"x": [0.0, 0.8, 1.6, 2.4000000000000004, 3.2, 4.0, 4.800000000000001, 5.6000000000000005, 6.4, 7.2, 8], "y": [9360, 89, 376, 411, 0, 350, 369, 468, 440, 226]}, "f00287": {"x": [0.0, 0.4, 0.8, 1.2000000000000002, 1.6, 2.0, 2.4000000000000004, 2.8000000000000003, 3.2, 3.6, 4], "y": [10874, 0, 85, 0, 0, 375, 0, 377, 0, 378]}, "f00152": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6389, 320, 295, 220, 241, 267, 256, 299, 376, 3426]}, "f00188": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6646, 371, 358, 301, 293, 320, 336, 359, 423, 2682]}, "f00251": {"x": [0, 0], "y": [12089]}, "f00350": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12076, 0, 0, 0, 0, 0, 0, 0, 0, 13]}, "f00173": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8701, 252, 245, 174, 192, 227, 178, 213, 223, 1684]}, "f00053": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11931, 21, 22, 9, 11, 10, 16, 16, 10, 43]}, "f00359": {"x": [0, 0], "y": [12089]}, "f00266": {"x": [0.0, 1.3, 2.6, 3.9000000000000004, 5.2, 6.5, 7.800000000000001, 9.1, 10.4, 11.700000000000001, 13], "y": [6426, 381, 387, 780, 346, 377, 761, 733, 1125, 773]}, "f00386": {"x": [0, 0], "y": [12089]}, "f00353": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12079, 0, 0, 0, 0, 0, 0, 0, 0, 10]}, "f00062": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10295, 181, 141, 124, 124, 135, 129, 102, 143, 715]}, "f00248": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11716, 0, 0, 0, 0, 0, 0, 0, 0, 373]}, "f00275": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11810, 0, 0, 0, 0, 0, 0, 0, 0, 279]}, "f00347": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12078, 0, 0, 0, 0, 0, 0, 0, 0, 11]}, "f00326": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11997, 0, 0, 0, 0, 0, 0, 0, 0, 92]}, "f00374": {"x": [0, 0], "y": [12089]}, "f00233": {"x": [0.0, 1.7, 3.4, 5.1, 6.8, 8.5, 10.2, 11.9, 13.6, 15.299999999999999, 17], "y": [3797, 752, 745, 375, 776, 739, 386, 776, 2760, 983]}, "f00077": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9160, 289, 233, 196, 184, 211, 207, 195, 208, 1206]}, "f00332": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12088, 0, 0, 0, 0, 0, 0, 0, 0, 1]}, "f00155": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5344, 444, 415, 336, 328, 347, 321, 425, 567, 3562]}, "f00035": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10265, 241, 181, 133, 120, 129, 116, 109, 160, 635]}, "f00161": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7603, 358, 320, 243, 249, 237, 266, 312, 376, 2125]}, "f00056": {"x": [0.0, 0.0], "y": [12089]}, "f00083": {"x": [0.0, 22.3, 44.6, 66.9, 89.2, 111.5, 133.8, 156.1, 178.4, 200.70000000000002, 223.0], "y": [12084, 1, 0, 0, 1, 0, 1, 1, 0, 1]}, "f00269": {"x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "y": [8553, 155, 368, 380, 367, 383, 373, 380, 603, 527]}, "f00134": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9129, 273, 206, 203, 201, 223, 183, 199, 247, 1225]}, "f00182": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5098, 474, 399, 367, 361, 386, 384, 432, 527, 3661]}, "f00041": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4554, 413, 500, 374, 362, 394, 415, 499, 548, 4030]}, "f00368": {"x": [0, 0], "y": [12089]}, "f00176": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5030, 395, 406, 330, 326, 394, 346, 429, 519, 3914]}, "f00140": {"x": [0.0, 0.0], "y": [12089]}, "f00260": {"x": [0.0, 1.2, 2.4, 3.5999999999999996, 4.8, 6.0, 7.199999999999999, 8.4, 9.6, 10.799999999999999, 12], "y": [7557, 377, 379, 376, 388, 750, 373, 706, 766, 417]}, "f00281": {"x": [0, 0], "y": [12089]}, "f00254": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12040, 0, 0, 0, 0, 0, 0, 0, 0, 49]}, "f00149": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6118, 349, 407, 286, 273, 303, 313, 392, 373, 3275]}, "f00023": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11765, 44, 43, 26, 34, 23, 32, 23, 17, 82]}, "f00158": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [3887, 485, 416, 417, 357, 405, 444, 502, 645, 4531]}, "f00017": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [3486, 436, 431, 395, 386, 461, 460, 565, 668, 4801]}, "f00050": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10907, 154, 129, 115, 73, 85, 78, 89, 109, 350]}, "f00236": {"x": [0.0, 1.6, 3.2, 4.800000000000001, 6.4, 8.0, 9.600000000000001, 11.200000000000001, 12.8, 14.4, 16], "y": [3801, 734, 377, 771, 366, 757, 753, 402, 3034, 1094]}, "f00143": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11390, 78, 57, 54, 58, 92, 48, 62, 55, 195]}, "f00044": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [3848, 456, 452, 360, 394, 462, 458, 486, 610, 4563]}, "f00038": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6753, 429, 404, 326, 293, 322, 328, 360, 427, 2447]}, "f00242": {"x": [0.0, 1.3, 2.6, 3.9000000000000004, 5.2, 6.5, 7.800000000000001, 9.1, 10.4, 11.700000000000001, 13], "y": [7207, 370, 359, 759, 380, 370, 757, 427, 396, 1064]}, "f00116": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10727, 138, 94, 99, 93, 121, 105, 98, 88, 526]}, "f00137": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11649, 54, 60, 39, 36, 39, 42, 31, 42, 97]}, "f00257": {"x": [0.0, 0.4, 0.8, 1.2000000000000002, 1.6, 2.0, 2.4000000000000004, 2.8000000000000003, 3.2, 3.6, 4], "y": [10630, 0, 325, 0, 0, 380, 0, 376, 0, 378]}, "f00320": {"x": [0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2], "y": [11706, 0, 0, 0, 0, 7, 0, 0, 0, 376]}, "f00164": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11034, 132, 120, 75, 79, 94, 91, 80, 80, 304]}, "f00215": {"x": [0.0, 1.4, 2.8, 4.199999999999999, 5.6, 7.0, 8.399999999999999, 9.799999999999999, 11.2, 12.6, 14], "y": [6427, 378, 757, 382, 375, 764, 378, 1075, 1007, 546]}, "f00308": {"x": [0, 0], "y": [12089]}, "f00122": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7084, 300, 256, 233, 226, 254, 275, 315, 345, 2801]}, "f00341": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12087, 0, 0, 0, 0, 0, 0, 0, 0, 2]}, "f00335": {"x": [0, 0], "y": [12089]}, "f00329": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12078, 0, 0, 0, 0, 0, 0, 0, 0, 11]}, "f00221": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11867, 0, 0, 0, 0, 0, 0, 0, 0, 222]}, "f00356": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12086, 0, 0, 0, 0, 0, 0, 0, 0, 3]}, "f00059": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11936, 27, 23, 15, 19, 19, 10, 5, 9, 26]}, "f00065": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7664, 367, 300, 263, 231, 275, 297, 292, 365, 2035]}, "f00314": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12007, 0, 0, 0, 0, 0, 0, 0, 0, 82]}, "f00263": {"x": [0.0, 1.4, 2.8, 4.199999999999999, 5.6, 7.0, 8.399999999999999, 9.799999999999999, 11.2, 12.6, 14], "y": [5669, 379, 768, 379, 372, 755, 369, 1327, 1358, 713]}, "f00323": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11827, 0, 0, 0, 0, 0, 0, 0, 0, 262]}, "f00203": {"x": [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0, 13.5, 15], "y": [5301, 387, 737, 389, 753, 384, 769, 353, 2301, 715]}, "f00026": {"x": [0.0, 25.4, 50.8, 76.19999999999999, 101.6, 127.0, 152.39999999999998, 177.79999999999998, 203.2, 228.6, 254.0], "y": [12054, 4, 3, 6, 6, 2, 3, 4, 4, 3]}, "f00391": {"x": [0, 0], "y": [12089]}, "f00125": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6739, 269, 253, 186, 216, 260, 242, 278, 346, 3300]}, "f00032": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11890, 36, 32, 17, 19, 19, 17, 15, 11, 33]}, "f00193": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11795, 51, 34, 31, 32, 31, 23, 26, 14, 52]}, "f00047": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6134, 437, 419, 252, 318, 402, 348, 383, 467, 2929]}, "f00110": {"x": [0.0, 25.3, 50.6, 75.9, 101.2, 126.5, 151.8, 177.1, 202.4, 227.70000000000002, 253.0], "y": [12009, 9, 7, 7, 11, 10, 12, 11, 5, 8]}, "f00245": {"x": [0.0, 0.6, 1.2, 1.7999999999999998, 2.4, 3.0, 3.5999999999999996, 4.2, 4.8, 5.3999999999999995, 6], "y": [10023, 178, 0, 381, 0, 380, 372, 0, 463, 292]}, "f00146": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7706, 290, 298, 216, 249, 292, 222, 273, 306, 2237]}, "f00005": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11851, 48, 30, 29, 25, 27, 17, 11, 15, 36]}, "f00104": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6824, 434, 338, 302, 300, 355, 322, 338, 404, 2472]}, "f00218": {"x": [0.0, 0.7, 1.4, 2.0999999999999996, 2.8, 3.5, 4.199999999999999, 4.8999999999999995, 5.6, 6.3, 7], "y": [9782, 59, 370, 0, 371, 376, 0, 382, 418, 331]}, "f00131": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4821, 449, 403, 413, 342, 448, 456, 462, 508, 3787]}, "f00317": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11834, 0, 0, 0, 0, 0, 0, 0, 0, 255]}, "f00224": {"x": [0, 0], "y": [12089]}, "f00230": {"x": [0.0, 1.1, 2.2, 3.3000000000000003, 4.4, 5.5, 6.6000000000000005, 7.700000000000001, 8.8, 9.9, 11], "y": [7933, 385, 380, 373, 406, 352, 383, 375, 600, 902]}, "f00239": {"x": [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0, 13.5, 15], "y": [4928, 370, 766, 359, 760, 380, 756, 372, 2554, 844]}, "f00094": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7248, 323, 294, 259, 240, 260, 288, 277, 324, 2576]}, "f00119": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7742, 293, 319, 211, 235, 251, 232, 275, 334, 2197]}, "f00302": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12016, 0, 0, 0, 0, 0, 0, 0, 0, 73]}, "f00292": {"x": [0.0, 0.8, 1.6, 2.4000000000000004, 3.2, 4.0, 4.800000000000001, 5.6000000000000005, 6.4, 7.2, 8], "y": [9263, 181, 384, 372, 0, 381, 381, 441, 458, 228]}, "f00011": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5764, 446, 429, 313, 341, 377, 338, 393, 448, 3240]}, "f00338": {"x": [0, 0], "y": [12089]}, "f00020": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8724, 361, 277, 231, 204, 236, 228, 251, 255, 1322]}, "f00175": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5905, 376, 382, 313, 287, 329, 343, 401, 408, 3345]}, "f00206": {"x": [0.0, 1.8, 3.6, 5.4, 7.2, 9.0, 10.8, 12.6, 14.4, 16.2, 18], "y": [3412, 753, 757, 747, 395, 747, 758, 1390, 1996, 1134]}, "f00029": {"x": [0.0, 22.6, 45.2, 67.80000000000001, 90.4, 113.0, 135.60000000000002, 158.20000000000002, 180.8, 203.4, 226.0], "y": [12088, 0, 0, 0, 0, 0, 0, 0, 0, 1]}, "f00274": {"x": [0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2], "y": [11586, 0, 0, 0, 0, 126, 0, 0, 0, 377]}, "f00128": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5125, 424, 393, 318, 305, 344, 326, 414, 524, 3916]}, "f00373": {"x": [0, 0], "y": [12089]}, "f00196": {"x": [0, 0], "y": [12089]}, "f00295": {"x": [0.0, 0.6, 1.2, 1.7999999999999998, 2.4, 3.0, 3.5999999999999996, 4.2, 4.8, 5.3999999999999995, 6], "y": [9997, 203, 0, 382, 0, 376, 376, 0, 408, 347]}, "f00305": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12084, 0, 0, 0, 0, 0, 0, 0, 0, 5]}, "f00289": {"x": [0.0, 0.6, 1.2, 1.7999999999999998, 2.4, 3.0, 3.5999999999999996, 4.2, 4.8, 5.3999999999999995, 6], "y": [9920, 285, 0, 373, 0, 379, 376, 0, 589, 167]}, "f00212": {"x": [0.0, 1.6, 3.2, 4.800000000000001, 6.4, 8.0, 9.600000000000001, 11.200000000000001, 12.8, 14.4, 16], "y": [4178, 741, 372, 780, 354, 761, 768, 388, 2747, 1000]}, "f00181": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5291, 472, 414, 347, 321, 397, 356, 396, 500, 3595]}, "f00076": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7483, 408, 326, 247, 281, 296, 271, 305, 364, 2108]}, "f00280": {"x": [0, 0], "y": [12089]}, "f00014": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [3738, 434, 464, 340, 369, 391, 391, 517, 510, 4935]}, "f00388": {"x": [0, 0], "y": [12089]}, "f00227": {"x": [0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2], "y": [11527, 0, 0, 0, 0, 187, 0, 0, 0, 375]}, "f00082": {"x": [0.0, 25.4, 50.8, 76.19999999999999, 101.6, 127.0, 152.39999999999998, 177.79999999999998, 203.2, 228.6, 254.0], "y": [12014, 7, 17, 4, 9, 7, 10, 7, 6, 8]}, "f00008": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9951, 267, 217, 165, 163, 154, 153, 135, 180, 704]}, "f00113": {"x": [0.0, 19.7, 39.4, 59.099999999999994, 78.8, 98.5, 118.19999999999999, 137.9, 157.6, 177.29999999999998, 197.0], "y": [12087, 1, 0, 0, 0, 0, 0, 0, 0, 1]}, "f00107": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10633, 174, 106, 97, 108, 144, 86, 106, 116, 519]}, "f00097": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6501, 292, 266, 208, 224, 247, 223, 273, 388, 3467]}, "f00311": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12085, 0, 0, 0, 0, 0, 0, 0, 0, 4]}, "f00184": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4057, 463, 429, 354, 401, 429, 411, 484, 696, 4365]}, "f00079": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11075, 131, 78, 77, 83, 89, 87, 67, 87, 315]}, "f00101": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4706, 406, 413, 326, 308, 358, 391, 466, 538, 4177]}, "f00002": {"x": [0.0, 6.9, 13.8, 20.700000000000003, 27.6, 34.5, 41.400000000000006, 48.300000000000004, 55.2, 62.1, 69.0], "y": [12086, 2, 0, 0, 0, 0, 0, 0, 0, 1]}, "f00070": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5411, 368, 362, 308, 278, 334, 326, 337, 451, 3914]}, "f00064": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8548, 333, 249, 220, 218, 225, 211, 235, 291, 1559]}, "f00209": {"x": [0.0, 1.7, 3.4, 5.1, 6.8, 8.5, 10.2, 11.9, 13.6, 15.299999999999999, 17], "y": [3802, 737, 750, 380, 760, 776, 367, 768, 2732, 1017]}, "f00283": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12004, 0, 0, 0, 0, 0, 0, 0, 0, 85]}, "f00277": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12062, 0, 0, 0, 0, 0, 0, 0, 0, 27]}, "f00091": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8587, 262, 261, 207, 183, 237, 172, 252, 280, 1648]}, "f00163": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10179, 165, 161, 155, 140, 159, 129, 136, 152, 713]}, "f00058": {"x": [0.0, 25.4, 50.8, 76.19999999999999, 101.6, 127.0, 152.39999999999998, 177.79999999999998, 203.2, 228.6, 254.0], "y": [12061, 3, 3, 3, 3, 4, 4, 3, 3, 2]}, "f00190": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9354, 268, 252, 206, 189, 197, 179, 168, 219, 1057]}, "f00200": {"x": [0.0, 0.6, 1.2, 1.7999999999999998, 2.4, 3.0, 3.5999999999999996, 4.2, 4.8, 5.3999999999999995, 6], "y": [10018, 198, 0, 362, 0, 403, 359, 0, 391, 358]}, "f00376": {"x": [0, 0], "y": [12089]}, "f00199": {"x": [0.0, 0.3, 0.6, 0.8999999999999999, 1.2, 1.5, 1.7999999999999998, 2.1, 2.4, 2.6999999999999997, 3], "y": [11267, 0, 0, 67, 0, 0, 377, 0, 0, 378]}, "f00085": {"x": [0.0, 13.3, 26.6, 39.900000000000006, 53.2, 66.5, 79.80000000000001, 93.10000000000001, 106.4, 119.7, 133.0], "y": [12086, 0, 1, 0, 0, 1, 0, 0, 0, 1]}, "f00298": {"x": [0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2], "y": [11342, 0, 0, 0, 0, 369, 0, 0, 0, 378]}, "f00157": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [3882, 449, 425, 384, 392, 441, 424, 521, 647, 4524]}, "f00361": {"x": [0, 0], "y": [12089]}, "f00256": {"x": [0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2], "y": [11346, 0, 0, 0, 0, 367, 0, 0, 0, 376]}, "f00262": {"x": [0.0, 1.4, 2.8, 4.199999999999999, 5.6, 7.0, 8.399999999999999, 9.799999999999999, 11.2, 12.6, 14], "y": [6052, 373, 760, 371, 387, 761, 364, 1167, 1212, 642]}, "f00355": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12084, 0, 0, 0, 0, 0, 0, 0, 0, 5]}, "f00178": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4830, 437, 381, 304, 340, 379, 356, 390, 449, 4223]}, "f00382": {"x": [0, 0], "y": [12089]}, "f00364": {"x": [0, 0], "y": [12089]}, "f00358": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12088, 0, 0, 0, 0, 0, 0, 0, 0, 1]}, "f00067": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6256, 386, 391, 343, 324, 331, 365, 335, 416, 2942]}, "f00271": {"x": [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5], "y": [10223, 0, 366, 0, 367, 0, 378, 0, 380, 375]}, "f00286": {"x": [0.0, 0.3, 0.6, 0.8999999999999999, 1.2, 1.5, 1.7999999999999998, 2.1, 2.4, 2.6999999999999997, 3], "y": [11300, 0, 0, 36, 0, 0, 382, 0, 0, 371]}, "f00244": {"x": [0.0, 0.8, 1.6, 2.4000000000000004, 3.2, 4.0, 4.800000000000001, 5.6000000000000005, 6.4, 7.2, 8], "y": [9118, 345, 363, 374, 0, 383, 386, 369, 601, 150]}, "f00379": {"x": [0, 0], "y": [12089]}, "f00337": {"x": [0, 0], "y": [12089]}, "f00151": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6312, 320, 285, 259, 275, 274, 261, 322, 391, 3390]}, "f00259": {"x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "y": [8358, 337, 383, 366, 385, 372, 379, 382, 391, 736]}, "f00073": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4424, 441, 415, 338, 328, 423, 411, 474, 566, 4269]}, "f00172": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10154, 149, 158, 111, 128, 134, 118, 173, 154, 810]}, "f00166": {"x": [0.0, 25.3, 50.6, 75.9, 101.2, 126.5, 151.8, 177.1, 202.4, 227.70000000000002, 253.0], "y": [12032, 5, 10, 5, 5, 9, 3, 7, 2, 11]}, "f00385": {"x": [0, 0], "y": [12089]}, "f00088": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11223, 93, 83, 61, 65, 79, 70, 64, 58, 293]}, "f00139": {"x": [0.0, 15.3, 30.6, 45.900000000000006, 61.2, 76.5, 91.80000000000001, 107.10000000000001, 122.4, 137.70000000000002, 153.0], "y": [12084, 1, 1, 0, 0, 0, 0, 0, 1, 2]}, "f00343": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12086, 0, 0, 0, 0, 0, 0, 0, 0, 3]}, "f00052": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11759, 52, 35, 24, 24, 33, 19, 21, 37, 85]}, "f00046": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4627, 410, 429, 346, 368, 383, 379, 491, 583, 4073]}, "f00187": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5262, 459, 383, 331, 332, 364, 383, 438, 551, 3586]}, "f00238": {"x": [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0, 13.5, 15], "y": [4555, 357, 758, 382, 752, 376, 756, 417, 2569, 1167]}, "f00250": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12078, 0, 0, 0, 0, 0, 0, 0, 0, 11]}, "f00370": {"x": [0, 0], "y": [12089]}, "f00265": {"x": [0.0, 1.3, 2.6, 3.9000000000000004, 5.2, 6.5, 7.800000000000001, 9.1, 10.4, 11.700000000000001, 13], "y": [6045, 388, 368, 756, 379, 393, 749, 926, 1318, 767]}, "f00145": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9002, 229, 222, 141, 173, 199, 187, 201, 233, 1502]}, "f00028": {"x": [0.0, 0.0], "y": [12089]}, "f00169": {"x": [0.0, 18.5, 37.0, 55.5, 74.0, 92.5, 111.0, 129.5, 148.0, 166.5, 185.0], "y": [12083, 1, 1, 0, 0, 0, 0, 1, 1, 2]}, "f00232": {"x": [0.0, 1.6, 3.2, 4.800000000000001, 6.4, 8.0, 9.600000000000001, 11.200000000000001, 12.8, 14.4, 16], "y": [4920, 755, 380, 754, 370, 760, 769, 413, 2147, 821]}, "f00352": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12077, 0, 0, 0, 0, 0, 0, 0, 0, 12]}, "f00127": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5959, 375, 377, 256, 263, 273, 285, 361, 422, 3518]}, "f00055": {"x": [0.0, 19.0, 38.0, 57.0, 76.0, 95.0, 114.0, 133.0, 152.0, 171.0, 190.0], "y": [12083, 0, 1, 1, 2, 0, 0, 0, 1, 1]}, "f00310": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12087, 0, 0, 0, 0, 0, 0, 0, 0, 2]}, "f00154": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5935, 413, 389, 270, 301, 368, 321, 351, 420, 3321]}, "f00049": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9852, 272, 225, 154, 162, 168, 134, 126, 148, 848]}, "f00253": {"x": [0, 0], "y": [12089]}, "f00367": {"x": [0, 0], "y": [12089]}, "f00331": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12088, 0, 0, 0, 0, 0, 0, 0, 0, 1]}, "f00325": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11937, 0, 0, 0, 0, 0, 0, 0, 0, 152]}, "f00034": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11018, 146, 117, 100, 91, 86, 70, 58, 87, 316]}, "f00247": {"x": [0.0, 0.3, 0.6, 0.8999999999999999, 1.2, 1.5, 1.7999999999999998, 2.1, 2.4, 2.6999999999999997, 3], "y": [11319, 0, 0, 15, 0, 0, 378, 0, 0, 377]}, "f00319": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11727, 0, 0, 0, 0, 0, 0, 0, 0, 362]}, "f00160": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6121, 435, 358, 294, 322, 376, 316, 395, 480, 2992]}, "f00346": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12079, 0, 0, 0, 0, 0, 0, 0, 0, 10]}, "f00040": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5033, 400, 476, 364, 364, 427, 434, 427, 517, 3647]}, "f00148": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6238, 375, 369, 319, 314, 298, 331, 372, 388, 3085]}, "f00226": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11987, 0, 0, 0, 0, 0, 0, 0, 0, 102]}, "f00061": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11035, 129, 90, 89, 88, 97, 76, 69, 95, 321]}, "f00268": {"x": [0.0, 1.1, 2.2, 3.3000000000000003, 4.4, 5.5, 6.6000000000000005, 7.700000000000001, 8.8, 9.9, 11], "y": [7944, 375, 382, 369, 377, 382, 379, 375, 647, 859]}, "f00133": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7831, 348, 304, 261, 234, 246, 251, 256, 360, 1998]}, "f00022": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11351, 119, 106, 67, 64, 65, 39, 36, 51, 191]}, "f00142": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11984, 13, 9, 10, 12, 9, 9, 11, 13, 19]}, "f00037": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7989, 403, 368, 247, 259, 261, 254, 275, 370, 1663]}, "f00241": {"x": [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0, 13.5, 15], "y": [6047, 382, 749, 378, 763, 373, 767, 380, 1767, 483]}, "f00334": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12088, 0, 0, 0, 0, 0, 0, 0, 0, 1]}, "f00229": {"x": [0.0, 0.8, 1.6, 2.4000000000000004, 3.2, 4.0, 4.800000000000001, 5.6000000000000005, 6.4, 7.2, 8], "y": [9283, 177, 381, 360, 0, 381, 373, 390, 566, 178]}, "f00043": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4046, 460, 445, 382, 381, 377, 440, 497, 599, 4462]}, "f00121": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7163, 327, 295, 290, 254, 279, 251, 305, 325, 2600]}, "f00001": {"x": [0.0, 9.9, 19.8, 29.700000000000003, 39.6, 49.5, 59.400000000000006, 69.3, 79.2, 89.10000000000001, 99.0], "y": [12087, 0, 0, 0, 0, 0, 1, 0, 0, 1]}, "f00115": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11554, 61, 59, 52, 55, 60, 39, 39, 46, 124]}, "f00307": {"x": [0, 0], "y": [12089]}, "f00016": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [3154, 446, 438, 391, 422, 460, 418, 526, 708, 5126]}, "f00220": {"x": [0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2], "y": [11406, 0, 0, 0, 0, 307, 0, 0, 0, 376]}, "f00214": {"x": [0.0, 1.6, 3.2, 4.800000000000001, 6.4, 8.0, 9.600000000000001, 11.200000000000001, 12.8, 14.4, 16], "y": [4926, 745, 393, 738, 383, 755, 762, 398, 2257, 732]}, "f00109": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11696, 39, 30, 37, 33, 49, 31, 37, 43, 94]}, "f00328": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12060, 0, 0, 0, 0, 0, 0, 0, 0, 29]}, "f00136": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11038, 109, 99, 87, 81, 94, 86, 90, 98, 307]}, "f00340": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12088, 0, 0, 0, 0, 0, 0, 0, 0, 1]}, "f00349": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12077, 0, 0, 0, 0, 0, 0, 0, 0, 12]}, "f00100": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5363, 398, 372, 293, 294, 303, 337, 395, 416, 3918]}, "f00235": {"x": [0.0, 1.6, 3.2, 4.800000000000001, 6.4, 8.0, 9.600000000000001, 11.200000000000001, 12.8, 14.4, 16], "y": [3778, 761, 382, 753, 393, 751, 747, 462, 2973, 1089]}, "f00313": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12046, 0, 0, 0, 0, 0, 0, 0, 0, 43]}, "f00208": {"x": [0.0, 1.7, 3.4, 5.1, 6.8, 8.5, 10.2, 11.9, 13.6, 15.299999999999999, 17], "y": [3793, 767, 733, 393, 749, 769, 353, 783, 2729, 1020]}, "f00186": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4193, 442, 423, 362, 346, 413, 462, 503, 661, 4284]}, "f00217": {"x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "y": [8623, 67, 379, 376, 377, 385, 371, 380, 485, 646]}, "f00025": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11988, 15, 20, 11, 6, 10, 5, 6, 9, 19]}, "f00390": {"x": [0, 0], "y": [12089]}, "f00384": {"x": [0, 0], "y": [12089]}, "f00093": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7596, 327, 256, 249, 230, 228, 252, 280, 358, 2313]}, "f00285": {"x": [0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2], "y": [11653, 0, 0, 0, 0, 58, 0, 0, 0, 378]}, "f00103": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5336, 433, 356, 361, 355, 378, 414, 448, 544, 3464]}, "f00202": {"x": [0.0, 1.3, 2.6, 3.9000000000000004, 5.2, 6.5, 7.800000000000001, 9.1, 10.4, 11.700000000000001, 13], "y": [6805, 386, 377, 747, 375, 393, 754, 882, 888, 482]}, "f00192": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11234, 92, 92, 76, 70, 79, 69, 75, 70, 232]}, "f00031": {"x": [0.0, 25.4, 50.8, 76.19999999999999, 101.6, 127.0, 152.39999999999998, 177.79999999999998, 203.2, 228.6, 254.0], "y": [12033, 11, 6, 9, 9, 4, 4, 3, 2, 8]}, "f00124": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6866, 258, 257, 191, 249, 258, 242, 254, 343, 3171]}, "f00130": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4186, 409, 402, 365, 366, 448, 452, 478, 621, 4362]}, "f00019": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6535, 433, 390, 275, 316, 397, 345, 375, 428, 2595]}, "f00087": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11773, 44, 39, 30, 33, 39, 12, 29, 20, 70]}, "f00301": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11969, 0, 0, 0, 0, 0, 0, 0, 0, 120]}, "f00010": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7104, 403, 375, 295, 270, 344, 305, 323, 361, 2309]}, "f00004": {"x": [0.0, 25.4, 50.8, 76.19999999999999, 101.6, 127.0, 152.39999999999998, 177.79999999999998, 203.2, 228.6, 254.0], "y": [12010, 18, 19, 7, 8, 4, 4, 3, 6, 10]}, "f00223": {"x": [0, 0], "y": [12089]}, "f00118": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8533, 253, 269, 203, 182, 239, 208, 218, 275, 1709]}, "f00291": {"x": [0.0, 0.8, 1.6, 2.4000000000000004, 3.2, 4.0, 4.800000000000001, 5.6000000000000005, 6.4, 7.2, 8], "y": [9310, 140, 375, 383, 0, 378, 369, 499, 431, 204]}, "f00322": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11763, 0, 0, 0, 0, 0, 0, 0, 0, 326]}, "f00316": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11901, 0, 0, 0, 0, 0, 0, 0, 0, 188]}, "f00013": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4169, 402, 453, 375, 377, 417, 391, 501, 459, 4545]}, "f00189": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8107, 299, 298, 257, 219, 235, 258, 268, 320, 1828]}, "f00195": {"x": [0.0, 0.0], "y": [12089]}, "f00112": {"x": [0.0, 0.0], "y": [12089]}, "f00081": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11816, 27, 22, 21, 30, 40, 21, 19, 26, 67]}, "f00007": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10927, 174, 149, 95, 99, 74, 78, 96, 86, 311]}, "f00211": {"x": [0.0, 1.6, 3.2, 4.800000000000001, 6.4, 8.0, 9.600000000000001, 11.200000000000001, 12.8, 14.4, 16], "y": [4173, 749, 373, 765, 363, 766, 749, 383, 2766, 1002]}, "f00180": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5213, 468, 396, 317, 338, 423, 311, 419, 483, 3721]}, "f00366": {"x": [0, 0], "y": [12089]}, "f00075": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5770, 490, 347, 302, 331, 397, 323, 417, 492, 3220]}, "f00069": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5619, 356, 326, 310, 280, 326, 337, 368, 447, 3720]}, "f00288": {"x": [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5], "y": [10378, 0, 200, 0, 382, 0, 383, 0, 432, 314]}, "f00174": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [7158, 305, 325, 249, 278, 294, 257, 330, 373, 2520]}, "f00387": {"x": [0, 0], "y": [12089]}, "f00205": {"x": [0.0, 1.7, 3.4, 5.1, 6.8, 8.5, 10.2, 11.9, 13.6, 15.299999999999999, 17], "y": [3418, 743, 757, 374, 756, 761, 395, 749, 2987, 1149]}, "f00060": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11619, 78, 52, 40, 30, 54, 36, 37, 27, 116]}, "f00304": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12070, 0, 0, 0, 0, 0, 0, 0, 0, 19]}, "f00273": {"x": [0.0, 0.3, 0.6, 0.8999999999999999, 1.2, 1.5, 1.7999999999999998, 2.1, 2.4, 2.6999999999999997, 3], "y": [11285, 0, 0, 53, 0, 0, 375, 0, 0, 376]}, "f00294": {"x": [0.0, 0.7, 1.4, 2.0999999999999996, 2.8, 3.5, 4.199999999999999, 4.8999999999999995, 5.6, 6.3, 7], "y": [9641, 189, 373, 0, 381, 372, 0, 384, 546, 203]}, "f00168": {"x": [0.0, 0.0], "y": [12089]}, "f00372": {"x": [0, 0], "y": [12089]}, "f00267": {"x": [0.0, 1.3, 2.6, 3.9000000000000004, 5.2, 6.5, 7.800000000000001, 9.1, 10.4, 11.700000000000001, 13], "y": [7182, 379, 398, 749, 369, 371, 754, 596, 855, 436]}, "f00106": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9670, 270, 196, 140, 185, 185, 162, 177, 194, 910]}, "f00096": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6688, 311, 265, 229, 227, 246, 257, 283, 335, 3248]}, "f00360": {"x": [0, 0], "y": [12089]}, "f00369": {"x": [0, 0], "y": [12089]}, "f00183": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4581, 546, 421, 348, 379, 423, 382, 469, 575, 3965]}, "f00141": {"x": [0.0, 16.6, 33.2, 49.800000000000004, 66.4, 83.0, 99.60000000000001, 116.20000000000002, 132.8, 149.4, 166.0], "y": [12085, 0, 0, 1, 0, 2, 0, 0, 0, 1]}, "f00090": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9452, 221, 189, 147, 169, 162, 165, 176, 221, 1187]}, "f00354": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12082, 0, 0, 0, 0, 0, 0, 0, 0, 7]}, "f00249": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11974, 0, 0, 0, 0, 0, 0, 0, 0, 115]}, "f00084": {"x": [0.0, 0.0], "y": [12089]}, "f00063": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [9480, 243, 186, 182, 154, 158, 185, 160, 192, 1149]}, "f00198": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11948, 0, 0, 0, 0, 0, 0, 0, 0, 141]}, "f00297": {"x": [0.0, 0.3, 0.6, 0.8999999999999999, 1.2, 1.5, 1.7999999999999998, 2.1, 2.4, 2.6999999999999997, 3], "y": [10963, 0, 0, 374, 0, 0, 374, 0, 0, 378]}, "f00156": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4527, 475, 409, 360, 340, 411, 376, 459, 645, 4087]}, "f00255": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11812, 0, 0, 0, 0, 0, 0, 0, 0, 277]}, "f00078": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10356, 204, 153, 113, 121, 147, 108, 97, 129, 661]}, "f00282": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12076, 0, 0, 0, 0, 0, 0, 0, 0, 13]}, "f00177": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4723, 404, 353, 334, 360, 405, 376, 411, 518, 4205]}, "f00042": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4282, 425, 468, 374, 372, 381, 462, 488, 521, 4316]}, "f00381": {"x": [0, 0], "y": [12089]}, "f00240": {"x": [0.0, 1.6, 3.2, 4.800000000000001, 6.4, 8.0, 9.600000000000001, 11.200000000000001, 12.8, 14.4, 16], "y": [5291, 762, 371, 759, 384, 762, 745, 450, 1867, 698]}, "f00276": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11977, 0, 0, 0, 0, 0, 0, 0, 0, 112]}, "f00099": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5984, 304, 310, 279, 257, 278, 251, 324, 403, 3699]}, "f00162": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8968, 271, 259, 188, 208, 200, 214, 214, 257, 1310]}, "f00348": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12074, 0, 0, 0, 0, 0, 0, 0, 0, 15]}, "f00057": {"x": [0.0, 10.7, 21.4, 32.099999999999994, 42.8, 53.5, 64.19999999999999, 74.89999999999999, 85.6, 96.3, 107.0], "y": [12087, 0, 0, 0, 0, 0, 0, 0, 1, 1]}, "f00261": {"x": [0.0, 1.4, 2.8, 4.199999999999999, 5.6, 7.0, 8.399999999999999, 9.799999999999999, 11.2, 12.6, 14], "y": [6432, 368, 761, 381, 387, 747, 379, 1024, 1069, 541]}, "f00375": {"x": [0, 0], "y": [12089]}, "f00039": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [5703, 470, 412, 383, 320, 403, 401, 401, 485, 3111]}, "f00237": {"x": [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0, 13.5, 15], "y": [4173, 382, 735, 393, 744, 398, 765, 372, 3016, 1111]}, "f00051": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11475, 97, 58, 63, 57, 52, 37, 46, 46, 158]}, "f00243": {"x": [0.0, 1.1, 2.2, 3.3000000000000003, 4.4, 5.5, 6.6000000000000005, 7.700000000000001, 8.8, 9.9, 11], "y": [8314, 395, 374, 370, 373, 374, 391, 371, 390, 737]}, "f00357": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12087, 0, 0, 0, 0, 0, 0, 0, 0, 2]}, "f00150": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6158, 350, 355, 292, 294, 299, 264, 318, 350, 3409]}, "f00270": {"x": [0.0, 0.7, 1.4, 2.0999999999999996, 2.8, 3.5, 4.199999999999999, 4.8999999999999995, 5.6, 6.3, 7], "y": [9462, 368, 372, 0, 379, 375, 0, 379, 401, 353]}, "f00024": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11902, 27, 31, 12, 14, 21, 8, 12, 16, 46]}, "f00165": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11691, 51, 46, 36, 43, 35, 41, 42, 24, 80]}, "f00159": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4615, 454, 453, 393, 382, 458, 424, 506, 588, 3816]}, "f00363": {"x": [0, 0], "y": [12089]}, "f00258": {"x": [0.0, 0.7, 1.4, 2.0999999999999996, 2.8, 3.5, 4.199999999999999, 4.8999999999999995, 5.6, 6.3, 7], "y": [9543, 281, 392, 0, 370, 369, 0, 378, 622, 134]}, "f00123": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6984, 294, 266, 220, 218, 245, 210, 279, 358, 3015]}, "f00378": {"x": [0, 0], "y": [12089]}, "f00321": {"x": [0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000002, 1.4000000000000001, 1.6, 1.8, 2], "y": [11711, 0, 0, 0, 0, 0, 0, 0, 0, 378]}, "f00336": {"x": [0, 0], "y": [12089]}, "f00342": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12087, 0, 0, 0, 0, 0, 0, 0, 0, 2]}, "f00045": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [3911, 454, 408, 329, 363, 435, 424, 508, 679, 4578]}, "f00264": {"x": [0.0, 1.4, 2.8, 4.199999999999999, 5.6, 7.0, 8.399999999999999, 9.799999999999999, 11.2, 12.6, 14], "y": [5678, 372, 753, 379, 393, 737, 380, 1236, 1402, 759]}, "f00072": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4799, 453, 387, 342, 317, 322, 368, 425, 502, 4174]}, "f00171": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11296, 74, 84, 56, 83, 89, 54, 64, 60, 229]}, "f00222": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12056, 0, 0, 0, 0, 0, 0, 0, 0, 33]}, "f00030": {"x": [0.0, 25.4, 50.8, 76.19999999999999, 101.6, 127.0, 152.39999999999998, 177.79999999999998, 203.2, 228.6, 254.0], "y": [12077, 3, 2, 3, 1, 2, 0, 0, 0, 1]}, "f00066": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6902, 393, 322, 331, 295, 348, 295, 328, 393, 2482]}, "f00138": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [12021, 17, 9, 7, 6, 9, 3, 5, 5, 7]}, "f00144": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [10286, 176, 139, 112, 141, 136, 126, 123, 122, 728]}, "f00279": {"x": [0, 0], "y": [12089]}, "f00153": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6259, 340, 350, 234, 286, 286, 279, 363, 389, 3303]}, "f00012": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [4872, 402, 424, 321, 351, 415, 387, 454, 468, 3995]}, "f00111": {"x": [0.0, 10.2, 20.4, 30.599999999999998, 40.8, 51.0, 61.199999999999996, 71.39999999999999, 81.6, 91.8, 102.0], "y": [12083, 0, 1, 0, 1, 1, 1, 0, 0, 2]}, "f00027": {"x": [0.0, 5.2, 10.4, 15.600000000000001, 20.8, 26.0, 31.200000000000003, 36.4, 41.6, 46.800000000000004, 52.0], "y": [12086, 0, 0, 0, 0, 1, 0, 0, 0, 2]}, "f00033": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11558, 86, 59, 58, 44, 45, 35, 42, 35, 127]}, "f00147": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6773, 352, 334, 276, 270, 303, 268, 333, 402, 2778]}, "f00246": {"x": [0.0, 0.4, 0.8, 1.2000000000000002, 1.6, 2.0, 2.4000000000000004, 2.8000000000000003, 3.2, 3.6, 4], "y": [10771, 0, 186, 0, 0, 377, 0, 377, 0, 378]}, "f00132": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6290, 443, 373, 301, 323, 374, 327, 360, 447, 2851]}, "f00345": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12084, 0, 0, 0, 0, 0, 0, 0, 0, 5]}, "f00204": {"x": [0.0, 1.6, 3.2, 4.800000000000001, 6.4, 8.0, 9.600000000000001, 11.200000000000001, 12.8, 14.4, 16], "y": [4185, 737, 380, 748, 374, 774, 742, 385, 2768, 996]}, "f00048": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8094, 379, 315, 252, 252, 305, 249, 296, 263, 1684]}, "f00231": {"x": [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0, 13.5, 15], "y": [6046, 395, 738, 377, 763, 382, 748, 379, 1725, 536]}, "f00303": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12043, 0, 0, 0, 0, 0, 0, 0, 0, 46]}, "f00126": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [6511, 338, 288, 220, 208, 241, 237, 292, 369, 3385]}, "f00006": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [11528, 92, 84, 57, 50, 47, 40, 43, 31, 117]}, "f00330": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12084, 0, 0, 0, 0, 0, 0, 0, 0, 5]}, "f00339": {"x": [0, 0], "y": [12089]}, "f00219": {"x": [0.0, 0.4, 0.8, 1.2000000000000002, 1.6, 2.0, 2.4000000000000004, 2.8000000000000003, 3.2, 3.6, 4], "y": [10726, 0, 230, 0, 0, 377, 0, 378, 0, 378]}, "f00225": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12086, 0, 0, 0, 0, 0, 0, 0, 0, 3]}, "f00252": {"x": [0, 0], "y": [12089]}, "f00324": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11879, 0, 0, 0, 0, 0, 0, 0, 0, 210]}, "f00351": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [12077, 0, 0, 0, 0, 0, 0, 0, 0, 12]}, "f00210": {"x": [0.0, 1.6, 3.2, 4.800000000000001, 6.4, 8.0, 9.600000000000001, 11.200000000000001, 12.8, 14.4, 16], "y": [4173, 741, 380, 763, 379, 746, 764, 372, 2690, 1081]}, "f00105": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [8423, 354, 259, 224, 214, 257, 237, 234, 274, 1613]}, "f00054": {"x": [0.0, 25.5, 51.0, 76.5, 102.0, 127.5, 153.0, 178.5, 204.0, 229.5, 255.0], "y": [12038, 1, 6, 8, 6, 6, 5, 8, 3, 8]}, "f00318": {"x": [0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1], "y": [11776, 0, 0, 0, 0, 0, 0, 0, 0, 313]}} \ No newline at end of file diff --git a/web_console_v2/api/test/fedlearner_webconsole/test_data/dataset_metainfo/_META b/web_console_v2/api/test/fedlearner_webconsole/test_data/dataset_metainfo/_META new file mode 100644 index 000000000..a8399694e --- /dev/null +++ b/web_console_v2/api/test/fedlearner_webconsole/test_data/dataset_metainfo/_META @@ -0,0 +1 @@ +{"dtypes": {"f00312": "bigint", "f00207": "bigint", "f00197": "bigint", "f00021": "float", "f00380": "bigint", "f00129": "float", "f00009": "float", "f00333": "bigint", "f00036": "float", "f00000": "float", "f00135": "float", "f00213": "bigint", "f00389": "bigint", "f00108": "float", "f00098": "float", "f00120": "float", "f00306": "bigint", "f00015": "float", "f00234": "bigint", "f00228": "bigint", "f00114": "float", "f00296": "bigint", "f00327": "bigint", "f00315": "bigint", "f00201": "bigint", "f00170": "float", "raw_id": "bigint", "f00278": "bigint", "f00117": "float", "f00191": "float", "f00216": "bigint", "f00185": "float", "f00071": "float", "f00284": "bigint", "f00299": "bigint", "f00179": "float", "f00362": "bigint", "f00309": "bigint", "f00018": "float", "f00383": "bigint", "f00377": "bigint", "f00086": "float", "f00300": "bigint", "f00290": "bigint", "f00003": "float", "f00092": "float", "f00102": "float", "f00344": "bigint", "f00095": "float", "f00365": "bigint", "f00068": "float", "f00272": "bigint", "f00167": "float", "f00371": "bigint", "f00194": "float", "f00080": "float", "f00074": "float", "f00089": "float", "f00293": "bigint", "f00287": "bigint", "f00152": "float", "f00188": "float", "f00251": "bigint", "f00350": "bigint", "f00173": "float", "f00053": "float", "f00359": "bigint", "f00266": "bigint", "f00386": "bigint", "f00353": "bigint", "f00062": "float", "f00248": "bigint", "f00275": "bigint", "f00347": "bigint", "f00326": "bigint", "f00374": "bigint", "f00233": "bigint", "f00077": "float", "f00332": "bigint", "f00155": "float", "f00035": "float", "f00161": "float", "f00056": "float", "f00083": "float", "f00269": "bigint", "f00134": "float", "f00182": "float", "f00041": "float", "f00368": "bigint", "f00176": "float", "f00140": "float", "f00260": "bigint", "f00281": "bigint", "f00254": "bigint", "f00149": "float", "f00023": "float", "f00158": "float", "f00017": "float", "f00050": "float", "f00236": "bigint", "f00143": "float", "f00044": "float", "f00038": "float", "f00242": "bigint", "f00116": "float", "f00137": "float", "f00257": "bigint", "f00320": "bigint", "f00164": "float", "f00215": "bigint", "f00308": "bigint", "f00122": "float", "f00341": "bigint", "f00335": "bigint", "f00329": "bigint", "f00221": "bigint", "f00356": "bigint", "f00059": "float", "f00065": "float", "f00314": "bigint", "f00263": "bigint", "f00323": "bigint", "f00203": "bigint", "f00026": "float", "f00391": "bigint", "f00125": "float", "f00032": "float", "f00193": "float", "f00047": "float", "f00110": "float", "f00245": "bigint", "f00146": "float", "f00005": "float", "f00104": "float", "f00218": "bigint", "f00131": "float", "f00317": "bigint", "f00224": "bigint", "f00230": "bigint", "f00239": "bigint", "f00094": "float", "f00119": "float", "f00302": "bigint", "f00292": "bigint", "f00011": "float", "f00338": "bigint", "f00020": "float", "f00175": "float", "f00206": "bigint", "f00029": "float", "f00274": "bigint", "f00128": "float", "f00373": "bigint", "f00196": "bigint", "f00295": "bigint", "f00305": "bigint", "f00289": "bigint", "f00212": "bigint", "f00181": "float", "f00076": "float", "f00280": "bigint", "f00014": "float", "f00388": "bigint", "f00227": "bigint", "f00082": "float", "f00008": "float", "f00113": "float", "f00107": "float", "f00097": "float", "f00311": "bigint", "f00184": "float", "f00079": "float", "f00101": "float", "f00002": "float", "f00070": "float", "f00064": "float", "f00209": "bigint", "f00283": "bigint", "f00277": "bigint", "f00091": "float", "f00163": "float", "f00058": "float", "f00190": "float", "f00200": "bigint", "f00376": "bigint", "f00199": "bigint", "f00085": "float", "f00298": "bigint", "f00157": "float", "f00361": "bigint", "f00256": "bigint", "f00262": "bigint", "f00355": "bigint", "f00178": "float", "f00382": "bigint", "f00364": "bigint", "f00358": "bigint", "f00067": "float", "f00271": "bigint", "f00286": "bigint", "f00244": "bigint", "f00379": "bigint", "f00337": "bigint", "f00151": "float", "f00259": "bigint", "f00073": "float", "f00172": "float", "f00166": "float", "f00385": "bigint", "f00088": "float", "f00139": "float", "f00343": "bigint", "f00052": "float", "f00046": "float", "f00187": "float", "f00238": "bigint", "f00250": "bigint", "f00370": "bigint", "f00265": "bigint", "f00145": "float", "f00028": "float", "f00169": "float", "f00232": "bigint", "f00352": "bigint", "f00127": "float", "f00055": "float", "f00310": "bigint", "f00154": "float", "f00049": "float", "f00253": "bigint", "f00367": "bigint", "f00331": "bigint", "f00325": "bigint", "f00034": "float", "f00247": "bigint", "f00319": "bigint", "f00160": "float", "f00346": "bigint", "f00040": "float", "f00148": "float", "f00226": "bigint", "f00061": "float", "f00268": "bigint", "f00133": "float", "f00022": "float", "f00142": "float", "f00037": "float", "f00241": "bigint", "f00334": "bigint", "f00229": "bigint", "f00043": "float", "f00121": "float", "f00001": "float", "f00115": "float", "f00307": "bigint", "f00016": "float", "f00220": "bigint", "f00214": "bigint", "f00109": "float", "f00328": "bigint", "f00136": "float", "f00340": "bigint", "f00349": "bigint", "f00100": "float", "f00235": "bigint", "f00313": "bigint", "f00208": "bigint", "f00186": "float", "f00217": "bigint", "f00025": "float", "f00390": "bigint", "f00384": "bigint", "f00093": "float", "f00285": "bigint", "f00103": "float", "f00202": "bigint", "f00192": "float", "f00031": "float", "f00124": "float", "f00130": "float", "f00019": "float", "f00087": "float", "f00301": "bigint", "f00010": "float", "f00004": "float", "f00223": "bigint", "f00118": "float", "f00291": "bigint", "f00322": "bigint", "f00316": "bigint", "f00013": "float", "f00189": "float", "f00195": "float", "f00112": "float", "f00081": "float", "f00007": "float", "f00211": "bigint", "f00180": "float", "f00366": "bigint", "f00075": "float", "f00069": "float", "f00288": "bigint", "f00174": "float", "f00387": "bigint", "f00205": "bigint", "f00060": "float", "f00304": "bigint", "f00273": "bigint", "f00294": "bigint", "f00168": "float", "f00372": "bigint", "f00267": "bigint", "f00106": "float", "f00096": "float", "f00360": "bigint", "f00369": "bigint", "f00183": "float", "f00141": "float", "f00090": "float", "f00354": "bigint", "f00249": "bigint", "f00084": "float", "f00063": "float", "f00198": "bigint", "f00297": "bigint", "f00156": "float", "f00255": "bigint", "f00078": "float", "f00282": "bigint", "f00177": "float", "f00042": "float", "f00381": "bigint", "f00240": "bigint", "f00276": "bigint", "f00099": "float", "f00162": "float", "f00348": "bigint", "f00057": "float", "f00261": "bigint", "f00375": "bigint", "f00039": "float", "f00237": "bigint", "f00051": "float", "f00243": "bigint", "f00357": "bigint", "f00150": "float", "f00270": "bigint", "f00024": "float", "f00165": "float", "f00159": "float", "f00363": "bigint", "f00258": "bigint", "f00123": "float", "f00378": "bigint", "f00321": "bigint", "f00336": "bigint", "f00342": "bigint", "f00045": "float", "f00264": "bigint", "f00072": "float", "f00171": "float", "f00222": "bigint", "f00030": "float", "f00066": "float", "f00138": "float", "f00144": "float", "f00279": "bigint", "f00153": "float", "f00012": "float", "f00111": "float", "f00027": "float", "f00033": "float", "f00147": "float", "f00246": "bigint", "f00132": "float", "f00345": "bigint", "f00204": "bigint", "f00048": "float", "f00231": "bigint", "f00303": "bigint", "f00126": "float", "f00006": "float", "f00330": "bigint", "f00339": "bigint", "f00219": "bigint", "f00225": "bigint", "f00252": "bigint", "f00324": "bigint", "f00351": "bigint", "f00210": "bigint", "f00105": "float", "f00054": "float", "f00318": "bigint"}, "count": 12089, "sample": [[0, 7, 0, 0.0, 0, 0.0, 0.0, 0, 5.0, 0.0, 252.0, 0, 0, 49.0, 203.0, 241.0, 0, 255.0, 1, 0, 0.0, 0, 0, 0, 6, 0.0, 0, 0, 3.0, 0.0, 0, 0.0, 208.0, 0, 0, 252.0, 0, 0, 228.0, 0, 0, 0.0, 0, 0, 0.0, 252.0, 173.0, 0, 16.0, 0, 59.0, 0, 0.0, 0, 0.0, 0.0, 252.0, 0.0, 0, 0, 244.0, 0.0, 0, 0, 231.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 3, 7.0, 0, 29.0, 0.0, 89.0, 0.0, 0.0, 0, 252.0, 3.0, 228.0, 0, 205.0, 0.0, 0, 0, 0, 18.0, 0.0, 0.0, 253.0, 0.0, 0, 0.0, 252.0, 227.0, 0, 0.0, 0.0, 0, 0, 37.0, 0, 0, 17.0, 0, 0, 0, 0, 0, 0.0, 252.0, 0, 0, 0, 12, 0.0, 0, 200.0, 0.0, 0.0, 117.0, 0.0, 0, 252.0, 0.0, 252.0, 0, 72.0, 0, 0, 4, 0, 180.0, 252.0, 0, 0, 53.0, 0, 0.0, 245.0, 9, 0.0, 0, 65.0, 0, 0, 0, 0, 0, 0, 124.0, 87.0, 0, 253.0, 0, 0, 0.0, 0.0, 0.0, 49.0, 21.0, 0, 0.0, 0.0, 129.0, 0.0, 18.0, 78.0, 2, 0, 0, 135.0, 180.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 0.0, 0, 0, 0, 0, 252.0, 0, 0, 0, 125.0, 0, 0, 0, 0, 0, 170.0, 0, 252.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 231.0, 0.0, 0, 0, 0, 0, 105.0, 0.0, 0.0, 6, 0, 216.0, 0.0, 0, 126.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 243.0, 88.0, 0, 0.0, 0, 241.0, 0.0, 0.0, 54.0, 0, 0, 2, 242.0, 106.0, 0.0, 0.0, 0, 253.0, 0, 0, 0.0, 0, 223.0, 0, 0, 247.0, 0, 0, 3, 0.0, 0, 0.0, 0, 0, 252.0, 0, 252.0, 10, 0.0, 0.0, 53.0, 14.0, 35.0, 0.0, 0, 10.0, 0.0, 0, 136.0, 0, 0, 0, 253.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 252.0, 0, 252.0, 0.0, 0, 252.0, 0, 14, 0.0, 0, 0, 0, 0.0, 0, 0, 66.0, 0.0, 0, 0, 0.0, 0.0, 5.0, 0, 0, 0.0, 6.0, 0, 0, 0.0, 0, 0.0, 0, 216.0, 170.0, 0, 0, 0, 253.0, 180.0, 0, 0.0, 0, 0, 252.0, 0, 0.0, 0, 0, 73.0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 252.0, 0, 252.0, 0.0, 0, 0.0, 252.0, 0.0, 0.0, 0, 252.0, 179.0, 0.0, 0.0, 0.0, 242.0, 0, 163.0, 0, 13, 6.0, 7, 0, 252.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 184.0, 0.0, 0], [0, 8, 0, 0.0, 0, 252.0, 222.0, 0, 45.0, 0.0, 0.0, 9, 0, 0.0, 0.0, 0.0, 0, 252.0, 13, 0, 0.0, 0, 0, 0, 6, 0.0, 1, 0, 0.0, 0.0, 0, 252.0, 44.0, 0, 0, 0.0, 0, 0, 177.0, 0, 0, 0.0, 0, 4, 0.0, 0.0, 252.0, 0, 0.0, 0, 44.0, 0, 0.0, 0, 0.0, 0.0, 252.0, 0.0, 0, 3, 0.0, 0.0, 0, 0, 61.0, 0.0, 0, 6, 0, 0, 0.0, 0, 0, 0, 0, 0, 14, 0.0, 0, 98.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 92.0, 253.0, 0, 29.0, 0.0, 9, 0, 0, 0.0, 0.0, 252.0, 252.0, 0.0, 13, 0.0, 253.0, 253.0, 0, 0.0, 0.0, 2, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 31.0, 0, 11, 0, 12, 0.0, 0, 0.0, 0.0, 0.0, 74.0, 0.0, 0, 5.0, 0.0, 0.0, 0, 74.0, 0, 0, 9, 10, 0.0, 0.0, 0, 1, 252.0, 0, 0.0, 252.0, 7, 0.0, 0, 86.0, 0, 0, 0, 0, 5, 13, 18.0, 0.0, 0, 253.0, 0, 0, 0.0, 45.0, 0.0, 0.0, 0.0, 0, 252.0, 0.0, 252.0, 0.0, 44.0, 0.0, 11, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 252.0, 0, 0, 11, 0, 0.0, 0, 0, 0, 52.0, 0, 2, 0, 0, 0, 0.0, 8, 252.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 253.0, 65.0, 13, 0, 0, 8, 0.0, 0.0, 0.0, 13, 0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 253.0, 9.0, 0, 0.0, 0, 0.0, 0.0, 0.0, 223.0, 2, 0, 6, 253.0, 0.0, 0.0, 0.0, 0, 252.0, 0, 5, 0.0, 0, 0.0, 0, 0, 15.0, 13, 0, 7, 243.0, 0, 0.0, 0, 0, 0.0, 0, 74.0, 10, 0.0, 0.0, 0.0, 252.0, 0.0, 0.0, 0, 252.0, 0.0, 0, 0.0, 3, 0, 0, 252.0, 0.0, 0.0, 0.0, 0.0, 0.0, 13, 0.0, 0, 74.0, 44.0, 4, 183.0, 0, 7, 0.0, 0, 0, 0, 0.0, 0, 3, 0.0, 0.0, 0, 0, 239.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 242.0, 0, 0.0, 0, 0.0, 255.0, 0, 7, 0, 0.0, 0.0, 0, 0.0, 11, 0, 253.0, 12, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 74.0, 0, 5, 0.0, 0, 0, 0, 0, 253.0, 9, 143.0, 0.0, 0, 0.0, 123.0, 0.0, 0.0, 0, 0.0, 252.0, 0.0, 0.0, 0.0, 75.0, 0, 0.0, 0, 7, 0.0, 12, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 14, 0.0, 0.0, 0], [0, 10, 0, 0.0, 0, 254.0, 0.0, 0, 0.0, 0.0, 0.0, 2, 0, 0.0, 0.0, 0.0, 0, 254.0, 15, 0, 0.0, 0, 0, 0, 0, 0.0, 2, 0, 0.0, 0.0, 0, 139.0, 1.0, 0, 0, 0.0, 0, 0, 171.0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 214.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0.0, 219.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 10, 0, 0, 0.0, 0, 0, 0, 0, 0, 16, 0.0, 0, 240.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 206.0, 89.0, 0, 215.0, 0.0, 1, 0, 0, 0.0, 0.0, 34.0, 254.0, 0.0, 15, 0.0, 240.0, 0.0, 0, 0.0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 7, 0, 9, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 19.0, 0.0, 0.0, 0, 0.0, 0, 0, 0, 11, 0.0, 0.0, 0, 0, 110.0, 0, 0.0, 254.0, 11, 0.0, 0, 254.0, 0, 0, 0, 0, 0, 10, 89.0, 0.0, 0, 254.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 254.0, 0.0, 254.0, 0.0, 0.0, 0.0, 16, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 254.0, 0, 0, 5, 0, 36.0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0, 254.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 171.0, 0.0, 14, 0, 0, 12, 0.0, 0.0, 0.0, 5, 0, 138.0, 0.0, 0, 25.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 73.0, 90.0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 93.0, 0.0, 0.0, 0.0, 0, 254.0, 0, 0, 0.0, 0, 0.0, 0, 0, 254.0, 15, 0, 13, 8.0, 0, 0.0, 0, 0, 0.0, 0, 28.0, 4, 0.0, 0.0, 0.0, 116.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0, 0, 0, 254.0, 0.0, 0.0, 0.0, 0.0, 0.0, 14, 51.0, 0, 31.0, 0.0, 0, 164.0, 0, 16, 0.0, 0, 0, 0, 0.0, 0, 3, 0.0, 0.0, 0, 0, 254.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 254.0, 0, 0.0, 0, 63.0, 89.0, 0, 0, 0, 7.0, 0.0, 0, 0.0, 5, 0, 0.0, 14, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 254.0, 13, 128.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 246.0, 0.0, 0.0, 0.0, 177.0, 0, 0.0, 0, 15, 0.0, 7, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 15, 0.0, 0.0, 0], [0, 2, 0, 22.0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 16, 0, 0.0, 0.0, 0.0, 0, 254.0, 15, 0, 0.0, 3, 0, 0, 0, 0.0, 3, 0, 0.0, 0.0, 9, 137.0, 0.0, 0, 0, 0.0, 0, 0, 254.0, 0, 0, 0.0, 0, 4, 0.0, 0.0, 192.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0.0, 254.0, 0.0, 5, 0, 0.0, 254.0, 0, 0, 0.0, 0.0, 0, 12, 0, 0, 0.0, 0, 0, 0, 0, 0, 16, 254.0, 0, 0.0, 0.0, 250.0, 0.0, 0.0, 8, 116.0, 0.0, 50.0, 0, 209.0, 0.0, 7, 0, 0, 126.0, 0.0, 188.0, 254.0, 2.0, 9, 0.0, 253.0, 0.0, 13, 0.0, 0.0, 0, 0, 0.0, 14, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 13, 0, 8, 0.0, 0, 0.0, 0.0, 0.0, 254.0, 0.0, 0, 0.0, 0.0, 254.0, 0, 254.0, 0, 0, 0, 14, 0.0, 0.0, 0, 5, 181.0, 0, 140.0, 24.0, 3, 0.0, 0, 0.0, 0, 0, 4, 0, 2, 12, 0.0, 254.0, 0, 254.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 23.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 3.0, 0, 0, 13, 0, 15.0, 0, 0, 0, 0.0, 2, 0, 3, 0, 0, 0.0, 2, 200.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 254.0, 254.0, 9, 0, 0, 12, 0.0, 0.0, 0.0, 15, 0, 0.0, 0.0, 0, 0.0, 191.0, 0, 0, 0, 0, 0.0, 0, 0, 254.0, 0, 30.0, 25.0, 0, 0.0, 11, 254.0, 0.0, 0.0, 0.0, 14, 0, 0, 155.0, 0.0, 0.0, 0.0, 0, 254.0, 0, 15, 0.0, 0, 0.0, 0, 0, 0.0, 9, 0, 0, 254.0, 4, 0.0, 0, 0, 0.0, 0, 254.0, 0, 0.0, 0.0, 0.0, 141.0, 252.0, 0.0, 0, 58.0, 0.0, 0, 0.0, 3, 0, 0, 254.0, 209.0, 0.0, 0.0, 0.0, 0.0, 6, 0.0, 0, 254.0, 0.0, 1, 0.0, 0, 16, 0.0, 0, 0, 4, 0.0, 0, 12, 154.0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 1, 0.0, 0, 118.0, 0, 254.0, 73.0, 0, 15, 0, 0.0, 61.0, 0, 0.0, 13, 0, 0.0, 8, 0.0, 8, 0, 86.0, 4, 0.0, 0.0, 254.0, 0, 0, 0.0, 0, 0, 0, 0, 254.0, 13, 91.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 234.0, 0.0, 0.0, 0.0, 0.0, 0, 254.0, 0, 15, 254.0, 6, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 1, 254.0, 0.0, 0], [0, 6, 0, 0.0, 0, 220.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 228.0, 247.0, 0, 0.0, 12, 0, 0.0, 0, 0, 0, 0, 0.0, 4, 0, 0.0, 0.0, 0, 0.0, 254.0, 0, 0, 0.0, 0, 0, 254.0, 0, 0, 0.0, 0, 0, 0.0, 214.0, 154.0, 0, 254.0, 0, 203.0, 0, 0.0, 0, 0.0, 33.0, 254.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 0.0, 160.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 13, 223.0, 0, 244.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 254.0, 0.0, 0, 4.0, 0.0, 0, 0, 0, 0.0, 67.0, 0.0, 254.0, 225.0, 8, 0.0, 98.0, 0.0, 0, 0.0, 0.0, 0, 0, 0.0, 0, 0, 146.0, 0, 0, 0, 0, 0, 0.0, 31.0, 0, 0, 0, 14, 0.0, 0, 28.0, 0.0, 0.0, 208.0, 0.0, 0, 255.0, 0.0, 0.0, 0, 0.0, 0, 0, 0, 0, 254.0, 254.0, 0, 0, 0.0, 0, 0.0, 206.0, 7, 0.0, 0, 254.0, 0, 0, 0, 0, 0, 0, 179.0, 223.0, 0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 240.0, 0, 64.0, 52.0, 254.0, 0.0, 212.0, 9.0, 14, 0, 0, 137.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 50.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 137.0, 0, 0, 0, 0, 0, 0.0, 0, 254.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 241.0, 254.0, 0.0, 0, 0, 0, 0, 0.0, 0.0, 0.0, 12, 0, 216.0, 0.0, 0, 137.0, 207.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 0.0, 49.0, 0, 0.0, 0, 0.0, 20.0, 0.0, 0.0, 0, 0, 0, 35.0, 179.0, 0.0, 0.0, 0, 39.0, 0, 0, 0.0, 0, 0.0, 0, 0, 254.0, 12, 0, 11, 0.0, 0, 39.0, 0, 0, 254.0, 0, 50.0, 9, 0.0, 0.0, 60.0, 12.0, 56.0, 0.0, 0, 0.0, 0.0, 0, 185.0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3, 8.0, 0, 251.0, 203.0, 0, 254.0, 0, 9, 0.0, 0, 0, 0, 0.0, 0, 0, 0.0, 254.0, 0, 0, 247.0, 0.0, 9.0, 0, 0, 0.0, 0.0, 0, 0, 232.0, 0, 127.0, 0, 0.0, 7.0, 0, 0, 0, 250.0, 0.0, 0, 0.0, 0, 0, 0.0, 4, 254.0, 0, 0, 0.0, 0, 124.0, 0.0, 0.0, 0, 0, 67.0, 0, 0, 0, 0, 254.0, 0, 254.0, 0.0, 0, 0.0, 82.0, 0.0, 0.0, 0, 4.0, 0.0, 0.0, 0.0, 0.0, 222.0, 0, 0.0, 0, 7, 157.0, 7, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 9, 0.0, 0.0, 0], [0, 15, 0, 0.0, 0, 31.0, 5.0, 0, 0.0, 0.0, 193.0, 15, 0, 0.0, 0.0, 253.0, 0, 245.0, 14, 0, 0.0, 0, 0, 0, 0, 0.0, 5, 0, 0.0, 122.0, 11, 253.0, 0.0, 0, 0, 236.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 253.0, 0.0, 0, 189.0, 0, 188.0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0.0, 253.0, 0, 0, 12.0, 0.0, 0, 4, 0, 0, 0.0, 0, 0, 0, 0, 0, 15, 0.0, 0, 131.0, 0.0, 253.0, 0.0, 0.0, 0, 205.0, 252.0, 192.0, 0, 253.0, 0.0, 1, 0, 0, 253.0, 0.0, 253.0, 115.0, 0.0, 14, 0.0, 0.0, 253.0, 2, 0.0, 0.0, 0, 0, 0.0, 12, 0, 186.0, 0, 0, 0, 0, 0, 0.0, 220.0, 0, 12, 0, 8, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 1, 218.0, 0.0, 0.0, 4, 174.0, 0, 0, 0, 13, 253.0, 225.0, 0, 0, 217.0, 0, 0.0, 253.0, 15, 0.0, 0, 0.0, 0, 0, 0, 0, 0, 14, 222.0, 0.0, 0, 250.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 253.0, 0.0, 0.0, 0.0, 0.0, 47.0, 15, 0, 0, 107.0, 94.0, 0.0, 253.0, 0, 0, 0, 0.0, 0, 222.0, 0, 0, 5, 0, 253.0, 0, 0, 0, 253.0, 0, 0, 1, 0, 0, 59.0, 0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0.0, 253.0, 13, 0, 0, 6, 48.0, 0.0, 0.0, 9, 0, 0.0, 0.0, 0, 128.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 253.0, 0, 253.0, 253.0, 0, 0.0, 3, 205.0, 0.0, 0.0, 124.0, 4, 0, 0, 0.0, 253.0, 0.0, 0.0, 0, 245.0, 0, 14, 0.0, 0, 58.0, 0, 0, 0.0, 14, 0, 15, 253.0, 5, 0.0, 0, 0, 253.0, 0, 0.0, 2, 0.0, 0.0, 0.0, 42.0, 0.0, 0.0, 0, 41.0, 0.0, 0, 41.0, 0, 0, 0, 253.0, 253.0, 0.0, 0.0, 0.0, 0.0, 14, 222.0, 0, 0.0, 25.0, 0, 152.0, 0, 15, 0.0, 0, 0, 0, 0.0, 0, 4, 0.0, 13.0, 0, 0, 253.0, 0.0, 0.0, 0, 0, 0.0, 11.0, 0, 0, 131.0, 0, 0.0, 0, 253.0, 105.0, 0, 10, 0, 0.0, 253.0, 0, 0.0, 5, 0, 253.0, 13, 0.0, 2, 0, 150.0, 0, 0.0, 0.0, 253.0, 0, 0, 22.0, 0, 0, 0, 0, 0.0, 12, 0.0, 0.0, 0, 0.0, 253.0, 0.0, 0.0, 0, 0.0, 253.0, 0.0, 0.0, 0.0, 253.0, 0, 205.0, 0, 14, 0.0, 5, 0, 0.0, 0.0, 0, 0, 1, 0, 0, 0, 0, 14, 0.0, 0.0, 0], [0, 10, 0, 0.0, 0, 233.0, 0.0, 0, 0.0, 0.0, 0.0, 15, 0, 0.0, 0.0, 0.0, 0, 253.0, 14, 2, 0.0, 0, 0, 0, 8, 0.0, 6, 0, 0.0, 0.0, 4, 253.0, 7.0, 0, 0, 21.0, 0, 0, 253.0, 0, 0, 0.0, 0, 6, 0.0, 0.0, 253.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0.0, 253.0, 0.0, 3, 4, 0.0, 138.0, 0, 0, 211.0, 0.0, 0, 11, 0, 0, 0.0, 0, 0, 0, 0, 0, 15, 59.0, 0, 37.0, 0.0, 0.0, 0.0, 0.0, 2, 0.0, 151.0, 87.0, 0, 59.0, 0.0, 10, 0, 0, 0.0, 0.0, 253.0, 253.0, 0.0, 14, 0.0, 253.0, 0.0, 10, 0.0, 0.0, 3, 0, 0.0, 7, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 12, 0, 13, 0.0, 0, 0.0, 0.0, 0.0, 253.0, 0.0, 0, 0.0, 0.0, 253.0, 0, 253.0, 0, 0, 10, 13, 0.0, 0.0, 0, 3, 201.0, 0, 49.0, 211.0, 15, 0.0, 0, 32.0, 0, 0, 1, 0, 5, 14, 36.0, 250.0, 0, 253.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 253.0, 0.0, 238.0, 0.0, 0.0, 0.0, 15, 0, 0, 0.0, 0.0, 0.0, 0.0, 3, 0, 0, 0.0, 0, 253.0, 0, 1, 12, 0, 36.0, 0, 0, 0, 0.0, 0, 2, 0, 0, 0, 0.0, 9, 253.0, 66.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 253.0, 253.0, 13, 0, 0, 11, 0.0, 0.0, 0.0, 14, 0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 138.0, 0, 87.0, 0.0, 0, 0.0, 7, 6.0, 0.0, 0.0, 0.0, 11, 0, 7, 248.0, 0.0, 0.0, 0.0, 0, 253.0, 0, 14, 0.0, 0, 0.0, 0, 0, 62.0, 14, 0, 11, 253.0, 0, 0.0, 0, 0, 0.0, 0, 253.0, 11, 0.0, 0.0, 0.0, 253.0, 230.0, 0.0, 0, 18.0, 0.0, 0, 0.0, 7, 0, 0, 253.0, 0.0, 0.0, 0.0, 0.0, 0.0, 14, 26.0, 0, 253.0, 0.0, 5, 211.0, 0, 15, 0.0, 0, 0, 2, 0.0, 0, 7, 0.0, 0.0, 0, 0, 222.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 203.0, 0, 0.0, 0, 36.0, 87.0, 0, 14, 0, 0.0, 0.0, 0, 0.0, 12, 0, 36.0, 13, 0.0, 3, 0, 0.0, 0, 0.0, 0.0, 253.0, 0, 6, 0.0, 0, 0, 0, 0, 253.0, 12, 152.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 253.0, 0.0, 0.0, 0.0, 0.0, 0, 150.0, 0, 14, 138.0, 13, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 14, 60.0, 0.0, 0], [0, 15, 0, 101.0, 0, 79.0, 0.0, 0, 0.0, 0.0, 0.0, 8, 0, 0.0, 244.0, 0.0, 0, 0.0, 12, 0, 0.0, 5, 0, 0, 0, 0.0, 7, 0, 0.0, 0.0, 4, 0.0, 253.0, 0, 2, 253.0, 0, 0, 253.0, 0, 0, 0.0, 1, 0, 0.0, 0.0, 30.0, 0, 0.0, 0, 0.0, 4, 0.0, 0, 0.0, 0.0, 253.0, 0.0, 3, 0, 253.0, 0.0, 0, 0, 0.0, 0.0, 0, 11, 0, 0, 0.0, 0, 1, 0, 0, 0, 5, 0.0, 0, 137.0, 0.0, 0.0, 0.0, 0.0, 9, 0.0, 141.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 182.0, 0.0, 14, 0.0, 198.0, 0.0, 12, 0.0, 0.0, 0, 0, 0.0, 7, 0, 58.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 8, 0, 0, 0.0, 0, 253.0, 0.0, 0.0, 247.0, 0.0, 6, 0.0, 0.0, 0.0, 2, 0.0, 0, 0, 0, 13, 0.0, 0.0, 1, 2, 0.0, 0, 251.0, 0.0, 12, 0.0, 2, 197.0, 0, 0, 4, 0, 0, 8, 253.0, 0.0, 0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 224.0, 0, 8.0, 0.0, 239.0, 0.0, 99.0, 0.0, 15, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 2, 0.0, 0, 0, 4, 0, 216.0, 0, 0, 0, 0.0, 5, 0, 7, 0, 0, 253.0, 0, 253.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 253.0, 0.0, 13, 0, 0, 11, 0.0, 0.0, 0.0, 0, 0, 253.0, 0.0, 0, 242.0, 0.0, 0, 0, 0, 0, 0.0, 2, 0, 0.0, 0, 0.0, 0.0, 0, 0.0, 10, 0.0, 0.0, 0.0, 0.0, 13, 0, 0, 99.0, 0.0, 0.0, 0.0, 0, 22.0, 0, 8, 0.0, 0, 0.0, 0, 0, 253.0, 14, 0, 15, 0.0, 2, 0.0, 0, 0, 0.0, 0, 23.0, 0, 0.0, 0.0, 213.0, 0.0, 253.0, 0.0, 1, 0.0, 0.0, 0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 14, 253.0, 0, 191.0, 0.0, 0, 0.0, 0, 1, 0.0, 0, 3, 3, 0.0, 0, 11, 0.0, 117.0, 0, 0, 62.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 3, 16.0, 0, 0.0, 0, 0.0, 3.0, 0, 14, 0, 253.0, 0.0, 0, 0.0, 0, 0, 0.0, 13, 0.0, 10, 0, 86.0, 7, 0.0, 0.0, 0.0, 0, 0, 169.0, 0, 0, 0, 0, 253.0, 9, 253.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 253.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3, 0.0, 0, 0, 129.0, 0, 1, 253.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 14, 0.0, 0.0, 0], [0, 0, 0, 3.0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 15, 0, 0.0, 195.0, 0.0, 0, 253.0, 0, 0, 0.0, 0, 0, 0, 0, 0.0, 8, 0, 0.0, 0.0, 11, 223.0, 192.0, 0, 0, 0.0, 0, 0, 253.0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0.0, 253.0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0, 253.0, 0, 184.0, 0.0, 253.0, 0.0, 0.0, 0, 253.0, 253.0, 61.0, 0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 253.0, 4.0, 0, 0.0, 176.0, 42.0, 6, 0.0, 0.0, 0, 0, 0.0, 12, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 172.0, 0.0, 0.0, 247.0, 0.0, 1, 0.0, 0.0, 112.0, 1, 0.0, 0, 0, 0, 2, 0.0, 0.0, 0, 0, 253.0, 0, 169.0, 0.0, 0, 0.0, 0, 0.0, 0, 0, 0, 0, 0, 14, 144.0, 203.0, 0, 253.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 56.0, 0, 243.0, 0.0, 0.0, 0.0, 59.0, 0.0, 2, 0, 0, 0.0, 0.0, 0.0, 96.0, 0, 0, 0, 0.0, 0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 0.0, 0, 0, 3, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 110.0, 250.0, 1, 0, 0, 0, 0.0, 0.0, 0.0, 0, 0, 17.0, 0.0, 0, 253.0, 195.0, 0, 0, 0, 0, 0.0, 0, 0, 164.0, 0, 61.0, 0.0, 0, 0.0, 0, 248.0, 0.0, 0.0, 0.0, 7, 0, 0, 83.0, 0.0, 0.0, 0.0, 0, 253.0, 0, 14, 0.0, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 223.0, 6, 0.0, 0, 0, 0.0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 253.0, 0.0, 0, 174.0, 0.0, 0, 0.0, 0, 0, 0, 253.0, 253.0, 0.0, 0.0, 0.0, 0.0, 14, 0.0, 0, 50.0, 0.0, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0.0, 0, 0, 229.0, 0.0, 0, 0, 253.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 62.0, 0, 42.0, 0, 0.0, 61.0, 0, 6, 0, 57.0, 253.0, 0, 0.0, 0, 0, 61.0, 0, 0.0, 6, 0, 0.0, 0, 0.0, 0.0, 85.0, 0, 0, 0.0, 0, 0, 0, 0, 79.0, 0, 30.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 192.0, 253.0, 0.0, 0.0, 0.0, 0.0, 0, 58.0, 0, 0, 253.0, 0, 0, 204.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 7, 253.0, 0.0, 0], [0, 0, 0, 0.0, 0, 72.0, 0.0, 0, 0.0, 0.0, 0.0, 15, 0, 0.0, 40.0, 0.0, 0, 0.0, 0, 0, 0.0, 2, 0, 0, 0, 0.0, 9, 0, 0.0, 0.0, 0, 254.0, 254.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 252.0, 0, 0.0, 0, 142.0, 0, 0.0, 0, 0.0, 0.0, 253.0, 0.0, 4, 0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 7, 0, 0, 0.0, 0, 0, 0, 0, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 223.0, 0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 252.0, 0.0, 0.0, 0, 0.0, 61.0, 0.0, 0, 0.0, 0.0, 0, 2, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 203.0, 0, 0, 0, 7, 0.0, 0.0, 0, 4, 113.0, 0, 0.0, 0.0, 0, 0.0, 0, 0.0, 0, 0, 4, 0, 0, 9, 0.0, 0.0, 0, 61.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 102.0, 0.0, 172.0, 0.0, 243.0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 152.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 62.0, 0, 0, 0, 0, 0, 0.0, 0, 254.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 1, 0.0, 0, 252.0, 0.0, 0, 0.0, 7, 0.0, 0.0, 0.0, 0.0, 8, 0, 0, 102.0, 0.0, 0.0, 0.0, 0, 0.0, 0, 7, 0.0, 0, 0.0, 0, 0, 111.0, 0, 0, 0, 213.0, 0, 0.0, 0, 0, 0.0, 0, 203.0, 0, 0.0, 0.0, 0.0, 253.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 3, 1, 0, 224.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2, 0.0, 0, 82.0, 203.0, 0, 0.0, 0, 0, 0.0, 0, 0, 6, 0.0, 0, 11, 0.0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 0.0, 0, 0.0, 0, 0.0, 102.0, 0, 14, 0, 71.0, 0.0, 0, 0.0, 0, 0, 152.0, 0, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 81.0, 0, 0, 0.0, 0, 2, 0, 0, 41.0, 0, 253.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 253.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0.0, 0], [0, 9, 0, 0.0, 0, 215.0, 0.0, 0, 0.0, 0.0, 0.0, 14, 0, 0.0, 0.0, 0.0, 0, 252.0, 13, 0, 0.0, 0, 0, 0, 3, 0.0, 10, 0, 0.0, 0.0, 0, 253.0, 53.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0, 3, 0.0, 0.0, 253.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0.0, 253.0, 0.0, 0, 2, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 5, 0, 0, 0.0, 0, 0, 0, 0, 0, 14, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 113.0, 0.0, 0, 255.0, 0.0, 10, 0, 0, 0.0, 0.0, 253.0, 63.0, 0.0, 13, 0.0, 253.0, 0.0, 0, 0.0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 11, 0, 12, 0.0, 0, 0.0, 0.0, 0.0, 12.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 89.0, 0, 0, 6, 11, 0.0, 0.0, 0, 0, 112.0, 0, 0.0, 253.0, 5, 0.0, 0, 19.0, 0, 0, 0, 0, 5, 13, 114.0, 0.0, 0, 252.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 253.0, 0.0, 227.0, 0.0, 0.0, 0.0, 15, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 252.0, 0, 0, 11, 0, 0.0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 7, 252.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 114.0, 15.0, 12, 0, 0, 9, 0.0, 0.0, 0.0, 14, 0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 4, 0, 2, 229.0, 0.0, 0.0, 0.0, 0, 239.0, 0, 6, 0.0, 0, 0.0, 0, 0, 22.0, 13, 0, 13, 204.0, 0, 0.0, 0, 0, 0.0, 0, 136.0, 10, 0.0, 0.0, 0.0, 253.0, 0.0, 0.0, 0, 25.0, 0.0, 0, 0.0, 3, 0, 0, 174.0, 0.0, 0.0, 0.0, 0.0, 0.0, 13, 63.0, 0, 27.0, 0.0, 4, 92.0, 0, 6, 0.0, 0, 0, 0, 0.0, 0, 4, 0.0, 0.0, 0, 0, 222.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 107.0, 0, 0.0, 0, 27.0, 126.0, 0, 8, 0, 0.0, 0.0, 0, 0.0, 11, 0, 0.0, 13, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 167.0, 0, 2, 0.0, 0, 0, 0, 0, 253.0, 9, 177.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 112.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0, 14, 0.0, 12, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 13, 0.0, 0.0, 0], [0, 6, 0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 10, 0, 0.0, 0.0, 0.0, 0, 0.0, 15, 0, 0.0, 0, 0, 0, 0, 0.0, 11, 0, 0.0, 0.0, 0, 254.0, 0.0, 0, 0, 0.0, 0, 0, 179.0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 100.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0.0, 80.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 4, 0, 0, 0.0, 0, 0, 0, 0, 0, 11, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 254.0, 0.0, 0, 0, 0, 5.0, 0.0, 254.0, 0.0, 0.0, 15, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 10, 0, 2, 0.0, 0, 0.0, 0.0, 0.0, 239.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 239.0, 0, 0, 0, 14, 0.0, 0.0, 0, 0, 0.0, 0, 0.0, 64.0, 11, 0.0, 0, 0.0, 0, 0, 0, 0, 0, 15, 0.0, 20.0, 0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 188.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 150.0, 0, 0, 5, 0, 38.0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 80.0, 20.0, 15, 0, 0, 7, 0.0, 0.0, 0.0, 3, 0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 0.0, 140.0, 0, 0.0, 1, 0.0, 0.0, 0.0, 0.0, 4, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0, 3, 0.0, 0, 0.0, 0, 0, 0.0, 15, 0, 5, 209.0, 0, 0.0, 0, 0, 0.0, 0, 239.0, 0, 0.0, 0.0, 0.0, 234.0, 239.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 12, 0.0, 0, 244.0, 0.0, 0, 0.0, 0, 17, 0.0, 0, 0, 0, 0.0, 0, 2, 0.0, 0.0, 0, 0, 34.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 3.0, 0, 0.0, 0, 181.0, 0.0, 0, 9, 0, 0.0, 0.0, 0, 0.0, 3, 0, 0.0, 14, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 129.0, 0, 0, 0.0, 0, 0, 0, 0, 0.0, 9, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 0, 0.0, 0, 11, 0.0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 8, 0.0, 0.0, 0], [0, 5, 0, 0.0, 0, 252.0, 76.0, 0, 0.0, 0.0, 0.0, 12, 0, 0.0, 0.0, 0.0, 0, 252.0, 13, 0, 0.0, 2, 0, 0, 0, 0.0, 12, 0, 0.0, 0.0, 0, 253.0, 47.0, 0, 0, 0.0, 0, 0, 128.0, 0, 0, 0.0, 0, 5, 0.0, 0.0, 252.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0.0, 252.0, 0.0, 5, 0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 11, 0, 0, 0.0, 0, 0, 0, 0, 0, 7, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 2, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 252.0, 252.0, 0.0, 9, 0.0, 253.0, 0.0, 0, 0.0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 11, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 178.0, 0, 0, 0, 12, 0.0, 0.0, 0, 6, 221.0, 0, 0.0, 0.0, 12, 0.0, 0, 90.0, 0, 0, 2, 0, 1, 13, 0.0, 0.0, 0, 86.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 222.0, 0.0, 252.0, 0.0, 0.0, 0.0, 3, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 252.0, 0, 0, 11, 0, 154.0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0, 252.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 148.0, 0.0, 13, 0, 0, 10, 0.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 0, 0.0, 5, 0.0, 0.0, 0.0, 0.0, 7, 0, 0, 100.0, 0.0, 0.0, 0.0, 0, 252.0, 0, 5, 0.0, 0, 0.0, 0, 0, 234.0, 13, 0, 2, 243.0, 0, 0.0, 0, 0, 0.0, 0, 199.0, 0, 0.0, 0.0, 0.0, 252.0, 0.0, 0.0, 0, 211.0, 0.0, 0, 0.0, 6, 0, 0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10, 0.0, 0, 74.0, 0.0, 0, 0.0, 0, 7, 0.0, 0, 0, 4, 0.0, 0, 10, 0.0, 0.0, 0, 0, 36.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 122.0, 0, 0.0, 0, 87.0, 0.0, 0, 13, 0, 34.0, 0.0, 0, 0.0, 5, 0, 0.0, 9, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 126.0, 0, 0, 0.0, 0, 0, 0, 0, 253.0, 11, 252.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 43.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 4, 0.0, 0.0, 0], [0, 16, 0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 11, 0, 0.0, 0.0, 0.0, 0, 87.0, 4, 0, 0.0, 0, 0, 0, 0, 0.0, 13, 0, 0.0, 116.0, 8, 48.0, 0.0, 0, 0, 254.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0, 249.0, 0, 192.0, 2, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 124.0, 16.0, 0, 0, 0.0, 0.0, 0, 4, 0, 0, 0.0, 0, 0, 0, 0, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 4, 0.0, 76.0, 252.0, 0, 0.0, 0.0, 0, 0, 0, 196.0, 0.0, 0.0, 0.0, 0.0, 9, 0.0, 0.0, 35.0, 13, 0.0, 0.0, 0, 0, 0.0, 8, 0, 254.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 4, 0.0, 0.0, 0.0, 6, 0.0, 0, 0, 0, 14, 242.0, 0.0, 0, 0, 18.0, 0, 0.0, 0.0, 8, 0.0, 0, 0.0, 0, 0, 0, 0, 0, 14, 116.0, 0.0, 0, 196.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 112.0, 0.0, 0.0, 0.0, 0.0, 0.0, 16, 0, 0, 0.0, 0.0, 0.0, 116.0, 0, 0, 0, 0.0, 0, 0.0, 0, 0, 0, 0, 254.0, 0, 0, 0, 254.0, 3, 0, 5, 0, 0, 250.0, 0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 14, 0, 0, 3, 0.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 254.0, 0.0, 0, 0.0, 4, 0.0, 0.0, 0.0, 0.0, 14, 0, 0, 0.0, 221.0, 0.0, 0.0, 0, 3.0, 2, 10, 0.0, 0, 0.0, 0, 0, 0.0, 7, 0, 16, 0.0, 10, 0.0, 0, 0, 77.0, 0, 0.0, 0, 116.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0, 0, 0, 254.0, 116.0, 0.0, 0.0, 0.0, 0.0, 9, 196.0, 0, 0.0, 101.0, 0, 0.0, 0, 2, 0.0, 0, 0, 0, 0.0, 0, 4, 0.0, 118.0, 0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 0.0, 0, 0.0, 0, 45.0, 121.0, 0, 15, 0, 0.0, 0.0, 0, 0.0, 0, 0, 212.0, 14, 0.0, 11, 0, 254.0, 3, 0.0, 0.0, 0.0, 0, 0, 228.0, 0, 0, 0, 0, 0.0, 3, 0.0, 0.0, 0, 0.0, 124.0, 0.0, 0.0, 0, 0.0, 204.0, 0.0, 0.0, 0.0, 0.0, 2, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 4, 0, 0, 0, 0, 12, 0.0, 0.0, 0], [0, 14, 0, 107.0, 0, 156.0, 0.0, 0, 92.0, 0.0, 0.0, 14, 0, 0.0, 252.0, 253.0, 0, 85.0, 14, 0, 0.0, 0, 0, 0, 0, 0.0, 14, 0, 0.0, 0.0, 0, 252.0, 253.0, 0, 0, 246.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 252.0, 252.0, 0, 252.0, 0, 252.0, 0, 0.0, 0, 0.0, 0.0, 252.0, 0.0, 0, 0, 71.0, 53.0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 14, 133.0, 0, 146.0, 2.0, 231.0, 0.0, 0.0, 0, 188.0, 249.0, 252.0, 0, 252.0, 0.0, 0, 0, 0, 252.0, 0.0, 252.0, 0.0, 0.0, 13, 0.0, 246.0, 192.0, 3, 0.0, 0.0, 0, 0, 0.0, 4, 0, 194.0, 0, 0, 0, 0, 0, 0.0, 252.0, 0, 0, 0, 12, 0.0, 0, 0.0, 0.0, 0.0, 249.0, 0.0, 0, 85.0, 0.0, 253.0, 0, 253.0, 0, 0, 0, 13, 253.0, 253.0, 0, 0, 85.0, 0, 253.0, 252.0, 15, 0.0, 0, 120.0, 0, 0, 0, 0, 0, 13, 232.0, 253.0, 0, 85.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 252.0, 0, 252.0, 0.0, 252.0, 0.0, 252.0, 252.0, 14, 0, 0, 215.0, 0.0, 0.0, 72.0, 0, 0, 0, 0.0, 0, 252.0, 0, 0, 0, 0, 253.0, 0, 0, 0, 252.0, 0, 0, 0, 0, 0, 57.0, 0, 252.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 232.0, 244.0, 12, 0, 0, 0, 0.0, 0.0, 0.0, 13, 0, 62.0, 0.0, 0, 71.0, 63.0, 0, 0, 0, 0, 0.0, 0, 0, 160.0, 0, 252.0, 252.0, 0, 0.0, 0, 253.0, 0.0, 0.0, 127.0, 11, 0, 0, 253.0, 253.0, 0.0, 0.0, 0, 57.0, 0, 12, 0.0, 0, 0.0, 0, 0, 252.0, 13, 0, 14, 252.0, 0, 0.0, 0, 0, 252.0, 0, 252.0, 4, 0.0, 0.0, 53.0, 253.0, 211.0, 0.0, 0, 15.0, 0.0, 0, 85.0, 0, 0, 0, 85.0, 51.0, 0.0, 0.0, 0.0, 0.0, 14, 249.0, 0, 252.0, 252.0, 0, 85.0, 0, 14, 0.0, 0, 0, 0, 0.0, 0, 0, 9.0, 252.0, 0, 0, 253.0, 0.0, 0.0, 0, 0, 0.0, 92.0, 0, 0, 211.0, 0, 0.0, 0, 252.0, 252.0, 0, 13, 0, 253.0, 231.0, 0, 0.0, 0, 0, 252.0, 12, 0.0, 0, 0, 129.0, 0, 0.0, 0.0, 252.0, 0, 0, 106.0, 0, 0, 0, 0, 232.0, 0, 252.0, 0.0, 0, 0.0, 253.0, 0.0, 0.0, 0, 0.0, 85.0, 0.0, 0.0, 0.0, 252.0, 0, 255.0, 0, 13, 253.0, 4, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 13, 203.0, 0.0, 0], [0, 0, 0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0, 24.0, 0, 0, 0.0, 5, 1, 0, 0, 0.0, 15, 0, 0.0, 0.0, 5, 0.0, 0.0, 0, 2, 0.0, 0, 0, 253.0, 0, 0, 0.0, 1, 0, 0.0, 0.0, 0.0, 0, 0.0, 0, 0.0, 4, 0.0, 0, 0.0, 0.0, 54.0, 0.0, 5, 0, 0.0, 112.0, 0, 0, 0.0, 0.0, 0, 5, 0, 0, 0.0, 0, 0, 0, 1, 0, 0, 167.0, 0, 0.0, 0.0, 253.0, 0.0, 0.0, 5, 106.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 245.0, 0.0, 4, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 2, 1, 0, 0.0, 0, 0.0, 0.0, 0.0, 253.0, 0.0, 6, 0.0, 0.0, 248.0, 5, 0.0, 0, 0, 0, 0, 0.0, 0.0, 1, 1, 0.0, 0, 32.0, 0.0, 0, 0.0, 1, 0.0, 0, 0, 6, 0, 0, 0, 0.0, 253.0, 0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 175.0, 0, 0, 0, 0.0, 2, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 0.0, 4, 0, 5, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 246.0, 0.0, 0, 0, 0, 8, 0.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0.0, 34.0, 0, 0, 0, 1, 0.0, 0, 0, 112.0, 0, 0.0, 0.0, 0, 0.0, 5, 253.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 117.0, 0, 0, 0.0, 1, 0.0, 0, 0, 0.0, 0, 0, 0, 0.0, 9, 0.0, 0, 0, 0.0, 0, 102.0, 0, 0.0, 0.0, 0.0, 0.0, 135.0, 0.0, 1, 0.0, 0.0, 0, 0.0, 0, 1, 0, 0.0, 253.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0, 235.0, 0.0, 0, 0.0, 0, 0, 0.0, 0, 3, 6, 0.0, 0, 5, 5.0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 3, 0.0, 0, 2.0, 0, 0.0, 0.0, 0, 0, 0, 0.0, 129.0, 0, 0.0, 0, 0, 0.0, 2, 0.0, 0, 0, 0.0, 4, 0.0, 0.0, 0.0, 0, 0, 0.0, 0, 2, 0, 0, 104.0, 9, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2, 196.0, 0, 0, 169.0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 1, 0, 0, 253.0, 0.0, 0], [0, 3, 0, 0.0, 0, 207.0, 0.0, 0, 0.0, 0.0, 0.0, 14, 0, 0.0, 0.0, 0.0, 0, 96.0, 13, 0, 0.0, 0, 0, 0, 0, 0.0, 16, 0, 0.0, 0.0, 0, 253.0, 0.0, 0, 0, 0.0, 0, 0, 128.0, 0, 0, 0.0, 0, 5, 0.0, 0.0, 252.0, 0, 0.0, 0, 0.0, 0, 0.0, 0, 0.0, 0.0, 252.0, 0.0, 6, 0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 11, 0, 0, 0.0, 0, 0, 0, 0, 0, 3, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 3, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 252.0, 252.0, 0.0, 5, 0.0, 70.0, 0.0, 2, 0.0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 11, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 64.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 116.0, 0, 0, 0, 12, 0.0, 0.0, 0, 6, 221.0, 0, 0.0, 0.0, 3, 0.0, 0, 0.0, 0, 0, 2, 0, 1, 13, 0.0, 0.0, 0, 23.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 138.0, 0.0, 207.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 248.0, 0, 0, 11, 0, 0.0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0, 223.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 253.0, 53.0, 8, 0, 0, 10, 0.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 0, 0.0, 6, 0.0, 0.0, 0.0, 0.0, 10, 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 221.0, 0, 8, 0.0, 0, 0.0, 0, 0, 0.0, 11, 0, 0, 253.0, 0, 0.0, 0, 0, 0.0, 0, 116.0, 0, 0.0, 0.0, 0.0, 252.0, 0.0, 0.0, 0, 26.0, 0.0, 0, 0.0, 6, 0, 0, 137.0, 0.0, 0.0, 0.0, 0.0, 0.0, 6, 0.0, 0, 116.0, 0.0, 0, 0.0, 0, 1, 0.0, 0, 0, 4, 0.0, 0, 9, 0.0, 0.0, 0, 0, 5.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 64.0, 0, 0.0, 0, 0.0, 0.0, 0, 13, 0, 0.0, 0.0, 0, 0.0, 2, 0, 0.0, 4, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 116.0, 0, 0, 0.0, 0, 0, 0, 0, 253.0, 11, 25.0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 210.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 1, 0.0, 0.0, 0], [0, 15, 0, 0.0, 0, 252.0, 0.0, 0, 0.0, 0.0, 0.0, 8, 0, 0.0, 0.0, 0.0, 0, 217.0, 13, 3, 0.0, 0, 0, 0, 7, 0.0, 17, 0, 0.0, 0.0, 0, 237.0, 0.0, 0, 0, 110.0, 0, 0, 252.0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 252.0, 0, 0.0, 0, 104.0, 0, 0.0, 0, 0.0, 0.0, 253.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 79.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 14, 0.0, 0, 63.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 191.0, 231.0, 0, 0.0, 0.0, 5, 0, 0, 0.0, 0.0, 252.0, 241.0, 0.0, 10, 0.0, 0.0, 144.0, 0, 0.0, 0.0, 3, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 0.0, 0, 4, 0, 10, 0.0, 0, 0.0, 0.0, 0.0, 144.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 144.0, 0, 0, 9, 9, 0.0, 0.0, 0, 0, 253.0, 0, 0.0, 0.0, 11, 0.0, 0, 176.0, 0, 0, 0, 0, 0, 11, 109.0, 0.0, 0, 252.0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 253.0, 0.0, 201.0, 0.0, 0.0, 0.0, 14, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, 0, 0, 0.0, 0, 252.0, 0, 2, 4, 0, 0.0, 0, 0, 0, 145.0, 0, 0, 0, 0, 0, 0.0, 6, 182.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 252.0, 0.0, 9, 0, 0, 0, 0.0, 0.0, 0.0, 13, 0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 252.0, 0.0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0, 7, 0.0, 0.0, 0.0, 0.0, 0, 215.0, 0, 0, 0.0, 0, 0.0, 0, 0, 21.0, 14, 0, 14, 62.0, 0, 0.0, 0, 0, 0.0, 0, 144.0, 10, 0.0, 0.0, 0.0, 252.0, 144.0, 0.0, 0, 105.0, 0.0, 0, 0.0, 0, 0, 0, 252.0, 0.0, 0.0, 0.0, 0.0, 0.0, 14, 109.0, 0, 145.0, 0.0, 0, 109.0, 0, 11, 0.0, 0, 0, 0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 255.0, 0.0, 0.0, 0, 0, 0.0, 0.0, 0, 0, 237.0, 0, 0.0, 0, 0.0, 108.0, 0, 5, 0, 0.0, 0.0, 0, 0.0, 5, 0, 253.0, 9, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 62.0, 0, 6, 0.0, 0, 0, 0, 0, 181.0, 2, 0.0, 0.0, 0, 0.0, 84.0, 0.0, 0.0, 0, 0.0, 252.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0, 10, 0.0, 12, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 13, 0.0, 0.0, 0], [0, 0, 0, 0.0, 0, 189.0, 254.0, 0, 254.0, 0.0, 0.0, 0, 0, 59.0, 252.0, 59.0, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0, 0.0, 18, 0, 0.0, 0.0, 0, 0.0, 99.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 0, 0, 0.0, 187.0, 254.0, 0, 251.0, 0, 0.0, 0, 0.0, 0, 0.0, 254.0, 207.0, 0.0, 0, 0, 151.0, 0.0, 0, 0, 0.0, 254.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 0, 0, 0, 254.0, 0, 144.0, 64.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0, 168.0, 0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0.0, 0, 0, 228.0, 0, 0, 0, 0, 0, 0.0, 253.0, 0, 0, 0, 0, 13.0, 0, 254.0, 0.0, 0.0, 40.0, 0.0, 0, 0.0, 0.0, 227.0, 0, 62.0, 0, 0, 0, 0, 254.0, 0.0, 0, 0, 151.0, 0, 0.0, 0.0, 0, 0.0, 0, 213.0, 0, 0, 0, 0, 0, 0, 0.0, 254.0, 0, 0.0, 0, 0, 111.0, 184.0, 0.0, 119.0, 245.0, 0, 0.0, 254.0, 254.0, 0.0, 76.0, 254.0, 0, 0, 0, 6.0, 0.0, 0.0, 0.0, 0, 0, 0, 0.0, 0, 0.0, 0, 0, 0, 0, 0.0, 0, 0, 0, 67.0, 0, 0, 0, 0, 0, 124.0, 0, 207.0, 0.0, 0.0, 0, 0.0, 0.0, 0, 216.0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0.0, 0.0, 0, 0, 254.0, 0.0, 0, 151.0, 72.0, 0, 0, 0, 0, 0.0, 0, 0, 0.0, 0, 0.0, 0.0, 0, 0.0, 0, 0.0, 0.0, 0.0, 249.0, 0, 0, 0, 0.0, 129.0, 0.0, 0.0, 0, 0.0, 0, 0, 8.0, 0, 0.0, 0, 0, 254.0, 0, 0, 0, 0.0, 0, 22.0, 0, 0, 254.0, 0, 248.0, 0, 0.0, 0.0, 254.0, 88.0, 0.0, 0.0, 0, 233.0, 0.0, 0, 0.0, 0, 0, 0, 0.0, 0.0, 0.0, 0.0, 227.0, 4.0, 0, 0.0, 0, 238.0, 0.0, 0, 0.0, 0, 0, 0.0, 0, 0, 0, 0.0, 0, 0, 153.0, 245.0, 0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 147.0, 0, 0, 16.0, 0, 254.0, 0, 0.0, 0.0, 0, 0, 0, 254.0, 0.0, 0, 0.0, 0, 0, 0.0, 0, 168.0, 0, 0, 26.0, 0, 13.0, 0.0, 0.0, 0, 0, 254.0, 0, 0, 0, 0, 0.0, 0, 167.0, 0.0, 0, 0.0, 141.0, 0.0, 0.0, 0, 151.0, 26.0, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0, 0, 60.0, 0, 0, 254.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 227.0, 218.0, 0], [0, 0, 0, 0.0, 0, 11.0, 253.0, 0, 253.0, 0.0, 0.0, 12, 0, 0.0, 0.0, 0.0, 0, 253.0, 10, 4, 0.0, 4, 0, 1, 8, 0.0, 19, 0, 0.0, 0.0, 7, 68.0, 245.0, 1, 0, 0.0, 0, 0, 253.0, 0, 0, 0.0, 0, 6, 0.0, 0.0, 253.0, 0, 0.0, 0, 81.0, 0, 0.0, 0, 0.0, 0.0, 253.0, 0.0, 5, 4, 0.0, 253.0, 0, 0, 42.0, 0.0, 0, 11, 0, 0, 0.0, 0, 0, 0, 0, 0, 11, 0.0, 0, 0.0, 124.0, 15.0, 0.0, 0.0, 8, 0.0, 0.0, 253.0, 0, 0.0, 0.0, 10, 0, 0, 0.0, 0.0, 186.0, 253.0, 0.0, 4, 0.0, 253.0, 253.0, 12, 0.0, 0.0, 4, 2, 0.0, 12, 0, 0.0, 0, 0, 0, 0, 0, 0.0, 171.0, 0, 12, 0, 6, 0.0, 0, 0.0, 0.0, 0.0, 36.0, 0.0, 0, 0.0, 0.0, 42.0, 0, 253.0, 1, 0, 10, 11, 0.0, 0.0, 0, 7, 253.0, 0, 41.0, 0.0, 0, 0.0, 0, 0.0, 0, 0, 4, 0, 5, 6, 0.0, 0.0, 0, 253.0, 0, 2, 0.0, 238.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0, 42.0, 0.0, 245.0, 81.0, 0, 1, 0, 0.0, 0.0, 0.0, 0.0, 6, 0, 2, 0.0, 0, 19.0, 0, 2, 12, 0, 0.0, 0, 0, 0, 143.0, 1, 3, 1, 0, 0, 0.0, 9, 246.0, 42.0, 0.0, 0, 0.0, 0.0, 0, 0.0, 253.0, 253.0, 10, 0, 0, 11, 0.0, 0.0, 0.0, 11, 0, 0.0, 0.0, 0, 0.0, 0.0, 0, 0, 0, 0, 0.0, 0, 1, 253.0, 0, 253.0, 0.0, 0, 0.0, 10, 12.0, 0.0, 0.0, 253.0, 13, 0, 7, 253.0, 0.0, 0.0, 0.0, 0, 253.0, 0, 14, 0.0, 0, 0.0, 0, 0, 0.0, 10, 0, 0, 253.0, 2, 0.0, 0, 0, 0.0, 2, 218.0, 9, 0.0, 0.0, 0.0, 162.0, 217.0, 0.0, 0, 253.0, 0.0, 0, 0.0, 7, 0, 1, 253.0, 15.0, 0.0, 0.0, 0.0, 77.0, 5, 0.0, 0, 143.0, 86.0, 5, 36.0, 0, 0, 0.0, 0, 0, 5, 0.0, 0, 11, 0.0, 0.0, 0, 0, 0.0, 0.0, 0.0, 0, 0, 0.0, 40.0, 0, 1, 0.0, 1, 0.0, 0, 0.0, 253.0, 0, 14, 0, 0.0, 0.0, 0, 0.0, 12, 0, 253.0, 4, 0.0, 6, 0, 0.0, 4, 0.0, 0.0, 253.0, 0, 6, 0.0, 0, 2, 0, 0, 253.0, 12, 245.0, 15.0, 0, 0.0, 245.0, 0.0, 0.0, 0, 0.0, 253.0, 0.0, 0.0, 0.0, 0.0, 0, 215.0, 0, 2, 0.0, 13, 0, 0.0, 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0.0, 1]]} \ No newline at end of file diff --git a/web_console_v2/api/test/fedlearner_webconsole/test_data/sparkapp.tar b/web_console_v2/api/test/fedlearner_webconsole/test_data/sparkapp.tar index 80f2b1e06..c7d93f210 100644 Binary files a/web_console_v2/api/test/fedlearner_webconsole/test_data/sparkapp.tar and b/web_console_v2/api/test/fedlearner_webconsole/test_data/sparkapp.tar differ diff --git a/web_console_v2/api/test/fedlearner_webconsole/utils/base64_test.py b/web_console_v2/api/test/fedlearner_webconsole/utils/base64_test.py new file mode 100644 index 000000000..2667e1025 --- /dev/null +++ b/web_console_v2/api/test/fedlearner_webconsole/utils/base64_test.py @@ -0,0 +1,37 @@ +# Copyright 2021 The FedLearner Authors. All Rights Reserved. +# +# 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. + +# coding: utf-8 +import unittest + +from fedlearner_webconsole.utils.base64 import base64encode, base64decode + + +class Base64Test(unittest.TestCase): + def test_base64encode(self): + self.assertEqual(base64encode('hello 1@2'), 'aGVsbG8gMUAy') + self.assertEqual(base64encode('😈'), '8J+YiA==') + + def test_base64decode(self): + self.assertEqual(base64decode('aGVsbG8gMUAy'), 'hello 1@2') + self.assertEqual(base64decode('JjEzOVlUKiYm'), '&139YT*&&') + + def test_base64_encode_and_decode(self): + self.assertEqual(base64decode(base64encode('test')), 'test') + self.assertEqual(base64encode(base64decode('aGVsbG8gMUAy')), + 'aGVsbG8gMUAy') + + +if __name__ == '__main__': + unittest.main() diff --git a/web_console_v2/api/test/fedlearner_webconsole/utils/file_manager_test.py b/web_console_v2/api/test/fedlearner_webconsole/utils/file_manager_test.py index 34ab41bc0..f32bf303e 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/utils/file_manager_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/utils/file_manager_test.py @@ -15,20 +15,20 @@ # coding: utf-8 import os import shutil -import stat import tempfile import unittest +from collections import namedtuple from pathlib import Path -from unittest.mock import patch, MagicMock -from pyarrow import fs +from tensorflow.io import gfile -from fedlearner_webconsole.utils.file_manager import (DefaultFileManager, - HdfsFileManager, - FileManager, File) +from fedlearner_webconsole.utils.file_manager import GFileFileManager, FileManager, File +FakeFileStatistics = namedtuple('FakeFileStatistics', ['length', 'mtime_nsec']) + + +class GFileFileManagerTest(unittest.TestCase): -class DefaultFileManagerTest(unittest.TestCase): _F1_SIZE = 3 _F2_SIZE = 4 _S1_SIZE = 55 @@ -37,21 +37,21 @@ class DefaultFileManagerTest(unittest.TestCase): _S1_MTIME = 1613982392 def _get_file_stat(self, orig_os_stat, path): - faked = list(orig_os_stat(path)) + gfile_stat = FakeFileStatistics(2, 1613982390 * 1e9) if path == self._get_temp_path('f1.txt') or \ path == self._get_temp_path('subdir/f1.txt'): - faked[stat.ST_SIZE] = self._F1_SIZE - faked[stat.ST_MTIME] = self._F1_MTIME - return os.stat_result(faked) + gfile_stat = FakeFileStatistics(self._F1_SIZE, + self._F1_MTIME * 1e9) + return gfile_stat elif path == self._get_temp_path('f2.txt') or \ path == self._get_temp_path('f3.txt'): - faked[stat.ST_SIZE] = self._F2_SIZE - faked[stat.ST_MTIME] = self._F2_MTIME - return os.stat_result(faked) + gfile_stat = FakeFileStatistics(self._F2_SIZE, + self._F2_MTIME * 1e9) + return gfile_stat elif path == self._get_temp_path('subdir/s1.txt'): - faked[stat.ST_SIZE] = self._S1_SIZE - faked[stat.ST_MTIME] = self._S1_MTIME - return os.stat_result(faked) + gfile_stat = FakeFileStatistics(self._S1_SIZE, + self._S1_MTIME * 1e9) + return gfile_stat else: return orig_os_stat(path) @@ -70,9 +70,9 @@ def setUp(self): def fake_stat(path, *arg, **kwargs): return self._get_file_stat(self._orig_os_stat, path) - os.stat = fake_stat + gfile.stat = fake_stat - self._fm = DefaultFileManager() + self._fm = GFileFileManager() def tearDown(self): os.stat = self._orig_os_stat @@ -177,119 +177,16 @@ def test_mkdir(self): self._fm.mkdir(os.path.join(self._get_temp_path(), 'subdir2')) self.assertTrue(os.path.isdir(self._get_temp_path('subdir2'))) - -class HdfsFileManagerTest(unittest.TestCase): - def setUp(self): - self._envs_patcher = patch('envs.Envs.HDFS_SERVER', 'hdfs://haruna/') - self._envs_patcher.start() - - self._mock_client = MagicMock() - self._mock_client_generator = MagicMock() - self._mock_client_generator.from_uri.return_value = (self._mock_client, - '/') - self._client_patcher = patch( - 'fedlearner_webconsole.utils.file_manager.FileSystem', - self._mock_client_generator) - self._client_patcher.start() - - self._fm = HdfsFileManager() - - def tearDown(self): - self._envs_patcher.stop() - self._client_patcher.stop() - - def test_can_handle(self): - self.assertFalse(self._fm.can_handle('/data/abc')) - self.assertTrue(self._fm.can_handle('hdfs://abc')) - - def test_ls(self): - mock_ls = MagicMock() - self._mock_client.get_file_info = mock_ls - mock_ls.side_effect = [ - fs.FileInfo(type=fs.FileType.Directory, - path='/data', - size=1024, - mtime_ns=1367317325346000000), - [ - fs.FileInfo(type=fs.FileType.File, - path='/data/abc', - size=1024, - mtime_ns=1367317325346000000), - fs.FileInfo(type=fs.FileType.Directory, - path='/data', - size=1024, - mtime_ns=1367317325346000000), - ] - ] - self.assertEqual( - self._fm.ls('hdfs:///data', recursive=True), - [File(path='hdfs:///data/abc', size=1024, mtime=1367317325)]) - mock_ls.assert_called() - - mock_ls = MagicMock() - self._mock_client.get_file_info = mock_ls - mock_ls.return_value = fs.FileInfo(type=fs.FileType.File, - path='/data/abc', - size=1024, - mtime_ns=1367317325346000000) - self.assertEqual( - self._fm.ls('hdfs:///data/abc', recursive=True), - [File(path='hdfs:///data/abc', size=1024, mtime=1367317325)]) - mock_ls.assert_called_once() - - @staticmethod - def _yield_files(files): - for file in files: - yield file - - def test_move(self): - mock_rename = MagicMock() - self._mock_client.move = mock_rename - mock_rename.return_value = self._yield_files(['/data/123']) - self.assertTrue(self._fm.move('hdfs:///data/abc', 'hdfs:///data/123')) - mock_rename.assert_called_once_with('/data/abc', '/data/123') - - mock_rename.return_value = self._yield_files([]) - self.assertFalse(self._fm.move('hdfs:///data/abc', 'hdfs:///data/123')) - - def test_remove_dir(self): - mock_get_file_info = MagicMock() - self._mock_client.get_file_info = mock_get_file_info - mock_get_file_info.return_value = fs.FileInfo(type=fs.FileType.File, - path='/data/123', - size=1024) - - self.assertTrue(self._fm.remove('hdfs:///data/123')) - self._mock_client.delete_file.assert_called_once_with('/data/123') - self._mock_client.delete_dir.assert_not_called() - - def test_remove_file(self): - mock_get_file_info = MagicMock() - self._mock_client.get_file_info = mock_get_file_info - mock_get_file_info.return_value = fs.FileInfo( - type=fs.FileType.Directory, path='/data/123', size=1024) - - self.assertTrue(self._fm.remove('hdfs:///data/123')) - self._mock_client.delete_file.assert_not_called() - self._mock_client.delete_dir.assert_called_once_with('/data/123') - - @patch('tensorflow.io.gfile.copy') - def test_copy(self, mock_copy): - self.assertTrue(self._fm.copy('hdfs:///source', 'hdfs:///dest')) - mock_copy.assert_called_once_with('hdfs:///source', 'hdfs:///dest') - - def test_mkdir(self): - mock_mkdir = MagicMock() - self._mock_client.create_dir = mock_mkdir - self.assertTrue(self._fm.mkdir('hdfs:///data')) - mock_mkdir.assert_called_once_with('/data') + def test_read(self): + content = self._fm.read(self._get_temp_path('f1.txt')) + self.assertEqual('xxx', content) class FileManagerTest(unittest.TestCase): @classmethod def setUpClass(cls): - os.environ[ - 'CUSTOMIZED_FILE_MANAGER'] = 'testing.fake_file_manager:FakeFileManager' + fake_fm = 'testing.fake_file_manager:FakeFileManager' + os.environ['CUSTOMIZED_FILE_MANAGER'] = fake_fm @classmethod def tearDownClass(cls): @@ -302,7 +199,7 @@ def test_can_handle(self): self.assertTrue(self._fm.can_handle('fake://123')) # Falls back to default manager self.assertTrue(self._fm.can_handle('/data/123')) - self.assertFalse(self._fm.can_handle('hdfs:///123')) + self.assertFalse(self._fm.can_handle('unsupported:///123')) def test_ls(self): self.assertEqual(self._fm.ls('fake://data'), [{ @@ -322,7 +219,8 @@ def test_remove(self): self.assertTrue(self._fm.remove('fake://remove/123')) self.assertFalse(self._fm.remove('fake://do_not_remove/123')) # No file manager can handle this - self.assertRaises(RuntimeError, lambda: self._fm.remove('hdfs://123')) + self.assertRaises(RuntimeError, + lambda: self._fm.remove('unsupported://123')) def test_copy(self): self.assertTrue(self._fm.copy('fake://copy/123', 'fake://copy/234')) @@ -336,7 +234,8 @@ def test_mkdir(self): self.assertTrue(self._fm.mkdir('fake://mkdir/123')) self.assertFalse(self._fm.mkdir('fake://do_not_mkdir/123')) # No file manager can handle this - self.assertRaises(RuntimeError, lambda: self._fm.mkdir('hdfs:///123')) + self.assertRaises(RuntimeError, + lambda: self._fm.mkdir('unsupported:///123')) if __name__ == '__main__': diff --git a/web_console_v2/api/test/fedlearner_webconsole/workflow/apis_test.py b/web_console_v2/api/test/fedlearner_webconsole/workflow/apis_test.py index a911e30ec..2c6382658 100644 --- a/web_console_v2/api/test/fedlearner_webconsole/workflow/apis_test.py +++ b/web_console_v2/api/test/fedlearner_webconsole/workflow/apis_test.py @@ -14,6 +14,8 @@ # coding: utf-8 import logging +import random +import string import time import json import unittest @@ -36,7 +38,7 @@ from fedlearner_webconsole.proto.common_pb2 import CreateJobFlag from fedlearner_webconsole.workflow.apis import is_peer_job_inheritance_matched from testing.common import BaseTestCase - +from fedlearner_webconsole.db import db_handler class WorkflowsApiTest(BaseTestCase): class Config(BaseTestCase.Config): @@ -47,15 +49,9 @@ def setUp(self): self.maxDiff = None super().setUp() # Inserts data - workflow1 = Workflow(name='workflow_key_get1', - project_id=1 - ) - workflow2 = Workflow(name='workflow_kay_get2', - project_id=2 - ) - workflow3 = Workflow(name='workflow_key_get3', - project_id=2 - ) + workflow1 = Workflow(name='workflow_key_get1', project_id=1) + workflow2 = Workflow(name='workflow_kay_get2', project_id=2) + workflow3 = Workflow(name='workflow_key_get3', project_id=2) db.session.add(workflow1) db.session.add(workflow2) db.session.add(workflow3) @@ -77,11 +73,10 @@ def test_get_with_keyword(self): def test_get_workflows(self): time.sleep(1) - workflow = Workflow(name='last', - project_id=1 - ) + workflow = Workflow(name='last', project_id=1) db.session.add(workflow) db.session.flush() + db.session.commit() response = self.get_helper('/api/v2/workflows') data = self.get_response_data(response) self.assertEqual(data[0]['name'], 'last') @@ -91,18 +86,22 @@ def test_get_workflows(self): def test_create_new_workflow(self, mock_uuid, mock_wakeup): mock_uuid.return_value = UUID('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') with open( - Path(__file__, '../../test_data/workflow_config.json').resolve() - ) as workflow_config: + Path(__file__, '../../test_data/workflow_config.json').resolve( + )) as workflow_config: config = json.load(workflow_config) + extra = ''.join( + random.choice(string.ascii_lowercase) for _ in range(10)) + # extra should be a valid json string so we mock one + extra = f'{{"parent_job_name":"{extra}"}}' workflow = { 'name': 'test-workflow', 'project_id': 1234567, 'forkable': True, 'comment': 'test-comment', - 'config': config + 'config': config, + 'extra': extra } - response = self.post_helper('/api/v2/workflows', - data=workflow) + response = self.post_helper('/api/v2/workflows', data=workflow) self.assertEqual(response.status_code, HTTPStatus.CREATED) created_workflow = json.loads(response.data).get('data') # Check scheduler @@ -115,35 +114,36 @@ def test_create_new_workflow(self, mock_uuid, mock_wakeup): del created_workflow['updated_at'] del created_workflow['start_at'] del created_workflow['stop_at'] - self.assertEqual(created_workflow, { - 'batch_update_interval': -1, - 'name': 'test-workflow', - 'project_id': 1234567, - 'forkable': True, - 'forked_from': None, - 'metric_is_public': False, - 'comment': 'test-comment', - 'state': 'NEW', - 'target_state': 'READY', - 'transaction_state': 'READY', - 'transaction_err': None, - 'create_job_flags': [1, 1, 1], - 'peer_create_job_flags': None, - 'job_ids': [], - 'transaction_state': 'READY', - 'last_triggered_batch': None, - 'recur_at': None, - 'recur_type': 'NONE', - 'trigger_dataset': None, - 'uuid': f'u{mock_uuid().hex[:19]}' - }) + self.assertEqual( + created_workflow, { + 'batch_update_interval': -1, + 'name': 'test-workflow', + 'project_id': 1234567, + 'extra': extra, + 'forkable': True, + 'forked_from': None, + 'metric_is_public': False, + 'comment': 'test-comment', + 'state': 'NEW', + 'target_state': 'READY', + 'transaction_state': 'READY', + 'transaction_err': None, + 'create_job_flags': [1, 1, 1], + 'peer_create_job_flags': None, + 'job_ids': [], + 'transaction_state': 'READY', + 'last_triggered_batch': None, + 'recur_at': None, + 'recur_type': 'NONE', + 'trigger_dataset': None, + 'uuid': f'u{mock_uuid().hex[:19]}' + }) # Check DB self.assertEqual(len(Workflow.query.all()), 4) # Post again mock_wakeup.reset_mock() - response = self.post_helper('/api/v2/workflows', - data=workflow) + response = self.post_helper('/api/v2/workflows', data=workflow) self.assertEqual(response.status_code, HTTPStatus.CONFLICT) # Check mock mock_wakeup.assert_not_called() @@ -153,7 +153,8 @@ def test_create_new_workflow(self, mock_uuid, mock_wakeup): @patch('fedlearner_webconsole.workflow.apis.composer.get_item_status') @patch('fedlearner_webconsole.workflow.apis.composer.collect') @patch('fedlearner_webconsole.workflow.apis.scheduler.wakeup') - def test_post_batch_update_interval_job(self, mock_wakeup, mock_collect, mock_get_item_status): + def test_post_batch_update_interval_job(self, mock_wakeup, mock_collect, + mock_get_item_status): mock_get_item_status.return_value = None with open( Path(__file__, '../../test_data/workflow_config.json').resolve( @@ -194,54 +195,48 @@ def test_fork_workflow(self): class WorkflowApiTest(BaseTestCase): def test_put_successfully(self): config = { - 'participants': [ - { - 'name': 'party_leader', - 'url': '127.0.0.1:5000', - 'domain_name': 'fl-leader.com' - } - ], - 'variables': [ - { - 'name': 'namespace', - 'value': 'leader' - }, - { - 'name': 'basic_envs', - 'value': '{}' - }, - { - 'name': 'storage_root_dir', - 'value': '/' - }, - { - 'name': 'EGRESS_URL', - 'value': '127.0.0.1:1991' - } - ] + 'participants': [{ + 'name': 'party_leader', + 'url': '127.0.0.1:5000', + 'domain_name': 'fl-leader.com' + }], + 'variables': [{ + 'name': 'namespace', + 'value': 'leader' + }, { + 'name': 'basic_envs', + 'value': '{}' + }, { + 'name': 'storage_root_dir', + 'value': '/' + }, { + 'name': 'EGRESS_URL', + 'value': '127.0.0.1:1991' + }] } - project = Project(name='test', - config=ParseDict(config, - project_pb2.Project()).SerializeToString()) + project = Project( + name='test', + config=ParseDict(config, + project_pb2.Project()).SerializeToString()) db.session.add(project) workflow = Workflow( name='test-workflow', project_id=1, state=WorkflowState.NEW, transaction_state=TransactionState.PARTICIPANT_PREPARE, - target_state=WorkflowState.READY - ) + target_state=WorkflowState.READY) db.session.add(workflow) db.session.commit() db.session.refresh(workflow) - response = self.put_helper( - f'/api/v2/workflows/{workflow.id}', - data={ - 'forkable': True, - 'config': {'group_alias': 'test-template'}, - 'comment': 'test comment' - }) + response = self.put_helper(f'/api/v2/workflows/{workflow.id}', + data={ + 'forkable': True, + 'config': { + 'group_alias': 'test-template' + }, + 'comment': 'test comment' + }) self.assertEqual(response.status_code, HTTPStatus.OK) updated_workflow = Workflow.query.get(workflow.id) @@ -262,12 +257,13 @@ def test_put_resetting(self): db.session.commit() db.session.refresh(workflow) - response = self.put_helper( - f'/api/v2/workflows/{workflow.id}', - data={ - 'forkable': True, - 'config': {'group_alias': 'test-template'}, - }) + response = self.put_helper(f'/api/v2/workflows/{workflow.id}', + data={ + 'forkable': True, + 'config': { + 'group_alias': 'test-template' + }, + }) self.assertEqual(response.status_code, HTTPStatus.CONFLICT) @patch('fedlearner_webconsole.workflow.apis.scheduler.wakeup') @@ -283,11 +279,8 @@ def test_patch_successfully(self, mock_wakeup): db.session.commit() db.session.refresh(workflow) - response = self.patch_helper( - f'/api/v2/workflows/{workflow.id}', - data={ - 'target_state': 'RUNNING' - }) + response = self.patch_helper(f'/api/v2/workflows/{workflow.id}', + data={'target_state': 'RUNNING'}) self.assertEqual(response.status_code, HTTPStatus.OK) patched_data = json.loads(response.data).get('data') self.assertEqual(patched_data['id'], workflow.id) @@ -301,26 +294,22 @@ def test_patch_successfully(self, mock_wakeup): @patch('fedlearner_webconsole.workflow.apis.scheduler.wakeup') def test_patch_invalid_target_state(self, mock_wakeup): - workflow = Workflow( - name='test-workflow', - project_id=123, - config=WorkflowDefinition().SerializeToString(), - forkable=False, - state=WorkflowState.READY, - target_state=WorkflowState.RUNNING - ) + workflow = Workflow(name='test-workflow', + project_id=123, + config=WorkflowDefinition().SerializeToString(), + forkable=False, + state=WorkflowState.READY, + target_state=WorkflowState.RUNNING) db.session.add(workflow) db.session.commit() db.session.refresh(workflow) - response = self.patch_helper( - f'/api/v2/workflows/{workflow.id}', - data={ - 'target_state': 'READY' - }) + response = self.patch_helper(f'/api/v2/workflows/{workflow.id}', + data={'target_state': 'READY'}) self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST) - self.assertEqual(json.loads(response.data).get('details'), - 'Another transaction is in progress [1]') + self.assertEqual( + json.loads(response.data).get('details'), + 'Another transaction is in progress [1]') # Checks DB patched_workflow = Workflow.query.get(workflow.id) self.assertEqual(patched_workflow.state, WorkflowState.READY) @@ -332,7 +321,9 @@ def test_patch_invalid_target_state(self, mock_wakeup): @patch('fedlearner_webconsole.workflow.apis.composer.patch_item_attr') @patch('fedlearner_webconsole.workflow.apis.composer.finish') @patch('fedlearner_webconsole.workflow.apis.composer.collect') - def test_patch_batch_update_interval(self, mock_collect, mock_finish, mock_patch_item, mock_get_item_status): + def test_patch_batch_update_interval(self, mock_collect, mock_finish, + mock_patch_item, + mock_get_item_status): mock_get_item_status.side_effect = [None, ItemStatus.ON] workflow = Workflow( name='test-workflow-left', @@ -347,8 +338,9 @@ def test_patch_batch_update_interval(self, mock_collect, mock_finish, mock_patch db.session.refresh(workflow) # test create cronjob - response = self.patch_helper(f'/api/v2/workflows/{workflow.id}', - data={'batch_update_interval': batch_update_interval}) + response = self.patch_helper( + f'/api/v2/workflows/{workflow.id}', + data={'batch_update_interval': batch_update_interval}) self.assertEqual(response.status_code, HTTPStatus.OK) mock_collect.assert_called_with( @@ -359,11 +351,14 @@ def test_patch_batch_update_interval(self, mock_collect, mock_finish, mock_patch # patch new interval time for cronjob batch_update_interval = 2 - response = self.patch_helper(f'/api/v2/workflows/{workflow.id}', - data={'batch_update_interval': batch_update_interval}) + response = self.patch_helper( + f'/api/v2/workflows/{workflow.id}', + data={'batch_update_interval': batch_update_interval}) self.assertEqual(response.status_code, HTTPStatus.OK) - mock_patch_item.assert_called_with(name=f'workflow_cron_job_{workflow.id}', key='interval_time', value=batch_update_interval * 60) - + mock_patch_item.assert_called_with( + name=f'workflow_cron_job_{workflow.id}', + key='interval_time', + value=batch_update_interval * 60) # test stop cronjob response = self.patch_helper(f'/api/v2/workflows/{workflow.id}', @@ -386,56 +381,24 @@ def test_patch_batch_update_interval(self, mock_collect, mock_finish, mock_patch data={'batch_update_interval': 1}) self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST) - - def test_patch_not_found(self): - response = self.patch_helper( - '/api/v2/workflows/1', - data={ - 'target_state': 'RUNNING' - }) + response = self.patch_helper('/api/v2/workflows/1', + data={'target_state': 'RUNNING'}) self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) def test_patch_create_job_flags(self): - wd = WorkflowDefinition() - jd = wd.job_definitions.add() - workflow = Workflow( - name='test-workflow', - project_id=123, - config=wd.SerializeToString(), - forkable=False, - state=WorkflowState.READY, - ) - db.session.add(workflow) - db.session.flush() - job = Job( - name='test_job', - job_type=JobType(1), - config=jd.SerializeToString(), - workflow_id=workflow.id, - project_id=123, - state=JobState.STOPPED, - is_disabled=False) - db.session.add(job) - db.session.flush() - workflow.job_ids = str(job.id) - db.session.commit() - response = self.patch_helper( - f'/api/v2/workflows/{workflow.id}', - data={ - 'create_job_flags': [3] - }) - self.assertEqual(response.status_code, HTTPStatus.OK) - patched_job = Job.query.get(job.id) - self.assertEqual(patched_job.is_disabled, True) - response = self.patch_helper( - f'/api/v2/workflows/{workflow.id}', - data={ - 'create_job_flags': [1] - }) - self.assertEqual(response.status_code, HTTPStatus.OK) - patched_job = Job.query.get(job.id) - self.assertEqual(patched_job.is_disabled, False) + with db_handler.session_scope() as session: + workflow, job = add_fake_workflow(session) + response = self.patch_helper(f'/api/v2/workflows/{workflow.id}', + data={'create_job_flags': [3]}) + self.assertEqual(response.status_code, HTTPStatus.OK) + patched_job = Job.query.get(job.id) + self.assertEqual(patched_job.is_disabled, True) + response = self.patch_helper(f'/api/v2/workflows/{workflow.id}', + data={'create_job_flags': [1]}) + self.assertEqual(response.status_code, HTTPStatus.OK) + patched_job = Job.query.get(job.id) + self.assertEqual(patched_job.is_disabled, False) # TODO: Move it to service_test @patch('fedlearner_webconsole.rpc.client.RpcClient.get_workflow') @@ -461,14 +424,51 @@ def test_is_peer_job_inheritance_matched(self, mock_get_workflow): workflow1 = Workflow(project=project, forked_from=workflow0.id) workflow1.set_config(config) workflow1.set_create_job_flags([CreateJobFlag.REUSE]) - workflow1.set_peer_create_job_flags([CreateJobFlag.NEW, CreateJobFlag.REUSE]) - + workflow1.set_peer_create_job_flags( + [CreateJobFlag.NEW, CreateJobFlag.REUSE]) self.assertTrue(is_peer_job_inheritance_matched(workflow1)) workflow1.set_create_job_flags([CreateJobFlag.NEW]) self.assertFalse(is_peer_job_inheritance_matched(workflow1)) + def test_is_local(self): + with db_handler.session_scope() as session: + workflow, job = add_fake_workflow(session) + self.assertTrue(workflow.is_local()) + config = workflow.get_config() + config.job_definitions[ + 0].is_federated = True + workflow.set_config(config) + self.assertFalse(False, workflow.is_local()) + + +def add_fake_workflow(session): + wd = WorkflowDefinition() + jd = wd.job_definitions.add() + workflow = Workflow( + name='test-workflow', + project_id=123, + config=wd.SerializeToString(), + forkable=False, + state=WorkflowState.READY, + ) + session.add(workflow) + session.flush() + job = Job( + name='test_job', + job_type=JobType(1), + config=jd.SerializeToString(), + workflow_id=workflow.id, + project_id=123, + state=JobState.STOPPED, + is_disabled=False) + session.add(job) + session.flush() + workflow.job_ids = str(job.id) + session.commit() + return workflow, job + if __name__ == '__main__': unittest.main() diff --git a/web_console_v2/api/testing/common.py b/web_console_v2/api/testing/common.py index 6ebb41930..fff83b5a0 100644 --- a/web_console_v2/api/testing/common.py +++ b/web_console_v2/api/testing/common.py @@ -15,7 +15,6 @@ # coding: utf-8 import contextlib import json -import os import logging import unittest import secrets @@ -25,20 +24,29 @@ from flask import Flask from flask_testing import TestCase from fedlearner_webconsole.composer.composer import Composer, ComposerConfig -from fedlearner_webconsole.db import db +from fedlearner_webconsole.db import db_handler as db, get_database_uri from fedlearner_webconsole.app import create_app from fedlearner_webconsole.initial_db import initial_db +from fedlearner_webconsole.scheduler.scheduler import scheduler # NOTE: the following models imported is intended to be analyzed by SQLAlchemy from fedlearner_webconsole.auth.models import Role, User, State from fedlearner_webconsole.composer.models import SchedulerItem, SchedulerRunner, OptimisticLock +from fedlearner_webconsole.utils.base64 import base64encode -test_db_path = '/tmp/fedlearner_test.db' + +def create_all_tables(database_uri: str = None): + if database_uri: + db.rebind(database_uri) + + # If there's a db file due to some reason, remove it first. + if db.metadata.tables.values(): + db.drop_all() + db.create_all() class BaseTestCase(TestCase): class Config(object): - SQLALCHEMY_DATABASE_URI = \ - f'sqlite:///{test_db_path}?check_same_thread=False' + SQLALCHEMY_DATABASE_URI = get_database_uri() SQLALCHEMY_TRACK_MODIFICATIONS = False JWT_SECRET_KEY = secrets.token_urlsafe(64) PROPAGATE_EXCEPTIONS = True @@ -49,26 +57,20 @@ class Config(object): START_COMPOSER = False def create_app(self): + create_all_tables(self.__class__.Config.SQLALCHEMY_DATABASE_URI) + initial_db() app = create_app(self.__class__.Config) - app.app_context().push() return app def setUp(self): - try: - # keep clean database before each test - os.remove(test_db_path) - except OSError: - pass - - db.create_all() - initial_db() + super().setUp() self.signin_helper() def tearDown(self): self.signout_helper() - - db.session.remove() + scheduler.stop() db.drop_all() + super().tearDown() def get_response_data(self, response): return json.loads(response.data).get('data') @@ -81,7 +83,7 @@ def signin_helper(self, username='ada', password='fl@123.'): resp = self.client.post('/api/v2/auth/signin', data=json.dumps({ 'username': username, - 'password': password + 'password': base64encode(password) }), content_type='application/json') resp_data = self.get_response_data(resp) @@ -232,7 +234,8 @@ def new_tear_down(*args, **kwargs): ) assert result.wasSuccessful() self._result_queue.put(True) - except Exception: + except Exception as err: + logging.error('expected happened %s', err) self._result_queue.put(False) raise @@ -264,13 +267,14 @@ def multi_process_test(test_list): raise Exception(f'Subprocess failed: number {i}') -def create_test_db(): - """Creates test db for testing non flask-must units.""" - app = Flask('fedlearner_webconsole_test') - app.config['TESTING'] = True - app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' - app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False - db.init_app(app) - # this does the binding - app.app_context().push() - return db +class NoWebServerTestCase(unittest.TestCase): + class Config(object): + SQLALCHEMY_DATABASE_URI = get_database_uri() + + def setUp(self) -> None: + super().setUp() + create_all_tables(self.__class__.Config.SQLALCHEMY_DATABASE_URI) + + def tearDown(self) -> None: + db.drop_all() + return super().tearDown() \ No newline at end of file diff --git a/web_console_v2/api/tools/local_runner/app_a.py b/web_console_v2/api/tools/local_runner/app_a.py index efa15188f..a9f9cb314 100644 --- a/web_console_v2/api/tools/local_runner/app_a.py +++ b/web_console_v2/api/tools/local_runner/app_a.py @@ -15,12 +15,14 @@ # coding: utf-8 import os import logging + +from envs import Envs from fedlearner_webconsole.app import create_app from tools.local_runner.initial_db import init_db -BASE_DIR = os.path.abspath(os.path.dirname(__file__)) BASE_DIR = os.path.abspath(os.path.dirname(__file__)) + class Config(object): SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'app_a.db') MYSQL_CHARSET = 'utf8mb4' @@ -31,10 +33,13 @@ class Config(object): LOGGING_LEVEL = logging.INFO GRPC_LISTEN_PORT = 1993 JWT_ACCESS_TOKEN_EXPIRES = 86400 + STORAGE_ROOT = Envs.STORAGE_ROOT START_GRPC_SERVER = True START_SCHEDULER = True - START_COMPOSER = False + START_COMPOSER = True + + app = create_app(Config) diff --git a/web_console_v2/api/tools/local_runner/app_b.py b/web_console_v2/api/tools/local_runner/app_b.py index 8c894270b..e9f7cb612 100644 --- a/web_console_v2/api/tools/local_runner/app_b.py +++ b/web_console_v2/api/tools/local_runner/app_b.py @@ -15,11 +15,14 @@ # coding: utf-8 import os import logging + +from envs import Envs from fedlearner_webconsole.app import create_app from tools.local_runner.initial_db import init_db BASE_DIR = os.path.abspath(os.path.dirname(__file__)) + class Config(object): SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'app_b.db') MYSQL_CHARSET = 'utf8mb4' @@ -30,10 +33,13 @@ class Config(object): LOGGING_LEVEL = logging.INFO GRPC_LISTEN_PORT = 1991 JWT_ACCESS_TOKEN_EXPIRES = 86400 + STORAGE_ROOT = Envs.STORAGE_ROOT START_GRPC_SERVER = True START_SCHEDULER = True START_COMPOSER = False + + app = create_app(Config) diff --git a/web_console_v2/api/tools/local_runner/run_a.sh b/web_console_v2/api/tools/local_runner/run_a.sh index a48b260ea..6622b5f4c 100755 --- a/web_console_v2/api/tools/local_runner/run_a.sh +++ b/web_console_v2/api/tools/local_runner/run_a.sh @@ -3,8 +3,9 @@ export FLASK_APP=app_a:app export FLASK_ENV=development flask create-db export K8S_CONFIG_PATH=$1 -export FEDLEARNER_WEBCONSOLE_POLLING_INTERVAL=1 +export FEDLEARNER_WEBCONSOLE_POLLING_INTERVAL=10 export SQLALCHEMY_DATABASE_URI="sqlite:///app_a.db" export FEATURE_MODEL_WORKFLOW_HOOK=True export FEATURE_MODEL_K8S_HOOK=True +export ES_READ_HOST=172.21.8.76 # aliyun-demo1 fedlearner-stack-elasticsearch-client flask run --host=0.0.0.0 --no-reload --eager-loading -p 9001 diff --git a/web_console_v2/api/tools/local_runner/run_b.sh b/web_console_v2/api/tools/local_runner/run_b.sh index 9eb7608aa..340f94763 100755 --- a/web_console_v2/api/tools/local_runner/run_b.sh +++ b/web_console_v2/api/tools/local_runner/run_b.sh @@ -7,4 +7,5 @@ export FEDLEARNER_WEBCONSOLE_POLLING_INTERVAL=1 export SQLALCHEMY_DATABASE_URI="sqlite:///app_b.db" export FEATURE_MODEL_WORKFLOW_HOOK=True export FEATURE_MODEL_K8S_HOOK=True +export ES_READ_HOST=172.21.14.199 # aliyun-demo2 fedlearner-stack-elasticsearch-client flask run --host=0.0.0.0 --no-reload --eager-loading -p 9002 diff --git a/web_console_v2/client/package.json b/web_console_v2/client/package.json index a6b05a876..0aa988a8a 100644 --- a/web_console_v2/client/package.json +++ b/web_console_v2/client/package.json @@ -5,7 +5,7 @@ "scripts": { "preinstall": "npx only-allow pnpm", "start": "node scripts/start.js", - "build": "node scripts/build.js", + "build": "node --max-old-space-size=4096 scripts/build.js", "test": "node scripts/test.js", "test:coverage": "npx jest --coverage", "lint": "eslint '*/**/*.{js,ts,tsx}' --fix", diff --git a/web_console_v2/client/src/App.tsx b/web_console_v2/client/src/App.tsx index 58ef482e0..1bcddae30 100644 --- a/web_console_v2/client/src/App.tsx +++ b/web_console_v2/client/src/App.tsx @@ -32,10 +32,11 @@ const AppSidebar = styled(Sidebar)` `; const AppMainContent = styled.main` + position: relative; display: flex; flex-direction: column; grid-area: main-content; - padding: var(--contentOuterPadding); + overflow: auto; overflow-anchor: auto; `; diff --git a/web_console_v2/client/src/assets/images/avatar.jpg b/web_console_v2/client/src/assets/images/avatar.jpg new file mode 100644 index 000000000..f19714c77 Binary files /dev/null and b/web_console_v2/client/src/assets/images/avatar.jpg differ diff --git a/web_console_v2/client/src/assets/images/avatar.svg b/web_console_v2/client/src/assets/images/avatar.svg deleted file mode 100644 index e5c65ad73..000000000 --- a/web_console_v2/client/src/assets/images/avatar.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/web_console_v2/client/src/assets/images/login-illustration.png b/web_console_v2/client/src/assets/images/login-illustration.png new file mode 100644 index 000000000..cdcf31465 Binary files /dev/null and b/web_console_v2/client/src/assets/images/login-illustration.png differ diff --git a/web_console_v2/client/src/assets/images/logo-colorful.svg b/web_console_v2/client/src/assets/images/logo-colorful.svg index a0c476217..f90316f4b 100644 --- a/web_console_v2/client/src/assets/images/logo-colorful.svg +++ b/web_console_v2/client/src/assets/images/logo-colorful.svg @@ -1,20 +1,20 @@ - - - - - + + + + + - - + + - - + + - - + + diff --git a/web_console_v2/client/src/components/BackButton/index.tsx b/web_console_v2/client/src/components/BackButton/index.tsx new file mode 100644 index 000000000..7a04963b0 --- /dev/null +++ b/web_console_v2/client/src/components/BackButton/index.tsx @@ -0,0 +1,29 @@ +import React, { FC } from 'react'; +import { Left } from 'components/IconPark'; +import GridRow from 'components/_base/GridRow'; +import styled from 'styled-components'; + +const Container = styled.div` + cursor: pointer; +`; + +type Props = { + onClick?: (evt: React.MouseEvent) => void; +}; + +const BackButton: FC = ({ onClick, children }) => { + return ( + + + + {children} + + + ); + + function onEleClick(evt: React.MouseEvent) { + onClick && onClick(evt); + } +}; + +export default BackButton; diff --git a/web_console_v2/client/src/components/BreadcrumbLink/index.tsx b/web_console_v2/client/src/components/BreadcrumbLink/index.tsx index 54e734aef..36dff226f 100644 --- a/web_console_v2/client/src/components/BreadcrumbLink/index.tsx +++ b/web_console_v2/client/src/components/BreadcrumbLink/index.tsx @@ -7,7 +7,6 @@ import { useTranslation } from 'react-i18next'; const Container = styled(Breadcrumb)` padding-left: 3px; - margin-bottom: 12px; `; type Props = { diff --git a/web_console_v2/client/src/components/Header/Account.tsx b/web_console_v2/client/src/components/Header/Account.tsx index c5401ab97..910c5fa1d 100644 --- a/web_console_v2/client/src/components/Header/Account.tsx +++ b/web_console_v2/client/src/components/Header/Account.tsx @@ -1,13 +1,12 @@ import React, { FC } from 'react'; import styled from 'styled-components'; import { userInfoQuery } from 'stores/user'; -import avatar from 'assets/images/avatar.svg'; +import avatar from 'assets/images/avatar.jpg'; import { useRecoilQuery } from 'hooks/recoil'; import { MixinCommonTransition, MixinSquare } from 'styles/mixins'; import { message, Popover, Button } from 'antd'; import GridRow from 'components/_base/GridRow'; import { Settings } from 'components/IconPark'; -// import LanguageSwitch from './LanguageSwitch'; import { Redirect, useHistory } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import store from 'store2'; @@ -15,16 +14,14 @@ import LOCAL_STORAGE_KEYS from 'shared/localStorageKeys'; import { useResetRecoilState } from 'recoil'; import { ErrorCodes } from 'typings/app'; import i18n from 'i18n'; -import { FedUserInfo, FedRoles } from 'typings/auth'; +import { FedUserInfo } from 'typings/auth'; import UserRoleBadge from 'components/UserRoleBadge'; -import Log from 'components/IconPark/icons/Log'; -import { logout } from 'services/user'; const Container = styled.div` ${MixinCommonTransition()} display: flex; align-items: center; - padding: 4px; + padding: 2px; cursor: pointer; border-radius: 50%; @@ -55,10 +52,6 @@ const UsernameRow = styled(GridRow)` margin-bottom: 0; } `; -// const LanguageRow = styled(Row)` -// height: 40px; -// margin-bottom: 10px; -// `; const ButtonRow = styled(GridRow)` height: 40px; margin-bottom: 10px; @@ -78,38 +71,17 @@ export const ACCOUNT_CHANNELS = { click_settings: 'click_settings', }; -const AccountPopover: FC<{ userInfo: FedUserInfo }> = ({ userInfo }) => { +const AccountPopover: FC = () => { const history = useHistory(); const { t } = useTranslation(); const resetUserInfo = useResetRecoilState(userInfoQuery); - let systemLogs = undefined; - - if (userInfo.role === FedRoles.Admin) { - systemLogs = ( - - - {t('settings.system_log')} - - ); - } return (
- {/* - - - - {t('app.switch_lng')} - - - - */} - - {t('settings.system_setting')} + {t('app.system_settings')} - {systemLogs} {t('app.logout')} @@ -118,7 +90,8 @@ const AccountPopover: FC<{ userInfo: FedUserInfo }> = ({ userInfo }) => { async function onLogoutClick() { try { - await logout(); + // logout api is now unavailable, only fe remove the user storage. + // await logout(); store.remove(LOCAL_STORAGE_KEYS.current_user); resetUserInfo(); history.push('/login'); @@ -130,10 +103,6 @@ const AccountPopover: FC<{ userInfo: FedUserInfo }> = ({ userInfo }) => { function onSettingClick() { history.push('/settings'); } - - function onSystemLogClick() { - window.open('/v2/logs/system', '_blank noopener'); - } }; const Username: FC<{ userInfo: FedUserInfo }> = ({ userInfo }) => { return ( @@ -162,7 +131,7 @@ function HeaderAccount() { return ( } + content={} title={} placement="bottomLeft" > diff --git a/web_console_v2/client/src/components/Header/ProjectSelect.tsx b/web_console_v2/client/src/components/Header/ProjectSelect.tsx new file mode 100644 index 000000000..e45ae4d0a --- /dev/null +++ b/web_console_v2/client/src/components/Header/ProjectSelect.tsx @@ -0,0 +1,98 @@ +import React, { FC, memo } from 'react'; +import styled from 'styled-components'; +import { useTranslation } from 'react-i18next'; +import { Dropdown } from 'antd'; +import PrettyMenu, { PrettyMenuItem } from 'components/PrettyMenu'; +import { useRecoilQuery } from 'hooks/recoil'; +import { projectListQuery, projectState } from 'stores/project'; +import GridRow from 'components/_base/GridRow'; +import { useRecoilState } from 'recoil'; +import { CaretDown } from 'components/IconPark'; +import { CloseCircleFilled } from '@ant-design/icons'; +import store from 'store2'; +import LOCAL_STORAGE_KEYS from 'shared/localStorageKeys'; +import { Project } from 'typings/project'; + +const Trigger = styled(GridRow)` + grid-area: project-select; + font-size: 14px; + cursor: pointer; + + &:hover { + > [data-name='clear'] { + display: block; + } + + > [data-name='arrow']:not([data-project-selected='false']) { + display: none; + } + } +`; +const Placeholder = styled.small` + opacity: 0.4; +`; +const ProjectItem = styled.div` + cursor: pointer; +`; +const ClearButton = styled(CloseCircleFilled)` + display: none; + font-size: 12px; +`; + +const ProjectSelect: FC = memo(() => { + const { t } = useTranslation(); + + const projectsQuery = useRecoilQuery(projectListQuery); + const [state, setProjectState] = useRecoilState(projectState); + + if (projectsQuery.isLoading || !projectsQuery.data) { + return ; + } + + const hasProjectSelected = Boolean(state.current); + + return ( + + {projectsQuery.data?.map((item, index) => ( + onProjectSelect(item)}> + +
{item.name}
+
+
+ ))} + {projectsQuery.data?.length === 0 && t('project.placeholder_no_project')} + + } + placement="bottomCenter" + > + + {state.current ? ( + {state.current.name} + ) : ( + {t('project.placeholder_global_project_filter')} + )} + {hasProjectSelected && } + + +
+ ); + + function onClearCick(evt: React.MouseEvent) { + evt.stopPropagation(); + setProjectState({ current: undefined }); + store.remove(LOCAL_STORAGE_KEYS.current_project); + } + function onProjectSelect(item: Project) { + setProjectState({ current: item }); + store.set(LOCAL_STORAGE_KEYS.current_project, item); + } +}); + +export default ProjectSelect; diff --git a/web_console_v2/client/src/components/Header/index.tsx b/web_console_v2/client/src/components/Header/index.tsx index 526cc14c1..d0028f89a 100644 --- a/web_console_v2/client/src/components/Header/index.tsx +++ b/web_console_v2/client/src/components/Header/index.tsx @@ -1,11 +1,12 @@ import React from 'react'; import styled from 'styled-components'; import HeaderAccount from './Account'; -import { Button, Tooltip } from 'antd'; +import { Tooltip } from 'antd'; import logo from 'assets/images/logo-colorful.svg'; import { StyledComponetProps } from 'typings/component'; import { QuestionCircle } from 'components/IconPark'; import { useTranslation } from 'react-i18next'; +import ProjectSelect from './ProjectSelect'; export const Z_INDEX_HEADER = 1001; export const Z_INDEX_GREATER_THAN_HEADER = 1002; @@ -16,8 +17,8 @@ const Container = styled.header` top: 0; display: grid; align-items: center; - grid-template-areas: 'logo . language account-info'; - grid-template-columns: auto 1fr auto auto; + grid-template-areas: 'logo project-select . help account-info'; + grid-template-columns: auto auto 1fr auto auto; gap: 12px; height: var(--headerHeight); padding: 0 30px; @@ -27,10 +28,14 @@ const Container = styled.header` `; const LogoLink = styled.a` grid-area: logo; - - > img { - height: 32px; - } +`; +const Logo = styled.img` + height: 32px; +`; +const HelpIcon = styled(QuestionCircle)` + font-size: 14px; + margin-right: 10px; + cursor: pointer; `; function Header({ className }: StyledComponetProps) { @@ -39,12 +44,16 @@ function Header({ className }: StyledComponetProps) { return ( - Federation Learner logo + - {/* This empty element is used to fill the space blank */} + + + + {/* This empty element is used to fill the blank sapce */}
+ - + + + - - - - - - + + + + + ); async function backToList() { history.push('/users'); @@ -92,6 +88,7 @@ const UserForm: FC<{ isEdit?: boolean; onSubmit?: any; initialValues?: any }> = async function onFinish(data: any) { try { toggleSubmitting(true); + data.password = btoa(data.password); await onSubmit(data); } catch { // ignore error diff --git a/web_console_v2/client/src/views/Users/UserList/index.tsx b/web_console_v2/client/src/views/Users/UserList/index.tsx index 29abd8684..1b7ca4723 100644 --- a/web_console_v2/client/src/views/Users/UserList/index.tsx +++ b/web_console_v2/client/src/views/Users/UserList/index.tsx @@ -1,5 +1,5 @@ import React, { FC, useState, useMemo } from 'react'; -import ListPageLayout from 'components/ListPageLayout'; +import SharedPageLayout from 'components/SharedPageLayout'; import { useTranslation } from 'react-i18next'; import { Row, Button, Col, Form, Input, Table, message, Tag, Popconfirm } from 'antd'; import { useHistory, Link } from 'react-router-dom'; @@ -108,7 +108,7 @@ const UsersList: FC = () => { const isEmpty = !query.isFetching && query.data?.data.length === 0; return ( - + ); + + async function onClick() { + try { + const blob = await request(getTemplateDownloadHref(id), { + responseType: 'blob', + }); + saveBlob(blob, `${name}.json`); + } catch (error) { + message.error(error.message); + } + } }; const DuplicateTemplate: FC<{ template: WorkflowTemplate }> = ({ template: { id } }) => { @@ -170,15 +176,7 @@ const TemplateList: FC = () => { <> - - - {t('menu.label_workflow_tpl')} - - } - tip="This feature is experimental" - > + { /> )} - + ); diff --git a/web_console_v2/client/src/views/Workflows/CreateWorkflow/StepOneBasic/index.tsx b/web_console_v2/client/src/views/Workflows/CreateWorkflow/StepOneBasic/index.tsx index 77182a324..b2a94311f 100644 --- a/web_console_v2/client/src/views/Workflows/CreateWorkflow/StepOneBasic/index.tsx +++ b/web_console_v2/client/src/views/Workflows/CreateWorkflow/StepOneBasic/index.tsx @@ -244,16 +244,20 @@ const WorkflowsCreateStepOne: FC = ({ setWorkflowConfigForm(parsedTpl.config as WorkflowConfig); } async function getWorkflowDetail() { - const { data } = await getWorkflowDetailById(params.id); + let { data } = await getWorkflowDetailById(params.id); + data = parseComplexDictField(data); + setWorkflow(data); formInstance.setFieldsValue((data as any) as CreateWorkflowBasicForm); } async function getPeerWorkflow() { const res = await getPeerWorkflowsConfig(params.id); - const anyPeerWorkflow = Object.values(res.data).find((item) => !!item.config)!; + const anyPeerWorkflow = parseComplexDictField( + Object.values(res.data).find((item) => Boolean(item.uuid))!, + )!; - setPeerConfig(anyPeerWorkflow.config!); + setPeerConfig(anyPeerWorkflow.config ?? (undefined as never)); setGroupAlias(anyPeerWorkflow.config?.group_alias || ''); return anyPeerWorkflow; diff --git a/web_console_v2/client/src/views/Workflows/CreateWorkflow/SteptTwoConfig/InspectPeerConfig.tsx b/web_console_v2/client/src/views/Workflows/CreateWorkflow/SteptTwoConfig/InspectPeerConfig.tsx deleted file mode 100644 index 93b85115e..000000000 --- a/web_console_v2/client/src/views/Workflows/CreateWorkflow/SteptTwoConfig/InspectPeerConfig.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import React, { FC } from 'react'; -import styled from 'styled-components'; -import { Modal, Tabs, Button } from 'antd'; -import { ModalProps } from 'antd/lib/modal/Modal'; -import { Close } from 'components/IconPark'; -import { useTranslation } from 'react-i18next'; -import { WorkflowConfig } from 'typings/workflow'; -import PropertyList from 'components/PropertyList'; -import { Z_INDEX_GREATER_THAN_HEADER } from 'components/Header'; - -const InspectModal = styled(Modal)` - top: 20%; - - .ant-modal-header { - display: none; - } - .ant-modal-body { - padding: 0; - } -`; -const ModalHeader = styled.h2` - padding: 20px; - padding-bottom: 10px; - margin-bottom: 0; - font-size: 16px; - line-height: 24px; -`; -const JobTabs = styled(Tabs)` - &.ant-tabs-top > .ant-tabs-nav { - margin-bottom: 9px; - } -`; - -const InspectPeerConfig: FC< - ModalProps & { toggleVisible: Function; config: WorkflowConfig | null } -> = ({ config, toggleVisible, ...props }) => { - const { t } = useTranslation(); - - if (!config) return null; - - const jobs = config.job_definitions; - - return ( - } onClick={closeModal} />} - > - {t('workflow.peer_config')} - {config && ( - - {jobs.map((item) => { - return ( - - { - return { - label: vari.name, - value: vari.value, - }; - })} - /> - - ); - })} - - )} - - ); - - function closeModal() { - toggleVisible(false); - } -}; - -export default InspectPeerConfig; diff --git a/web_console_v2/client/src/views/Workflows/CreateWorkflow/SteptTwoConfig/index.tsx b/web_console_v2/client/src/views/Workflows/CreateWorkflow/SteptTwoConfig/index.tsx index 5145a635e..4e5a22fd1 100644 --- a/web_console_v2/client/src/views/Workflows/CreateWorkflow/SteptTwoConfig/index.tsx +++ b/web_console_v2/client/src/views/Workflows/CreateWorkflow/SteptTwoConfig/index.tsx @@ -33,7 +33,7 @@ import { to } from 'shared/helpers'; import { WorkflowCreateProps } from '..'; import { WorkflowAcceptPayload, WorkflowInitiatePayload } from 'typings/workflow'; import { Variable } from 'typings/variable'; -import InspectPeerConfigs from './InspectPeerConfig'; +import InspectPeerConfigs from '../../InspectPeerConfig'; import { ExclamationCircle } from 'components/IconPark'; import { Z_INDEX_GREATER_THAN_HEADER } from 'components/Header'; import { stringifyComplexDictField } from 'shared/formSchema'; @@ -135,7 +135,7 @@ const CanvasAndForm: FC = ({ isInitiate, isAccept }) => { ref={drawerRef as any} visible={drawerVisible} toggleVisible={toggleDrawerVisible} - showPeerConfigButton={isAccept} + showPeerConfigButton={isAccept && Boolean(peerConfig)} currentIdx={currNode?.data.index} nodesCount={jobNodes.length} jobDefinition={currNode?.data.raw} diff --git a/web_console_v2/client/src/views/Workflows/CreateWorkflow/index.tsx b/web_console_v2/client/src/views/Workflows/CreateWorkflow/index.tsx index bdf59e2ac..3c699bec4 100644 --- a/web_console_v2/client/src/views/Workflows/CreateWorkflow/index.tsx +++ b/web_console_v2/client/src/views/Workflows/CreateWorkflow/index.tsx @@ -1,13 +1,14 @@ import React, { FC, useState } from 'react'; import styled from 'styled-components'; import { Steps, Row, Card } from 'antd'; -import BreadcrumbLink from 'components/BreadcrumbLink'; import StepOneBasic from './StepOneBasic'; import SteptTwoConfig from './SteptTwoConfig'; -import { Route, useParams } from 'react-router-dom'; +import { Route, useHistory, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { useUnmount } from 'react-use'; import { useResetCreateForms } from 'hooks/workflow'; +import SharedPageLayout from 'components/SharedPageLayout'; +import BackButton from 'components/BackButton'; const { Step } = Steps; @@ -39,6 +40,7 @@ export type WorkflowCreateProps = { */ const WorkflowsCreate: FC = (workflowCreateProps) => { const { t } = useTranslation(); + const history = useHistory(); const params = useParams<{ step: keyof typeof CreateSteps; id?: string }>(); const [currentStep, setStep] = useState(CreateSteps[params.step || 'basic']); const reset = useResetCreateForms(); @@ -48,14 +50,10 @@ const WorkflowsCreate: FC = (workflowCreateProps) => { }); return ( - <> - - + history.goBack()}>{t('menu.label_workflow')}} + contentWrapByCard={false} + > @@ -93,7 +91,7 @@ const WorkflowsCreate: FC = (workflowCreateProps) => { render={(props) => } /> - + ); function setToConfigStep() { diff --git a/web_console_v2/client/src/views/Workflows/EditWorkflow/StepOneBasic/index.tsx b/web_console_v2/client/src/views/Workflows/EditWorkflow/StepOneBasic/index.tsx index 1c3e22970..90c12a33d 100644 --- a/web_console_v2/client/src/views/Workflows/EditWorkflow/StepOneBasic/index.tsx +++ b/web_console_v2/client/src/views/Workflows/EditWorkflow/StepOneBasic/index.tsx @@ -93,6 +93,7 @@ const WorkflowsCreateStepOne: FC<{ onSuccess?: any }> = ({ onSuccess }) => { ); const peerErrorMsg = (peerWorkflowQuery.error as Error)?.message; + useEffect(() => { if (peerErrorMsg) { notification.error({ @@ -256,7 +257,9 @@ const WorkflowsCreateStepOne: FC<{ onSuccess?: any }> = ({ onSuccess }) => { setWorkflowConfigForm(parsedTpl.config as WorkflowConfig); } async function getWorkflowDetail() { - const { data } = await getWorkflowDetailById(params.id); + let { data } = await getWorkflowDetailById(params.id); + data = parseComplexDictField(data); + setWorkflow(data); setWorkflowConfigForm(data.config as WorkflowConfig); formInstance.setFieldsValue((data as any) as CreateWorkflowBasicForm); @@ -264,9 +267,11 @@ const WorkflowsCreateStepOne: FC<{ onSuccess?: any }> = ({ onSuccess }) => { async function getPeerWorkflow() { const res = await getPeerWorkflowsConfig(params.id); - const anyPeerWorkflow = Object.values(res.data).find((item) => !!item.config)!; + const anyPeerWorkflow = parseComplexDictField( + Object.values(res.data).find((item) => Boolean(item.uuid))!, + )!; - setPeerConfig(anyPeerWorkflow.config!); + setPeerConfig(anyPeerWorkflow.config ?? (undefined as never)); setGroupAlias(anyPeerWorkflow.config?.group_alias || ''); return anyPeerWorkflow; diff --git a/web_console_v2/client/src/views/Workflows/EditWorkflow/SteptTwoConfig/index.tsx b/web_console_v2/client/src/views/Workflows/EditWorkflow/SteptTwoConfig/index.tsx index 5d94f5dc1..21c1cc97e 100644 --- a/web_console_v2/client/src/views/Workflows/EditWorkflow/SteptTwoConfig/index.tsx +++ b/web_console_v2/client/src/views/Workflows/EditWorkflow/SteptTwoConfig/index.tsx @@ -33,7 +33,7 @@ import { patchWorkflow } from 'services/workflow'; import { to } from 'shared/helpers'; import { WorkflowAcceptPayload } from 'typings/workflow'; import { Variable } from 'typings/variable'; -import InspectPeerConfigs from './InspectPeerConfig'; +import InspectPeerConfigs from '../../InspectPeerConfig'; import { ExclamationCircle } from 'components/IconPark'; import { Z_INDEX_GREATER_THAN_HEADER } from 'components/Header'; import { stringifyComplexDictField } from 'shared/formSchema'; @@ -141,7 +141,7 @@ const CanvasAndForm: FC = () => { readonly={isCurrNodeReused} message={isCurrNodeReused ? t('workflow.msg_resued_job_cannot_edit') : ''} toggleVisible={toggleDrawerVisible} - showPeerConfigButton + showPeerConfigButton={Boolean(peerConfig)} currentIdx={currNode?.data.index} nodesCount={jobNodes.length} jobDefinition={currNode?.data.raw} diff --git a/web_console_v2/client/src/views/Workflows/EditWorkflow/index.tsx b/web_console_v2/client/src/views/Workflows/EditWorkflow/index.tsx index ee7f79f48..1272f00c1 100644 --- a/web_console_v2/client/src/views/Workflows/EditWorkflow/index.tsx +++ b/web_console_v2/client/src/views/Workflows/EditWorkflow/index.tsx @@ -1,13 +1,14 @@ import React, { FC, useState } from 'react'; import styled from 'styled-components'; import { Steps, Row, Card } from 'antd'; -import BreadcrumbLink from 'components/BreadcrumbLink'; import StepOneBasic from './StepOneBasic'; import SteptTwoConfig from './SteptTwoConfig'; -import { Route, useParams } from 'react-router-dom'; +import { Route, useHistory, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { useUnmount } from 'react-use'; import { useResetCreateForms } from 'hooks/workflow'; +import SharedPageLayout from 'components/SharedPageLayout'; +import BackButton from 'components/BackButton'; const { Step } = Steps; @@ -27,6 +28,7 @@ enum CreateSteps { const WorkflowsEdit: FC = () => { const { t } = useTranslation(); + const history = useHistory(); const params = useParams<{ step: keyof typeof CreateSteps; id?: string }>(); const [currentStep, setStep] = useState(CreateSteps[params.step || 'basic']); const reset = useResetCreateForms(); @@ -36,14 +38,10 @@ const WorkflowsEdit: FC = () => { }); return ( - <> - - + history.goBack()}>{t('menu.label_workflow')}} + contentWrapByCard={false} + > @@ -63,7 +61,7 @@ const WorkflowsEdit: FC = () => { /> - + ); function setToConfigStep() { diff --git a/web_console_v2/client/src/views/Workflows/ForkWorkflow/index.tsx b/web_console_v2/client/src/views/Workflows/ForkWorkflow/index.tsx index bab3264c7..f79eb7e53 100644 --- a/web_console_v2/client/src/views/Workflows/ForkWorkflow/index.tsx +++ b/web_console_v2/client/src/views/Workflows/ForkWorkflow/index.tsx @@ -1,13 +1,14 @@ import React, { FC, useState } from 'react'; import styled from 'styled-components'; import { Steps, Row, Card } from 'antd'; -import BreadcrumbLink from 'components/BreadcrumbLink'; -import { Route, useParams } from 'react-router-dom'; +import { Route, useParams, useHistory } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { useUnmount } from 'react-use'; import { useResetForkForms } from 'hooks/workflow'; import StepOneBasic from './StepOneBasic'; import StepTwoConfig from './StepTwoConfig'; +import SharedPageLayout from 'components/SharedPageLayout'; +import BackButton from 'components/BackButton'; const { Step } = Steps; @@ -26,6 +27,7 @@ enum ForkSteps { const ForkWorkflow: FC = () => { const { t } = useTranslation(); + const history = useHistory(); const params = useParams<{ step: keyof typeof ForkSteps; id?: string }>(); const [currentStep, setStep] = useState(ForkSteps[params.step || 'basic']); const reset = useResetForkForms(); @@ -36,14 +38,10 @@ const ForkWorkflow: FC = () => { }); return ( - <> - - + history.goBack()}>{t('menu.label_workflow')}} + contentWrapByCard={false} + > @@ -63,7 +61,7 @@ const ForkWorkflow: FC = () => { /> - + ); function setToConfigStep() { diff --git a/web_console_v2/client/src/views/Workflows/EditWorkflow/SteptTwoConfig/InspectPeerConfig.tsx b/web_console_v2/client/src/views/Workflows/InspectPeerConfig.tsx similarity index 100% rename from web_console_v2/client/src/views/Workflows/EditWorkflow/SteptTwoConfig/InspectPeerConfig.tsx rename to web_console_v2/client/src/views/Workflows/InspectPeerConfig.tsx diff --git a/web_console_v2/client/src/views/Workflows/WorkflowActions.tsx b/web_console_v2/client/src/views/Workflows/WorkflowActions.tsx index 61d0ce07d..f43999f8b 100644 --- a/web_console_v2/client/src/views/Workflows/WorkflowActions.tsx +++ b/web_console_v2/client/src/views/Workflows/WorkflowActions.tsx @@ -222,7 +222,7 @@ const WorkflowActions: FC = ({ workflow, type = 'default', without = [], return message.error(t('workflow.msg_get_peer_cfg_failed') + error.message); } - const anyPeerWorkflow = Object.values(res.data).find((item) => !!item.config)!; + const anyPeerWorkflow = Object.values(res.data).find((item) => !!item.uuid)!; if (!anyPeerWorkflow.forkable) { message.warning(t('workflow.msg_unforkable')); return; diff --git a/web_console_v2/client/src/views/Workflows/WorkflowDetail/GlobalConfigDrawer.tsx b/web_console_v2/client/src/views/Workflows/WorkflowDetail/GlobalConfigDrawer.tsx new file mode 100644 index 000000000..06db160d1 --- /dev/null +++ b/web_console_v2/client/src/views/Workflows/WorkflowDetail/GlobalConfigDrawer.tsx @@ -0,0 +1,120 @@ +import ErrorBoundary from 'antd/lib/alert/ErrorBoundary'; +import React, { ForwardRefRenderFunction } from 'react'; +import styled from 'styled-components'; +import { Drawer, Row, Button, Tag } from 'antd'; +import { DrawerProps } from 'antd/lib/drawer'; +import { NodeData } from 'components/WorkflowJobsCanvas/types'; +import { useTranslation } from 'react-i18next'; +import { Close } from 'components/IconPark'; +import GridRow from 'components/_base/GridRow'; +import PropertyList from 'components/PropertyList'; +import { WorkflowExecutionDetails } from 'typings/workflow'; +import { Link } from 'react-router-dom'; +import WhichProject from 'components/WhichProject'; +import { useStoreActions } from 'react-flow-renderer'; + +const Container = styled(Drawer)` + top: 60px; + + .ant-drawer-body { + padding-top: 0; + padding-bottom: 200px; + } +`; +const DrawerHeader = styled(Row)` + position: sticky; + z-index: 2; + top: 0; + margin: 0 -24px 0; + padding: 20px 16px 20px 24px; + background-color: white; + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.12); +`; +const DrawerTitle = styled.h3` + position: relative; + margin-bottom: 0; + margin-right: 10px; +`; + +interface Props extends DrawerProps { + isPeerSide?: boolean; + jobData?: NodeData; + workflow?: WorkflowExecutionDetails; + toggleVisible?: Function; +} + +export type JobExecutionDetailsExposedRef = {}; + +const GlobalConfigDrawer: ForwardRefRenderFunction = ({ + jobData, + workflow, + isPeerSide = false, + toggleVisible, + ...props +}) => { + const { t } = useTranslation(); + + const setSelectedElements = useStoreActions((actions) => actions.setSelectedElements); + + if (!jobData || !jobData.raw) { + return null; + } + + const job = jobData.raw; + + const workflowProps = [ + { + label: t('workflow.label_template_name'), + value: workflow?.config?.group_alias || ( + {t('workflow.job_node_pending')} + ), + }, + { + label: t('workflow.label_project'), + // TODO: peerWorkflow no project id + value: , + }, + // Display workflow global variables + ...(workflow?.config?.variables || []).map((item) => ({ + label: item.name, + value: item.value, + })), + ]; + + return ( + + + + + {job.name} + + {isPeerSide ? ( + {t('workflow.peer_config')} + ) : ( + {t('workflow.our_config')} + )} + + + + } + contentWrapByCard={false} + > + + + + + + {workflow?.name} + + {workflow && } + + {workflow && ( + + + )} - - - {jobsWithExeDetails.length === 0 ? ( - - - - ) : ( - - toggleDrawerVisible(false)} - /> - + + + {isForked && originWorkflowQuery.isSuccess && ( + + + {t('workflow.forked_from')} + + {originWorkflowQuery.data?.data.name} + + )} - - {/* Peer config */} - {peerJobsVisible && ( + + + + + {/* Our config */} - {t('workflow.peer_config')} + {t('workflow.our_config')} - + {!peerJobsVisible && ( + + )} - {peerJobsWithExeDetails.length === 0 ? ( + {jobsWithExeDetails.length === 0 ? ( - {peerWorkflowQuery.isFetching ? ( - - ) : ( - - )} + ) : ( toggleDrawerVisible(false)} /> )} - )} - - - - - - + {/* Peer config */} + {peerJobsVisible && ( + + + + {t('workflow.peer_config')} + + + + + + {peerJobsWithExeDetails.length === 0 ? ( + + {peerWorkflowQuery.isFetching ? ( + + ) : ( + + )} + + ) : ( + + toggleDrawerVisible(false)} + /> + + )} + + )} + + + + + + + + ); function viewJobDetail(jobNode: JobNode) { diff --git a/web_console_v2/client/src/views/Workflows/WorkflowList/index.tsx b/web_console_v2/client/src/views/Workflows/WorkflowList/index.tsx index 0883cece6..6f3af6088 100644 --- a/web_console_v2/client/src/views/Workflows/WorkflowList/index.tsx +++ b/web_console_v2/client/src/views/Workflows/WorkflowList/index.tsx @@ -1,21 +1,21 @@ import React, { FC, useEffect, useState } from 'react'; import styled from 'styled-components'; -import { Row, Col, Button, Form, Input, Select, Table, message, Spin } from 'antd'; +import { Row, Col, Button, Form, Input, Table, message, Spin } from 'antd'; import { Link, useHistory } from 'react-router-dom'; import { useQuery } from 'react-query'; import { fetchWorkflowList } from 'services/workflow'; import i18n from 'i18n'; import { formatTimestamp } from 'shared/date'; import { useTranslation } from 'react-i18next'; -import ListPageLayout from 'components/ListPageLayout'; +import SharedPageLayout from 'components/SharedPageLayout'; import { Workflow } from 'typings/workflow'; import WorkflowStage from './WorkflowStage'; import WorkflowActions from '../WorkflowActions'; import WhichProject from 'components/WhichProject'; import NoResult from 'components/NoResult'; -import { useRecoilQuery } from 'hooks/recoil'; -import { projectListQuery } from 'stores/project'; +import { projectState } from 'stores/project'; import { isInvalid } from 'shared/workflow'; +import { useRecoilValue } from 'recoil'; const FilterItem = styled(Form.Item)` > .ant-form-item-control { @@ -121,11 +121,11 @@ const WorkflowList: FC = () => { const [listData, setList] = useState([]); const [params, setParams] = useState({ keyword: '', uuid: '' }); - const projectsQuery = useRecoilQuery(projectListQuery); + const project = useRecoilValue(projectState); const { isLoading, isError, data: res, error, refetch } = useQuery( - ['fetchWorkflowList', params.project, params.keyword, params.uuid], - () => fetchWorkflowList(params), + ['fetchWorkflowList', params.keyword, params.uuid, project.current?.id], + () => fetchWorkflowList({ ...params, project: project.current?.id }), ); if (isError && error) { @@ -140,7 +140,7 @@ const WorkflowList: FC = () => { return ( - +