forked from cerc-io/stack-orchestrator
Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc4396d593 | ||
|
|
f826f50c4d | ||
|
|
b83465767d | ||
|
|
50509203d1 | ||
|
|
282e175566 | ||
|
|
635aa7037b | ||
|
|
9877cfaf85 | ||
|
|
c642e5d490 | ||
|
|
02c49d66f5 | ||
|
|
90cebdb7a6 | ||
|
|
1f9653e6f7 | ||
|
|
0587813dd0 | ||
|
|
4b3ea7c30f | ||
|
|
db8aec52aa | ||
|
|
b83030f63b | ||
|
|
a3eb3c0bb0 | ||
|
|
eae2af7ccc | ||
|
|
837e443800 |
@@ -1,23 +1,16 @@
|
|||||||
name: K8s Deploy Test
|
name: K8s Deploy Test
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
|
||||||
branches: '*'
|
|
||||||
push:
|
push:
|
||||||
branches:
|
branches: '*'
|
||||||
- main
|
paths:
|
||||||
- ci-test
|
- '!**'
|
||||||
paths-ignore:
|
- '.gitea/workflows/triggers/fixturenet-laconicd-test'
|
||||||
- '.gitea/workflows/triggers/*'
|
|
||||||
|
|
||||||
# Needed until we can incorporate docker startup into the executor container
|
|
||||||
env:
|
|
||||||
DOCKER_HOST: unix:///var/run/dind.sock
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
name: "Run deploy test suite"
|
name: "Run deploy test suite on kind/k8s"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04-with-syn-ethdb
|
||||||
steps:
|
steps:
|
||||||
- name: "Clone project repository"
|
- name: "Clone project repository"
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@@ -41,15 +34,9 @@ jobs:
|
|||||||
run: ./scripts/create_build_tag_file.sh
|
run: ./scripts/create_build_tag_file.sh
|
||||||
- name: "Build local shiv package"
|
- name: "Build local shiv package"
|
||||||
run: ./scripts/build_shiv_package.sh
|
run: ./scripts/build_shiv_package.sh
|
||||||
- name: Start dockerd # Also needed until we can incorporate into the executor
|
- name: "Install kind"
|
||||||
run: |
|
run: ./tests/scripts/install-kind.sh
|
||||||
dockerd -H $DOCKER_HOST --userland-proxy=false &
|
- name: "Install Kubectl"
|
||||||
sleep 5
|
run: ./tests/scripts/install-kubectl.sh
|
||||||
- name: "Install Go"
|
- name: "Run k8s deployment test"
|
||||||
uses: actions/setup-go@v4
|
run: ./tests/k8s-deploy/run-deploy-test.sh
|
||||||
with:
|
|
||||||
go-version: '1.21'
|
|
||||||
- name: "Install Kind"
|
|
||||||
run: go install sigs.k8s.io/kind@v0.20.0
|
|
||||||
- name: "Debug Kind"
|
|
||||||
run: kind create cluster --retain && docker logs kind-control-plane
|
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ jobs:
|
|||||||
run: ./scripts/create_build_tag_file.sh
|
run: ./scripts/create_build_tag_file.sh
|
||||||
- name: "Build local shiv package"
|
- name: "Build local shiv package"
|
||||||
run: ./scripts/build_shiv_package.sh
|
run: ./scripts/build_shiv_package.sh
|
||||||
|
- name: "Install wget" # 20240109 - Only needed until the executors are updated.
|
||||||
|
run: apt update && apt install -y wget
|
||||||
- name: Start dockerd # Also needed until we can incorporate into the executor
|
- name: Start dockerd # Also needed until we can incorporate into the executor
|
||||||
run: |
|
run: |
|
||||||
dockerd -H $DOCKER_HOST --userland-proxy=false &
|
dockerd -H $DOCKER_HOST --userland-proxy=false &
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Change this file to trigger running the test-k8s-deploy CI job
|
||||||
@@ -2,7 +2,7 @@ services:
|
|||||||
laconicd:
|
laconicd:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
image: cerc/laconicd:local
|
image: cerc/laconicd:local
|
||||||
command: ["sh", "/docker-entrypoint-scripts.d/create-fixturenet.sh"]
|
entrypoint: ["sh", "/docker-entrypoint-scripts.d/create-fixturenet.sh"]
|
||||||
volumes:
|
volumes:
|
||||||
# The cosmos-sdk node's database directory:
|
# The cosmos-sdk node's database directory:
|
||||||
- laconicd-data:/root/.laconicd
|
- laconicd-data:/root/.laconicd
|
||||||
@@ -15,12 +15,12 @@ services:
|
|||||||
- "6060"
|
- "6060"
|
||||||
- "26657"
|
- "26657"
|
||||||
- "26656"
|
- "26656"
|
||||||
- "9473"
|
- "9473:9473"
|
||||||
- "8545"
|
- "8545"
|
||||||
- "8546"
|
- "8546"
|
||||||
- "9090"
|
- "9090"
|
||||||
- "9091"
|
- "9091"
|
||||||
- "1317"
|
- "1317:1317"
|
||||||
cli:
|
cli:
|
||||||
image: cerc/laconic-registry-cli:local
|
image: cerc/laconic-registry-cli:local
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
version: "3.2"
|
||||||
|
|
||||||
|
services:
|
||||||
|
geojson:
|
||||||
|
image: cerc/geojson:local
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 0.0.0.0:8080:8080
|
||||||
@@ -2,8 +2,10 @@ version: "3.7"
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
grafana:
|
grafana:
|
||||||
image: grafana/grafana
|
image: grafana/grafana:10.2.2
|
||||||
restart: always
|
restart: always
|
||||||
|
environment:
|
||||||
|
GF_SERVER_ROOT_URL: ${GF_SERVER_ROOT_URL}
|
||||||
volumes:
|
volumes:
|
||||||
- ../config/monitoring/grafana/provisioning:/etc/grafana/provisioning
|
- ../config/monitoring/grafana/provisioning:/etc/grafana/provisioning
|
||||||
- ../config/monitoring/grafana/dashboards:/etc/grafana/dashboards
|
- ../config/monitoring/grafana/dashboards:/etc/grafana/dashboards
|
||||||
|
|||||||
@@ -5,12 +5,11 @@ services:
|
|||||||
image: prom/node-exporter:latest
|
image: prom/node-exporter:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command:
|
command:
|
||||||
|
- '--web.listen-address=:9100'
|
||||||
- '--path.rootfs=/host'
|
- '--path.rootfs=/host'
|
||||||
- '--collector.systemd'
|
- '--collector.systemd'
|
||||||
- '--collector.processes'
|
- '--collector.processes'
|
||||||
network_mode: host
|
network_mode: host
|
||||||
pid: host
|
pid: host
|
||||||
ports:
|
|
||||||
- 9100
|
|
||||||
volumes:
|
volumes:
|
||||||
- '/:/host:ro,rslave'
|
- '/:/host:ro,rslave'
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ services:
|
|||||||
restart: on-failure
|
restart: on-failure
|
||||||
environment:
|
environment:
|
||||||
- NEXT_PUBLIC_WEB_API_BASE_URL=${CERC_WEB_API_BASE_URL}
|
- NEXT_PUBLIC_WEB_API_BASE_URL=${CERC_WEB_API_BASE_URL}
|
||||||
|
- ASSET_LIST_COMMIT_HASH=a326bcefc51372b4912be5a2a2fa84a5d142a438
|
||||||
- NEXT_PUBLIC_BASEPATH=/apps/osmosis
|
- NEXT_PUBLIC_BASEPATH=/apps/osmosis
|
||||||
- NEXT_PUBLIC_URBIT_DEPLOYMENT=true
|
- NEXT_PUBLIC_URBIT_DEPLOYMENT=true
|
||||||
working_dir: /app/packages/web
|
working_dir: /app/packages/web
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ services:
|
|||||||
restart: on-failure
|
restart: on-failure
|
||||||
environment:
|
environment:
|
||||||
- NEXT_PUBLIC_WEB_API_BASE_URL=${CERC_WEB_API_BASE_URL}
|
- NEXT_PUBLIC_WEB_API_BASE_URL=${CERC_WEB_API_BASE_URL}
|
||||||
|
- ASSET_LIST_COMMIT_HASH=a326bcefc51372b4912be5a2a2fa84a5d142a438
|
||||||
working_dir: /app/packages/web
|
working_dir: /app/packages/web
|
||||||
command: ["./build-app.sh"]
|
command: ["./build-app.sh"]
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ version: "3.7"
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
prometheus:
|
prometheus:
|
||||||
image: prom/prometheus
|
image: prom/prometheus:v2.49.1
|
||||||
restart: always
|
restart: always
|
||||||
volumes:
|
volumes:
|
||||||
- ../config/monitoring/prometheus:/etc/prometheus
|
- ../config/monitoring/prometheus:/etc/prometheus
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
# https://www.clever-cloud.com/blog/features/2021/12/03/slack-alerts-for-grafana/
|
||||||
|
|
||||||
|
apiVersion: 1
|
||||||
|
|
||||||
|
contactPoints:
|
||||||
|
- orgId: 1
|
||||||
|
name: SlackNotifier
|
||||||
|
receivers:
|
||||||
|
- uid: a71b06e3-58b6-41fe-af65-fbbb29653951
|
||||||
|
type: slack
|
||||||
|
settings:
|
||||||
|
# Slack hook URL (see https://api.slack.com/messaging/webhooks)
|
||||||
|
url: <YOUR_SLACK_HOOK_URL>
|
||||||
|
disableResolveMessage: false
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# https://grafana.com/docs/grafana/latest/alerting/alerting-rules/create-notification-policy/
|
||||||
|
|
||||||
|
apiVersion: 1
|
||||||
|
|
||||||
|
policies:
|
||||||
|
- orgId: 1
|
||||||
|
receiver: grafana-default-email
|
||||||
|
group_by:
|
||||||
|
- grafana_folder
|
||||||
|
- alertname
|
||||||
|
routes:
|
||||||
|
- receiver: SlackNotifier
|
||||||
|
object_matchers:
|
||||||
|
# Add matchers below
|
||||||
|
# - ['grafana_folder', '=', 'MyAlerts']
|
||||||
@@ -0,0 +1,933 @@
|
|||||||
|
# https://grafana.com/docs/grafana/latest/alerting/alerting-rules/create-grafana-managed-rule/
|
||||||
|
|
||||||
|
apiVersion: 1
|
||||||
|
|
||||||
|
groups:
|
||||||
|
- orgId: 1
|
||||||
|
name: watcher
|
||||||
|
folder: WatcherAlerts
|
||||||
|
interval: 30s
|
||||||
|
rules:
|
||||||
|
# Azimuth
|
||||||
|
- uid: azimuth_diff_external
|
||||||
|
title: azimuth_watcher_head_tracking
|
||||||
|
condition: condition
|
||||||
|
data:
|
||||||
|
- refId: diff
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
disableTextWrap: false
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number - on(chain) group_right sync_status_block_number{job="azimuth", instance="azimuth", kind="latest_indexed"}
|
||||||
|
fullMetaSearch: false
|
||||||
|
includeNullMetadata: true
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: diff
|
||||||
|
useBackend: false
|
||||||
|
- refId: latest_external
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number{chain="ethereum"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_external
|
||||||
|
- refId: latest_indexed
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: sync_status_block_number{job="azimuth", instance="azimuth", kind="latest_indexed"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_indexed
|
||||||
|
- refId: condition
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params: []
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: avg
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
name: Expression
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: ${diff} >= 16
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: condition
|
||||||
|
type: math
|
||||||
|
noDataState: Alerting
|
||||||
|
execErrState: Alerting
|
||||||
|
for: 15m
|
||||||
|
annotations:
|
||||||
|
summary: Watcher {{ index $labels "instance" }} of group {{ index $labels "job" }} is falling behind external head by {{ index $values "diff" }}
|
||||||
|
isPaused: false
|
||||||
|
- uid: censures_diff_external
|
||||||
|
title: censures_watcher_head_tracking
|
||||||
|
condition: condition
|
||||||
|
data:
|
||||||
|
- refId: diff
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
disableTextWrap: false
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number - on(chain) group_right sync_status_block_number{job="azimuth", instance="censures", kind="latest_indexed"}
|
||||||
|
fullMetaSearch: false
|
||||||
|
includeNullMetadata: true
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: diff
|
||||||
|
useBackend: false
|
||||||
|
- refId: latest_external
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number{chain="ethereum"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_external
|
||||||
|
- refId: latest_indexed
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: sync_status_block_number{job="azimuth", instance="censures", kind="latest_indexed"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_indexed
|
||||||
|
- refId: condition
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params: []
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: avg
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
name: Expression
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: ${diff} >= 16
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: condition
|
||||||
|
type: math
|
||||||
|
noDataState: Alerting
|
||||||
|
execErrState: Alerting
|
||||||
|
for: 15m
|
||||||
|
annotations:
|
||||||
|
summary: Watcher {{ index $labels "instance" }} of group {{ index $labels "job" }} is falling behind external head by {{ index $values "diff" }}
|
||||||
|
isPaused: false
|
||||||
|
- uid: claims_diff_external
|
||||||
|
title: claims_watcher_head_tracking
|
||||||
|
condition: condition
|
||||||
|
data:
|
||||||
|
- refId: diff
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
disableTextWrap: false
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number - on(chain) group_right sync_status_block_number{job="azimuth", instance="claims", kind="latest_indexed"}
|
||||||
|
fullMetaSearch: false
|
||||||
|
includeNullMetadata: true
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: diff
|
||||||
|
useBackend: false
|
||||||
|
- refId: latest_external
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number{chain="ethereum"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_external
|
||||||
|
- refId: latest_indexed
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: sync_status_block_number{job="azimuth", instance="claims", kind="latest_indexed"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_indexed
|
||||||
|
- refId: condition
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params: []
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: avg
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
name: Expression
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: ${diff} >= 16
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: condition
|
||||||
|
type: math
|
||||||
|
noDataState: Alerting
|
||||||
|
execErrState: Alerting
|
||||||
|
for: 15m
|
||||||
|
annotations:
|
||||||
|
summary: Watcher {{ index $labels "instance" }} of group {{ index $labels "job" }} is falling behind external head by {{ index $values "diff" }}
|
||||||
|
isPaused: false
|
||||||
|
- uid: conditional_star_release_diff_external
|
||||||
|
title: conditional_star_release_watcher_head_tracking
|
||||||
|
condition: condition
|
||||||
|
data:
|
||||||
|
- refId: diff
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
disableTextWrap: false
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number - on(chain) group_right sync_status_block_number{job="azimuth", instance="conditional_star_release", kind="latest_indexed"}
|
||||||
|
fullMetaSearch: false
|
||||||
|
includeNullMetadata: true
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: diff
|
||||||
|
useBackend: false
|
||||||
|
- refId: latest_external
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number{chain="ethereum"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_external
|
||||||
|
- refId: latest_indexed
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: sync_status_block_number{job="azimuth", instance="conditional_star_release", kind="latest_indexed"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_indexed
|
||||||
|
- refId: condition
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params: []
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: avg
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
name: Expression
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: ${diff} >= 16
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: condition
|
||||||
|
type: math
|
||||||
|
noDataState: Alerting
|
||||||
|
execErrState: Alerting
|
||||||
|
for: 15m
|
||||||
|
annotations:
|
||||||
|
summary: Watcher {{ index $labels "instance" }} of group {{ index $labels "job" }} is falling behind external head by {{ index $values "diff" }}
|
||||||
|
isPaused: false
|
||||||
|
- uid: delegated_sending_diff_external
|
||||||
|
title: delegated_sending_watcher_head_tracking
|
||||||
|
condition: condition
|
||||||
|
data:
|
||||||
|
- refId: diff
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
disableTextWrap: false
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number - on(chain) group_right sync_status_block_number{job="azimuth", instance="delegated_sending", kind="latest_indexed"}
|
||||||
|
fullMetaSearch: false
|
||||||
|
includeNullMetadata: true
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: diff
|
||||||
|
useBackend: false
|
||||||
|
- refId: latest_external
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number{chain="ethereum"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_external
|
||||||
|
- refId: latest_indexed
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: sync_status_block_number{job="azimuth", instance="delegated_sending", kind="latest_indexed"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_indexed
|
||||||
|
- refId: condition
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params: []
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: avg
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
name: Expression
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: ${diff} >= 16
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: condition
|
||||||
|
type: math
|
||||||
|
noDataState: Alerting
|
||||||
|
execErrState: Alerting
|
||||||
|
for: 15m
|
||||||
|
annotations:
|
||||||
|
summary: Watcher {{ index $labels "instance" }} of group {{ index $labels "job" }} is falling behind external head by {{ index $values "diff" }}
|
||||||
|
isPaused: false
|
||||||
|
- uid: ecliptic_diff_external
|
||||||
|
title: ecliptic_watcher_head_tracking
|
||||||
|
condition: condition
|
||||||
|
data:
|
||||||
|
- refId: diff
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
disableTextWrap: false
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number - on(chain) group_right sync_status_block_number{job="azimuth", instance="ecliptic", kind="latest_indexed"}
|
||||||
|
fullMetaSearch: false
|
||||||
|
includeNullMetadata: true
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: diff
|
||||||
|
useBackend: false
|
||||||
|
- refId: latest_external
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number{chain="ethereum"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_external
|
||||||
|
- refId: latest_indexed
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: sync_status_block_number{job="azimuth", instance="ecliptic", kind="latest_indexed"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_indexed
|
||||||
|
- refId: condition
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params: []
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: avg
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
name: Expression
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: ${diff} >= 16
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: condition
|
||||||
|
type: math
|
||||||
|
noDataState: Alerting
|
||||||
|
execErrState: Alerting
|
||||||
|
for: 15m
|
||||||
|
annotations:
|
||||||
|
summary: Watcher {{ index $labels "instance" }} of group {{ index $labels "job" }} is falling behind external head by {{ index $values "diff" }}
|
||||||
|
isPaused: false
|
||||||
|
- uid: linear_star_release_diff_external
|
||||||
|
title: linear_star_release_watcher_head_tracking
|
||||||
|
condition: condition
|
||||||
|
data:
|
||||||
|
- refId: diff
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
disableTextWrap: false
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number - on(chain) group_right sync_status_block_number{job="azimuth", instance="linear_star_release", kind="latest_indexed"}
|
||||||
|
fullMetaSearch: false
|
||||||
|
includeNullMetadata: true
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: diff
|
||||||
|
useBackend: false
|
||||||
|
- refId: latest_external
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number{chain="ethereum"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_external
|
||||||
|
- refId: latest_indexed
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: sync_status_block_number{job="azimuth", instance="azimuth", kind="latest_indexed"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_indexed
|
||||||
|
- refId: condition
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params: []
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: avg
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
name: Expression
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: ${diff} >= 16
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: condition
|
||||||
|
type: math
|
||||||
|
noDataState: Alerting
|
||||||
|
execErrState: Alerting
|
||||||
|
for: 15m
|
||||||
|
annotations:
|
||||||
|
summary: Watcher {{ index $labels "instance" }} of group {{ index $labels "job" }} is falling behind external head by {{ index $values "diff" }}
|
||||||
|
isPaused: false
|
||||||
|
- uid: polls_diff_external
|
||||||
|
title: polls_watcher_head_tracking
|
||||||
|
condition: condition
|
||||||
|
data:
|
||||||
|
- refId: diff
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
disableTextWrap: false
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number - on(chain) group_right sync_status_block_number{job="azimuth", instance="polls", kind="latest_indexed"}
|
||||||
|
fullMetaSearch: false
|
||||||
|
includeNullMetadata: true
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: diff
|
||||||
|
useBackend: false
|
||||||
|
- refId: latest_external
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number{chain="ethereum"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_external
|
||||||
|
- refId: latest_indexed
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: sync_status_block_number{job="azimuth", instance="polls", kind="latest_indexed"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_indexed
|
||||||
|
- refId: condition
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params: []
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: avg
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
name: Expression
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: ${diff} >= 16
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: condition
|
||||||
|
type: math
|
||||||
|
noDataState: Alerting
|
||||||
|
execErrState: Alerting
|
||||||
|
for: 15m
|
||||||
|
annotations:
|
||||||
|
summary: Watcher {{ index $labels "instance" }} of group {{ index $labels "job" }} is falling behind external head by {{ index $values "diff" }}
|
||||||
|
isPaused: false
|
||||||
|
|
||||||
|
# Sushi
|
||||||
|
- uid: sushiswap_diff_external
|
||||||
|
title: sushiswap_watcher_head_tracking
|
||||||
|
condition: condition
|
||||||
|
data:
|
||||||
|
- refId: diff
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
disableTextWrap: false
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number - on(chain) group_right sync_status_block_number{job="sushi", instance="sushiswap", kind="latest_indexed"}
|
||||||
|
fullMetaSearch: false
|
||||||
|
includeNullMetadata: true
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: diff
|
||||||
|
useBackend: false
|
||||||
|
- refId: latest_external
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number{chain="filecoin"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_external
|
||||||
|
- refId: latest_indexed
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: sync_status_block_number{job="sushi", instance="sushiswap", kind="latest_indexed"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_indexed
|
||||||
|
- refId: condition
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params: []
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: avg
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
name: Expression
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: ${diff} >= 16
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: condition
|
||||||
|
type: math
|
||||||
|
noDataState: Alerting
|
||||||
|
execErrState: Alerting
|
||||||
|
for: 15m
|
||||||
|
annotations:
|
||||||
|
summary: Watcher {{ index $labels "instance" }} of group {{ index $labels "job" }} is falling behind external head by {{ index $values "diff" }}
|
||||||
|
isPaused: false
|
||||||
|
- uid: merkl_sushiswap_diff_external
|
||||||
|
title: merkl_sushiswap_watcher_head_tracking
|
||||||
|
condition: condition
|
||||||
|
data:
|
||||||
|
- refId: diff
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
disableTextWrap: false
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number - on(chain) group_right sync_status_block_number{job="sushi", instance="merkl_sushiswap", kind="latest_indexed"}
|
||||||
|
fullMetaSearch: false
|
||||||
|
includeNullMetadata: true
|
||||||
|
instant: true
|
||||||
|
intervalMs: 1000
|
||||||
|
legendFormat: __auto
|
||||||
|
maxDataPoints: 43200
|
||||||
|
range: false
|
||||||
|
refId: diff
|
||||||
|
useBackend: false
|
||||||
|
- refId: latest_external
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: latest_block_number{chain="filecoin"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_external
|
||||||
|
- refId: latest_indexed
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: PBFA97CFB590B2093
|
||||||
|
model:
|
||||||
|
datasource:
|
||||||
|
type: prometheus
|
||||||
|
uid: PBFA97CFB590B2093
|
||||||
|
editorMode: code
|
||||||
|
expr: sync_status_block_number{job="sushi", instance="merkl_sushiswap", kind="latest_indexed"}
|
||||||
|
hide: false
|
||||||
|
instant: true
|
||||||
|
legendFormat: __auto
|
||||||
|
range: false
|
||||||
|
refId: latest_indexed
|
||||||
|
- refId: condition
|
||||||
|
relativeTimeRange:
|
||||||
|
from: 600
|
||||||
|
to: 0
|
||||||
|
datasourceUid: __expr__
|
||||||
|
model:
|
||||||
|
conditions:
|
||||||
|
- evaluator:
|
||||||
|
params:
|
||||||
|
- 0
|
||||||
|
- 0
|
||||||
|
type: gt
|
||||||
|
operator:
|
||||||
|
type: and
|
||||||
|
query:
|
||||||
|
params: []
|
||||||
|
reducer:
|
||||||
|
params: []
|
||||||
|
type: avg
|
||||||
|
type: query
|
||||||
|
datasource:
|
||||||
|
name: Expression
|
||||||
|
type: __expr__
|
||||||
|
uid: __expr__
|
||||||
|
expression: ${diff} >= 16
|
||||||
|
intervalMs: 1000
|
||||||
|
maxDataPoints: 43200
|
||||||
|
refId: condition
|
||||||
|
type: math
|
||||||
|
noDataState: Alerting
|
||||||
|
execErrState: Alerting
|
||||||
|
for: 15m
|
||||||
|
annotations:
|
||||||
|
summary: Watcher {{ index $labels "instance" }} of group {{ index $labels "job" }} is falling behind external head by {{ index $values "diff" }}
|
||||||
|
isPaused: false
|
||||||
@@ -2,4 +2,6 @@
|
|||||||
# Build a local version of the task executor for act-runner
|
# Build a local version of the task executor for act-runner
|
||||||
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
|
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
|
||||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
docker build -t cerc/act-runner-task-executor:local -f ${CERC_REPO_BASE_DIR}/hosting/act-runner/Dockerfile.task-executor ${build_command_args} ${SCRIPT_DIR}
|
|
||||||
|
cd ${CERC_REPO_BASE_DIR}/hosting/act-runner
|
||||||
|
docker build -t cerc/act-runner-task-executor:local -f Dockerfile.task-executor ${build_command_args} .
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build the birbit image
|
||||||
|
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
|
||||||
|
docker build -t cerc/birbit:local -f ${CERC_REPO_BASE_DIR}/birbit/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/birbit
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
FROM node:14
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN npm install && npm run build
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
CMD ["npm", "run", "serve"]
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build the geojson image
|
||||||
|
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
|
||||||
|
docker build -t cerc/geojson:local -f ${CERC_CONTAINER_BASE_DIR}/cerc-geojson/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/geojson.io
|
||||||
|
#docker build -t cerc/geojson:local -f ${CERC_REPO_BASE_DIR}/geojson.io/Dockerfile ${build_command_args} ${CERC_REPO_BASE_DIR}/geojson.io
|
||||||
@@ -21,6 +21,11 @@ WORK_DIR="${1:-/app}"
|
|||||||
|
|
||||||
cd "${WORK_DIR}" || exit 1
|
cd "${WORK_DIR}" || exit 1
|
||||||
|
|
||||||
|
# If this file doesn't exist at all, we'll get errors below.
|
||||||
|
if [ ! -f "next.config.js" ]; then
|
||||||
|
touch next.config.js
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -f "next.config.dist" ]; then
|
if [ ! -f "next.config.dist" ]; then
|
||||||
cp next.config.js next.config.dist
|
cp next.config.js next.config.dist
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name: act-runner
|
|||||||
description: "Local act-runner"
|
description: "Local act-runner"
|
||||||
repos:
|
repos:
|
||||||
- git.vdb.to/cerc-io/hosting
|
- git.vdb.to/cerc-io/hosting
|
||||||
- gitea.com/gitea/act_runner
|
- gitea.com/telackey/act_runner@telackey/entrypoint
|
||||||
containers:
|
containers:
|
||||||
- cerc/act-runner
|
- cerc/act-runner
|
||||||
- cerc/act-runner-task-executor
|
- cerc/act-runner-task-executor
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# birbit
|
||||||
|
|
||||||
|
takes geo-tagged images, publishes the metadata on chain, then generates a geojson front end of that geo data
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
version: "0.1"
|
||||||
|
name: birbit
|
||||||
|
repos:
|
||||||
|
#- github.com/zramsay/birbit
|
||||||
|
- github.com/mapbox/geojson.io
|
||||||
|
containers:
|
||||||
|
#- cerc/birbit
|
||||||
|
- cerc/geojson
|
||||||
|
pods:
|
||||||
|
# configurable process that reads from chain and generates a view for the front end
|
||||||
|
# for MVP is basically does nothing, b/c FE view is reading all records
|
||||||
|
# imagine a 'watcher' for a specific view
|
||||||
|
#- birbit
|
||||||
|
# front end, gets its file from kubo;
|
||||||
|
# https://github.com/mapbox/geojson.io/blob/main/API.md#datadatatextx-url
|
||||||
|
# deployed via kubernetes
|
||||||
|
- geojson
|
||||||
|
# hosts all the dot geojson files that are required to generated views
|
||||||
|
- kubo
|
||||||
@@ -2,7 +2,7 @@ version: "1.0"
|
|||||||
name: merkl-sushiswap-v3
|
name: merkl-sushiswap-v3
|
||||||
description: "SushiSwap v3 watcher stack"
|
description: "SushiSwap v3 watcher stack"
|
||||||
repos:
|
repos:
|
||||||
- github.com/cerc-io/merkl-sushiswap-v3-watcher-ts@v0.1.4
|
- github.com/cerc-io/merkl-sushiswap-v3-watcher-ts@v0.1.6
|
||||||
containers:
|
containers:
|
||||||
- cerc/watcher-merkl-sushiswap-v3
|
- cerc/watcher-merkl-sushiswap-v3
|
||||||
pods:
|
pods:
|
||||||
|
|||||||
@@ -140,6 +140,10 @@ Set the following env variables in the deployment env config file (`monitoring-d
|
|||||||
# External ETH RPC endpoint (filecoin)
|
# External ETH RPC endpoint (filecoin)
|
||||||
# (Optional, default: https://api.node.glif.io/rpc/v1)
|
# (Optional, default: https://api.node.glif.io/rpc/v1)
|
||||||
CERC_FIL_RPC_ENDPOINT=
|
CERC_FIL_RPC_ENDPOINT=
|
||||||
|
|
||||||
|
# Grafana server host URL (used in various links in alerts, etc.)
|
||||||
|
# (Optional, default: http://localhost:3000)
|
||||||
|
GF_SERVER_ROOT_URL=
|
||||||
```
|
```
|
||||||
|
|
||||||
## Start the stack
|
## Start the stack
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ laconic-so --stack monitoring deploy create --spec-file monitoring-watchers-spec
|
|||||||
|
|
||||||
## Configure
|
## Configure
|
||||||
|
|
||||||
|
### Prometheus scrape config
|
||||||
|
|
||||||
Add the following scrape configs to prometheus config file (`monitoring-watchers-deployment/config/monitoring/prometheus/prometheus.yml`) in the deployment folder:
|
Add the following scrape configs to prometheus config file (`monitoring-watchers-deployment/config/monitoring/prometheus/prometheus.yml`) in the deployment folder:
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
@@ -100,6 +102,27 @@ Add the following scrape configs to prometheus config file (`monitoring-watchers
|
|||||||
|
|
||||||
Add scrape config as done above for any additional watcher to add it to the Watchers dashboard.
|
Add scrape config as done above for any additional watcher to add it to the Watchers dashboard.
|
||||||
|
|
||||||
|
### Grafana alerts config
|
||||||
|
|
||||||
|
Place the pre-configured watcher alerts rules in Grafana provisioning directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp monitoring-watchers-deployment/config/monitoring/watcher-alert-rules.yml monitoring-watchers-deployment/config/monitoring/grafana/provisioning/alerting/
|
||||||
|
```
|
||||||
|
|
||||||
|
Update the alerting contact points config (`monitoring-watchers-deployment/config/monitoring/grafana/provisioning/alerting/contactpoints.yml`) with desired contact points
|
||||||
|
|
||||||
|
Add corresponding routes to the notification policies config (`monitoring-watchers-deployment/monitoring/grafana/provisioning/alerting/policies.yaml`) with appropriate object-matchers:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
...
|
||||||
|
routes:
|
||||||
|
- receiver: SlackNotifier
|
||||||
|
object_matchers:
|
||||||
|
# Add matchers below
|
||||||
|
- ['grafana_folder', '=', 'WatcherAlerts']
|
||||||
|
```
|
||||||
|
|
||||||
### Env
|
### Env
|
||||||
|
|
||||||
Set the following env variables in the deployment env config file (`monitoring-watchers-deployment/config.env`):
|
Set the following env variables in the deployment env config file (`monitoring-watchers-deployment/config.env`):
|
||||||
@@ -107,6 +130,10 @@ Set the following env variables in the deployment env config file (`monitoring-w
|
|||||||
```bash
|
```bash
|
||||||
# Infura key to be used
|
# Infura key to be used
|
||||||
CERC_INFURA_KEY=
|
CERC_INFURA_KEY=
|
||||||
|
|
||||||
|
# Grafana server host URL to be used
|
||||||
|
# (Optional, default: http://localhost:3000)
|
||||||
|
GF_SERVER_ROOT_URL=
|
||||||
```
|
```
|
||||||
|
|
||||||
## Start the stack
|
## Start the stack
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name: package-registry
|
|||||||
description: "Local Package Registry"
|
description: "Local Package Registry"
|
||||||
repos:
|
repos:
|
||||||
- git.vdb.to/cerc-io/hosting
|
- git.vdb.to/cerc-io/hosting
|
||||||
- gitea.com/gitea/act_runner
|
- gitea.com/telackey/act_runner@telackey/entrypoint
|
||||||
containers:
|
containers:
|
||||||
- cerc/act-runner
|
- cerc/act-runner
|
||||||
- cerc/act-runner-task-executor
|
- cerc/act-runner-task-executor
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ version: "1.0"
|
|||||||
name: sushiswap-v3
|
name: sushiswap-v3
|
||||||
description: "SushiSwap v3 watcher stack"
|
description: "SushiSwap v3 watcher stack"
|
||||||
repos:
|
repos:
|
||||||
- github.com/cerc-io/sushiswap-v3-watcher-ts@v0.1.5
|
- github.com/cerc-io/sushiswap-v3-watcher-ts@v0.1.6
|
||||||
containers:
|
containers:
|
||||||
- cerc/watcher-sushiswap-v3
|
- cerc/watcher-sushiswap-v3
|
||||||
pods:
|
pods:
|
||||||
|
|||||||
@@ -444,7 +444,7 @@ def create_operation(deployment_command_context, spec_file, deployment_dir, netw
|
|||||||
deployer_config_generator = getDeployerConfigGenerator(deployment_type)
|
deployer_config_generator = getDeployerConfigGenerator(deployment_type)
|
||||||
# TODO: make deployment_dir_path a Path above
|
# TODO: make deployment_dir_path a Path above
|
||||||
deployer_config_generator.generate(deployment_dir_path)
|
deployer_config_generator.generate(deployment_dir_path)
|
||||||
call_stack_deploy_create(deployment_context, [network_dir, initial_peers])
|
call_stack_deploy_create(deployment_context, [network_dir, initial_peers, deployment_command_context])
|
||||||
|
|
||||||
|
|
||||||
# TODO: this code should be in the stack .py files but
|
# TODO: this code should be in the stack .py files but
|
||||||
|
|||||||
@@ -168,8 +168,8 @@ class ClusterInfo:
|
|||||||
result.append(pv)
|
result.append(pv)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# to suit the deployment, and also annotate the container specs to point at said volumes
|
# TODO: put things like image pull policy into an object-scope struct
|
||||||
def get_deployment(self):
|
def get_deployment(self, image_pull_policy: str = None):
|
||||||
containers = []
|
containers = []
|
||||||
for pod_name in self.parsed_pod_yaml_map:
|
for pod_name in self.parsed_pod_yaml_map:
|
||||||
pod = self.parsed_pod_yaml_map[pod_name]
|
pod = self.parsed_pod_yaml_map[pod_name]
|
||||||
@@ -189,7 +189,7 @@ class ClusterInfo:
|
|||||||
container = client.V1Container(
|
container = client.V1Container(
|
||||||
name=container_name,
|
name=container_name,
|
||||||
image=image_to_use,
|
image=image_to_use,
|
||||||
image_pull_policy="Always",
|
image_pull_policy=image_pull_policy,
|
||||||
env=envs_from_environment_variables_map(self.environment_variables.map),
|
env=envs_from_environment_variables_map(self.environment_variables.map),
|
||||||
ports=[client.V1ContainerPort(container_port=port)],
|
ports=[client.V1ContainerPort(container_port=port)],
|
||||||
volume_mounts=volume_mounts,
|
volume_mounts=volume_mounts,
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ class K8sDeployer(Deployer):
|
|||||||
print("PVCs created:")
|
print("PVCs created:")
|
||||||
print(f"{pvc_resp}")
|
print(f"{pvc_resp}")
|
||||||
# Process compose files into a Deployment
|
# Process compose files into a Deployment
|
||||||
deployment = self.cluster_info.get_deployment()
|
deployment = self.cluster_info.get_deployment(image_pull_policy=None if self.is_kind() else "Always")
|
||||||
# Create the k8s objects
|
# Create the k8s objects
|
||||||
if opts.o.debug:
|
if opts.o.debug:
|
||||||
print(f"Sending this deployment: {deployment}")
|
print(f"Sending this deployment: {deployment}")
|
||||||
@@ -132,18 +132,18 @@ class K8sDeployer(Deployer):
|
|||||||
print("Service created:")
|
print("Service created:")
|
||||||
print(f"{service_resp}")
|
print(f"{service_resp}")
|
||||||
|
|
||||||
# TODO: disable ingress for kind
|
if not self.is_kind():
|
||||||
ingress: client.V1Ingress = self.cluster_info.get_ingress()
|
ingress: client.V1Ingress = self.cluster_info.get_ingress()
|
||||||
|
|
||||||
if opts.o.debug:
|
if opts.o.debug:
|
||||||
print(f"Sending this ingress: {ingress}")
|
print(f"Sending this ingress: {ingress}")
|
||||||
ingress_resp = self.networking_api.create_namespaced_ingress(
|
ingress_resp = self.networking_api.create_namespaced_ingress(
|
||||||
namespace=self.k8s_namespace,
|
namespace=self.k8s_namespace,
|
||||||
body=ingress
|
body=ingress
|
||||||
)
|
)
|
||||||
if opts.o.debug:
|
if opts.o.debug:
|
||||||
print("Ingress created:")
|
print("Ingress created:")
|
||||||
print(f"{ingress_resp}")
|
print(f"{ingress_resp}")
|
||||||
|
|
||||||
def down(self, timeout, volumes):
|
def down(self, timeout, volumes):
|
||||||
self.connect_api()
|
self.connect_api()
|
||||||
@@ -196,16 +196,16 @@ class K8sDeployer(Deployer):
|
|||||||
except client.exceptions.ApiException as e:
|
except client.exceptions.ApiException as e:
|
||||||
_check_delete_exception(e)
|
_check_delete_exception(e)
|
||||||
|
|
||||||
# TODO: disable ingress for kind
|
if not self.is_kind():
|
||||||
ingress: client.V1Ingress = self.cluster_info.get_ingress()
|
ingress: client.V1Ingress = self.cluster_info.get_ingress()
|
||||||
if opts.o.debug:
|
if opts.o.debug:
|
||||||
print(f"Deleting this ingress: {ingress}")
|
print(f"Deleting this ingress: {ingress}")
|
||||||
try:
|
try:
|
||||||
self.networking_api.delete_namespaced_ingress(
|
self.networking_api.delete_namespaced_ingress(
|
||||||
name=ingress.metadata.name, namespace=self.k8s_namespace
|
name=ingress.metadata.name, namespace=self.k8s_namespace
|
||||||
)
|
)
|
||||||
except client.exceptions.ApiException as e:
|
except client.exceptions.ApiException as e:
|
||||||
_check_delete_exception(e)
|
_check_delete_exception(e)
|
||||||
|
|
||||||
if self.is_kind():
|
if self.is_kind():
|
||||||
# Destroy the kind cluster
|
# Destroy the kind cluster
|
||||||
@@ -219,7 +219,7 @@ class K8sDeployer(Deployer):
|
|||||||
|
|
||||||
if all_pods.items:
|
if all_pods.items:
|
||||||
for p in all_pods.items:
|
for p in all_pods.items:
|
||||||
if self.cluster_info.app_name in p.metadata.name:
|
if f"{self.cluster_info.app_name}-deployment" in p.metadata.name:
|
||||||
pods.append(p)
|
pods.append(p)
|
||||||
|
|
||||||
if not pods:
|
if not pods:
|
||||||
@@ -266,7 +266,7 @@ class K8sDeployer(Deployer):
|
|||||||
ret = []
|
ret = []
|
||||||
|
|
||||||
for p in pods.items:
|
for p in pods.items:
|
||||||
if self.cluster_info.app_name in p.metadata.name:
|
if f"{self.cluster_info.app_name}-deployment" in p.metadata.name:
|
||||||
pod_ip = p.status.pod_ip
|
pod_ip = p.status.pod_ip
|
||||||
ports = AttrDict()
|
ports = AttrDict()
|
||||||
for c in p.spec.containers:
|
for c in p.spec.containers:
|
||||||
@@ -299,11 +299,20 @@ class K8sDeployer(Deployer):
|
|||||||
|
|
||||||
def logs(self, services, tail, follow, stream):
|
def logs(self, services, tail, follow, stream):
|
||||||
self.connect_api()
|
self.connect_api()
|
||||||
pods = pods_in_deployment(self.core_api, "test-deployment")
|
pods = pods_in_deployment(self.core_api, self.cluster_info.app_name)
|
||||||
if len(pods) > 1:
|
if len(pods) > 1:
|
||||||
print("Warning: more than one pod in the deployment")
|
print("Warning: more than one pod in the deployment")
|
||||||
k8s_pod_name = pods[0]
|
if len(pods) == 0:
|
||||||
log_data = self.core_api.read_namespaced_pod_log(k8s_pod_name, namespace="default", container="test")
|
log_data = "******* Pods not running ********\n"
|
||||||
|
else:
|
||||||
|
k8s_pod_name = pods[0]
|
||||||
|
# If the pod is not yet started, the logs request below will throw an exception
|
||||||
|
try:
|
||||||
|
log_data = self.core_api.read_namespaced_pod_log(k8s_pod_name, namespace="default", container="test")
|
||||||
|
except client.exceptions.ApiException as e:
|
||||||
|
if opts.o.debug:
|
||||||
|
print(f"Error from read_namespaced_pod_log: {e}")
|
||||||
|
log_data = "******* No logs available ********\n"
|
||||||
return log_stream_from_string(log_data)
|
return log_stream_from_string(log_data)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ from typing import Set, Mapping, List
|
|||||||
|
|
||||||
from stack_orchestrator.opts import opts
|
from stack_orchestrator.opts import opts
|
||||||
from stack_orchestrator.deploy.deploy_util import parsed_pod_files_map_from_file_names
|
from stack_orchestrator.deploy.deploy_util import parsed_pod_files_map_from_file_names
|
||||||
|
from stack_orchestrator.deploy.deployer import DeployerException
|
||||||
|
|
||||||
|
|
||||||
def _run_command(command: str):
|
def _run_command(command: str):
|
||||||
@@ -29,10 +30,13 @@ def _run_command(command: str):
|
|||||||
result = subprocess.run(command, shell=True)
|
result = subprocess.run(command, shell=True)
|
||||||
if opts.o.debug:
|
if opts.o.debug:
|
||||||
print(f"Result: {result}")
|
print(f"Result: {result}")
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def create_cluster(name: str, config_file: str):
|
def create_cluster(name: str, config_file: str):
|
||||||
_run_command(f"kind create cluster --name {name} --config {config_file}")
|
result = _run_command(f"kind create cluster --name {name} --config {config_file}")
|
||||||
|
if result.returncode != 0:
|
||||||
|
raise DeployerException(f"kind create cluster failed: {result}")
|
||||||
|
|
||||||
|
|
||||||
def destroy_cluster(name: str):
|
def destroy_cluster(name: str):
|
||||||
@@ -41,12 +45,14 @@ def destroy_cluster(name: str):
|
|||||||
|
|
||||||
def load_images_into_kind(kind_cluster_name: str, image_set: Set[str]):
|
def load_images_into_kind(kind_cluster_name: str, image_set: Set[str]):
|
||||||
for image in image_set:
|
for image in image_set:
|
||||||
_run_command(f"kind load docker-image {image} --name {kind_cluster_name}")
|
result = _run_command(f"kind load docker-image {image} --name {kind_cluster_name}")
|
||||||
|
if result.returncode != 0:
|
||||||
|
raise DeployerException(f"kind create cluster failed: {result}")
|
||||||
|
|
||||||
|
|
||||||
def pods_in_deployment(core_api: client.CoreV1Api, deployment_name: str):
|
def pods_in_deployment(core_api: client.CoreV1Api, deployment_name: str):
|
||||||
pods = []
|
pods = []
|
||||||
pod_response = core_api.list_namespaced_pod(namespace="default", label_selector="app=test-app")
|
pod_response = core_api.list_namespaced_pod(namespace="default", label_selector=f"app={deployment_name}")
|
||||||
if opts.o.debug:
|
if opts.o.debug:
|
||||||
print(f"pod_response: {pod_response}")
|
print(f"pod_response: {pod_response}")
|
||||||
for pod_info in pod_response.items:
|
for pod_info in pod_response.items:
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ from stack_orchestrator.deploy.webapp import deploy_webapp
|
|||||||
from stack_orchestrator.deploy.webapp.util import (LaconicRegistryClient,
|
from stack_orchestrator.deploy.webapp.util import (LaconicRegistryClient,
|
||||||
build_container_image, push_container_image,
|
build_container_image, push_container_image,
|
||||||
file_hash, deploy_to_k8s, publish_deployment,
|
file_hash, deploy_to_k8s, publish_deployment,
|
||||||
hostname_for_deployment_request, generate_hostname_for_app)
|
hostname_for_deployment_request, generate_hostname_for_app,
|
||||||
|
match_owner)
|
||||||
|
|
||||||
|
|
||||||
def process_app_deployment_request(
|
def process_app_deployment_request(
|
||||||
@@ -57,19 +58,12 @@ def process_app_deployment_request(
|
|||||||
dns_crn = f"{dns_record_namespace}/{fqdn}"
|
dns_crn = f"{dns_record_namespace}/{fqdn}"
|
||||||
dns_record = laconic.get_record(dns_crn)
|
dns_record = laconic.get_record(dns_crn)
|
||||||
if dns_record:
|
if dns_record:
|
||||||
dns_record_owners = dns_record.owners
|
matched_owner = match_owner(app_deployment_request, dns_record)
|
||||||
dns_request_owners = []
|
if not matched_owner and dns_record.request:
|
||||||
if dns_record.request:
|
matched_owner = match_owner(app_deployment_request, laconic.get_record(dns_record.request, require=True))
|
||||||
prev_request = laconic.get_record(dns_record.request, require=True)
|
|
||||||
dns_request_owners = prev_request.owners
|
|
||||||
|
|
||||||
owner_match = None
|
if matched_owner:
|
||||||
|
print("Matched DnsRecord ownership:", matched_owner)
|
||||||
for owner in app_deployment_request.owners:
|
|
||||||
if owner in dns_request_owners or owner in dns_record_owners:
|
|
||||||
owner_match = owner
|
|
||||||
if owner_match:
|
|
||||||
print("Matched DnsRecord ownership to", owner)
|
|
||||||
else:
|
else:
|
||||||
raise Exception("Unable to confirm ownership of DnsRecord %s for request %s" %
|
raise Exception("Unable to confirm ownership of DnsRecord %s for request %s" %
|
||||||
(dns_record.id, app_deployment_request.id))
|
(dns_record.id, app_deployment_request.id))
|
||||||
@@ -153,7 +147,6 @@ def dump_known_requests(filename, requests):
|
|||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@click.option("--kube-config", help="Provide a config file for a k8s deployment")
|
@click.option("--kube-config", help="Provide a config file for a k8s deployment")
|
||||||
@click.option("--kube-config", help="Provide a config file for a k8s deployment")
|
|
||||||
@click.option("--laconic-config", help="Provide a config file for laconicd", required=True)
|
@click.option("--laconic-config", help="Provide a config file for laconicd", required=True)
|
||||||
@click.option("--image-registry", help="Provide a container image registry url for this k8s cluster")
|
@click.option("--image-registry", help="Provide a container image registry url for this k8s cluster")
|
||||||
@click.option("--deployment-parent-dir", help="Create deployment directories beneath this directory", required=True)
|
@click.option("--deployment-parent-dir", help="Create deployment directories beneath this directory", required=True)
|
||||||
@@ -237,9 +230,20 @@ def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_
|
|||||||
if d.attributes.request:
|
if d.attributes.request:
|
||||||
deployments_by_request[d.attributes.request] = d
|
deployments_by_request[d.attributes.request] = d
|
||||||
|
|
||||||
|
# Find removal requests.
|
||||||
|
cancellation_requests = {}
|
||||||
|
removal_requests = laconic.app_deployment_removal_requests()
|
||||||
|
for r in removal_requests:
|
||||||
|
if r.attributes.request:
|
||||||
|
cancellation_requests[r.attributes.request] = r
|
||||||
|
|
||||||
requests_to_execute = []
|
requests_to_execute = []
|
||||||
for r in requests_by_name.values():
|
for r in requests_by_name.values():
|
||||||
if r.id not in deployments_by_request:
|
if r.id in cancellation_requests and match_owner(cancellation_requests[r.id], r):
|
||||||
|
print(f"Found deployment cancellation request for {r.id} at {cancellation_requests[r.id].id}")
|
||||||
|
elif r.id in deployments_by_request:
|
||||||
|
print(f"Found satisfied request for {r.id} at {deployments_by_request[r.id].id}")
|
||||||
|
else:
|
||||||
if r.id not in previous_requests:
|
if r.id not in previous_requests:
|
||||||
print(f"Request {r.id} needs to processed.")
|
print(f"Request {r.id} needs to processed.")
|
||||||
requests_to_execute.append(r)
|
requests_to_execute.append(r)
|
||||||
@@ -247,8 +251,6 @@ def command(ctx, kube_config, laconic_config, image_registry, deployment_parent_
|
|||||||
print(
|
print(
|
||||||
f"Skipping unsatisfied request {r.id} because we have seen it before."
|
f"Skipping unsatisfied request {r.id} because we have seen it before."
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
print(f"Found satisfied request {r.id} at {deployments_by_request[r.id].names[0]}")
|
|
||||||
|
|
||||||
print("Found %d unsatisfied request(s) to process." % len(requests_to_execute))
|
print("Found %d unsatisfied request(s) to process." % len(requests_to_execute))
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
# Copyright ©2023 Vulcanize
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import click
|
||||||
|
|
||||||
|
from stack_orchestrator.deploy.webapp.util import LaconicRegistryClient, match_owner
|
||||||
|
|
||||||
|
|
||||||
|
def process_app_removal_request(ctx,
|
||||||
|
laconic: LaconicRegistryClient,
|
||||||
|
app_removal_request,
|
||||||
|
deployment_parent_dir,
|
||||||
|
delete_volumes,
|
||||||
|
delete_names):
|
||||||
|
deployment_record = laconic.get_record(app_removal_request.attributes.deployment, require=True)
|
||||||
|
dns_record = laconic.get_record(deployment_record.attributes.dns, require=True)
|
||||||
|
deployment_dir = os.path.join(deployment_parent_dir, dns_record.attributes.name)
|
||||||
|
|
||||||
|
if not os.path.exists(deployment_dir):
|
||||||
|
raise Exception("Deployment directory %s does not exist." % deployment_dir)
|
||||||
|
|
||||||
|
# Check if the removal request is from the owner of the DnsRecord or deployment record.
|
||||||
|
matched_owner = match_owner(app_removal_request, deployment_record, dns_record)
|
||||||
|
|
||||||
|
# Or of the original deployment request.
|
||||||
|
if not matched_owner and deployment_record.request:
|
||||||
|
matched_owner = match_owner(app_removal_request, laconic.get_record(deployment_record.request, require=True))
|
||||||
|
|
||||||
|
if matched_owner:
|
||||||
|
print("Matched deployment ownership:", matched_owner)
|
||||||
|
else:
|
||||||
|
raise Exception("Unable to confirm ownership of deployment %s for removal request %s" %
|
||||||
|
(deployment_record.id, app_removal_request.id))
|
||||||
|
|
||||||
|
# TODO(telackey): Call the function directly. The easiest way to build the correct click context is to
|
||||||
|
# exec the process, but it would be better to refactor so we could just call down_operation with the
|
||||||
|
# necessary parameters
|
||||||
|
down_command = [sys.argv[0], "deployment", "--dir", deployment_dir, "down"]
|
||||||
|
if delete_volumes:
|
||||||
|
down_command.append("--delete-volumes")
|
||||||
|
result = subprocess.run(down_command)
|
||||||
|
result.check_returncode()
|
||||||
|
|
||||||
|
removal_record = {
|
||||||
|
"record": {
|
||||||
|
"type": "ApplicationDeploymentRemovalRecord",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"request": app_removal_request.id,
|
||||||
|
"deployment": deployment_record.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
laconic.publish(removal_record)
|
||||||
|
|
||||||
|
if delete_names:
|
||||||
|
if deployment_record.names:
|
||||||
|
for name in deployment_record.names:
|
||||||
|
laconic.delete_name(name)
|
||||||
|
|
||||||
|
if dns_record.names:
|
||||||
|
for name in dns_record.names:
|
||||||
|
laconic.delete_name(name)
|
||||||
|
|
||||||
|
if delete_volumes:
|
||||||
|
shutil.rmtree(deployment_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def load_known_requests(filename):
|
||||||
|
if filename and os.path.exists(filename):
|
||||||
|
return json.load(open(filename, "r"))
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def dump_known_requests(filename, requests):
|
||||||
|
if not filename:
|
||||||
|
return
|
||||||
|
known_requests = load_known_requests(filename)
|
||||||
|
for r in requests:
|
||||||
|
known_requests[r.id] = r.createTime
|
||||||
|
json.dump(known_requests, open(filename, "w"))
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.option("--laconic-config", help="Provide a config file for laconicd", required=True)
|
||||||
|
@click.option("--deployment-parent-dir", help="Create deployment directories beneath this directory", required=True)
|
||||||
|
@click.option("--request-id", help="The ApplicationDeploymentRemovalRequest to process")
|
||||||
|
@click.option("--discover", help="Discover and process all pending ApplicationDeploymentRemovalRequests",
|
||||||
|
is_flag=True, default=False)
|
||||||
|
@click.option("--state-file", help="File to store state about previously seen requests.")
|
||||||
|
@click.option("--only-update-state", help="Only update the state file, don't process any requests anything.", is_flag=True)
|
||||||
|
@click.option("--delete-names/--preserve-names", help="Delete all names associated with removed deployments.", default=True)
|
||||||
|
@click.option("--delete-volumes/--preserve-volumes", default=True, help="delete data volumes")
|
||||||
|
@click.option("--dry-run", help="Don't do anything, just report what would be done.", is_flag=True)
|
||||||
|
@click.pass_context
|
||||||
|
def command(ctx, laconic_config, deployment_parent_dir,
|
||||||
|
request_id, discover, state_file, only_update_state,
|
||||||
|
delete_names, delete_volumes, dry_run):
|
||||||
|
if request_id and discover:
|
||||||
|
print("Cannot specify both --request-id and --discover", file=sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
if not request_id and not discover:
|
||||||
|
print("Must specify either --request-id or --discover", file=sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
if only_update_state and not state_file:
|
||||||
|
print("--only-update-state requires --state-file", file=sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
laconic = LaconicRegistryClient(laconic_config)
|
||||||
|
|
||||||
|
# Find deployment removal requests.
|
||||||
|
# single request
|
||||||
|
if request_id:
|
||||||
|
requests = [laconic.get_record(request_id, require=True)]
|
||||||
|
# TODO: assert record type
|
||||||
|
# all requests
|
||||||
|
elif discover:
|
||||||
|
requests = laconic.app_deployment_removal_requests()
|
||||||
|
|
||||||
|
if only_update_state:
|
||||||
|
if not dry_run:
|
||||||
|
dump_known_requests(state_file, requests)
|
||||||
|
return
|
||||||
|
|
||||||
|
previous_requests = load_known_requests(state_file)
|
||||||
|
requests.sort(key=lambda r: r.createTime)
|
||||||
|
|
||||||
|
# Find deployments.
|
||||||
|
deployments = {}
|
||||||
|
for d in laconic.app_deployments(all=True):
|
||||||
|
deployments[d.id] = d
|
||||||
|
|
||||||
|
# Find removal requests.
|
||||||
|
removals_by_deployment = {}
|
||||||
|
removals_by_request = {}
|
||||||
|
for r in laconic.app_deployment_removals():
|
||||||
|
if r.attributes.deployment:
|
||||||
|
# TODO: should we handle CRNs?
|
||||||
|
removals_by_deployment[r.attributes.deployment] = r
|
||||||
|
|
||||||
|
requests_to_execute = []
|
||||||
|
for r in requests:
|
||||||
|
if not r.attributes.deployment:
|
||||||
|
print(f"Skipping removal request {r.id} since it was a cancellation.")
|
||||||
|
elif r.id in removals_by_request:
|
||||||
|
print(f"Found satisfied request for {r.id} at {removals_by_request[r.id].id}")
|
||||||
|
elif r.attributes.deployment in removals_by_deployment:
|
||||||
|
print(
|
||||||
|
f"Found removal record for indicated deployment {r.attributes.deployment} at "
|
||||||
|
f"{removals_by_deployment[r.attributes.deployment].id}")
|
||||||
|
else:
|
||||||
|
if r.id not in previous_requests:
|
||||||
|
print(f"Request {r.id} needs to processed.")
|
||||||
|
requests_to_execute.append(r)
|
||||||
|
else:
|
||||||
|
print(f"Skipping unsatisfied request {r.id} because we have seen it before.")
|
||||||
|
|
||||||
|
print("Found %d unsatisfied request(s) to process." % len(requests_to_execute))
|
||||||
|
|
||||||
|
if not dry_run:
|
||||||
|
for r in requests_to_execute:
|
||||||
|
try:
|
||||||
|
process_app_removal_request(
|
||||||
|
ctx,
|
||||||
|
laconic,
|
||||||
|
r,
|
||||||
|
os.path.abspath(deployment_parent_dir),
|
||||||
|
delete_volumes,
|
||||||
|
delete_names
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
dump_known_requests(state_file, [r])
|
||||||
@@ -49,6 +49,14 @@ def cmd(*vargs):
|
|||||||
raise err
|
raise err
|
||||||
|
|
||||||
|
|
||||||
|
def match_owner(recordA, *records):
|
||||||
|
for owner in recordA.owners:
|
||||||
|
for otherRecord in records:
|
||||||
|
if owner in otherRecord.owners:
|
||||||
|
return owner
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class LaconicRegistryClient:
|
class LaconicRegistryClient:
|
||||||
def __init__(self, config_file):
|
def __init__(self, config_file):
|
||||||
self.config_file = config_file
|
self.config_file = config_file
|
||||||
@@ -146,11 +154,17 @@ class LaconicRegistryClient:
|
|||||||
raise Exception("Cannot locate record:", name_or_id)
|
raise Exception("Cannot locate record:", name_or_id)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def app_deployment_requests(self):
|
def app_deployment_requests(self, all=True):
|
||||||
return self.list_records({"type": "ApplicationDeploymentRequest"}, True)
|
return self.list_records({"type": "ApplicationDeploymentRequest"}, all)
|
||||||
|
|
||||||
def app_deployments(self):
|
def app_deployments(self, all=True):
|
||||||
return self.list_records({"type": "ApplicationDeploymentRecord"})
|
return self.list_records({"type": "ApplicationDeploymentRecord"}, all)
|
||||||
|
|
||||||
|
def app_deployment_removal_requests(self, all=True):
|
||||||
|
return self.list_records({"type": "ApplicationDeploymentRemovalRequest"}, all)
|
||||||
|
|
||||||
|
def app_deployment_removals(self, all=True):
|
||||||
|
return self.list_records({"type": "ApplicationDeploymentRemovalRecord"}, all)
|
||||||
|
|
||||||
def publish(self, record, names=[]):
|
def publish(self, record, names=[]):
|
||||||
tmpdir = tempfile.mkdtemp()
|
tmpdir = tempfile.mkdtemp()
|
||||||
@@ -165,11 +179,17 @@ class LaconicRegistryClient:
|
|||||||
cmd("laconic", "-c", self.config_file, "cns", "record", "publish", "--filename", record_fname)
|
cmd("laconic", "-c", self.config_file, "cns", "record", "publish", "--filename", record_fname)
|
||||||
)["id"]
|
)["id"]
|
||||||
for name in names:
|
for name in names:
|
||||||
cmd("laconic", "-c", self.config_file, "cns", "name", "set", name, new_record_id)
|
self.set_name(name, new_record_id)
|
||||||
return new_record_id
|
return new_record_id
|
||||||
finally:
|
finally:
|
||||||
cmd("rm", "-rf", tmpdir)
|
cmd("rm", "-rf", tmpdir)
|
||||||
|
|
||||||
|
def set_name(self, name, record_id):
|
||||||
|
cmd("laconic", "-c", self.config_file, "cns", "name", "set", name, record_id)
|
||||||
|
|
||||||
|
def delete_name(self, name):
|
||||||
|
cmd("laconic", "-c", self.config_file, "cns", "name", "delete", name)
|
||||||
|
|
||||||
|
|
||||||
def file_hash(filename):
|
def file_hash(filename):
|
||||||
return hashlib.sha1(open(filename).read().encode()).hexdigest()
|
return hashlib.sha1(open(filename).read().encode()).hexdigest()
|
||||||
@@ -187,9 +207,11 @@ def build_container_image(app_record, tag, extra_build_args=[]):
|
|||||||
print(f"Cloning repository {repo} to {clone_dir} ...")
|
print(f"Cloning repository {repo} to {clone_dir} ...")
|
||||||
if ref:
|
if ref:
|
||||||
# TODO: Determing branch or hash, and use depth 1 if we can.
|
# TODO: Determing branch or hash, and use depth 1 if we can.
|
||||||
result = subprocess.run(["git", "clone", repo, clone_dir])
|
git_env = dict(os.environ.copy())
|
||||||
result.check_returncode()
|
# Never prompt
|
||||||
subprocess.check_call(["git", "checkout", ref], cwd=clone_dir)
|
git_env["GIT_TERMINAL_PROMPT"] = "0"
|
||||||
|
subprocess.check_call(["git", "clone", repo, clone_dir], env=git_env)
|
||||||
|
subprocess.check_call(["git", "checkout", ref], cwd=clone_dir, env=git_env)
|
||||||
else:
|
else:
|
||||||
result = subprocess.run(["git", "clone", "--depth", "1", repo, clone_dir])
|
result = subprocess.run(["git", "clone", "--depth", "1", repo, clone_dir])
|
||||||
result.check_returncode()
|
result.check_returncode()
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ from stack_orchestrator.repos import setup_repositories
|
|||||||
from stack_orchestrator.build import build_containers
|
from stack_orchestrator.build import build_containers
|
||||||
from stack_orchestrator.build import build_npms
|
from stack_orchestrator.build import build_npms
|
||||||
from stack_orchestrator.build import build_webapp
|
from stack_orchestrator.build import build_webapp
|
||||||
from stack_orchestrator.deploy.webapp import run_webapp, deploy_webapp, deploy_webapp_from_registry
|
from stack_orchestrator.deploy.webapp import (run_webapp,
|
||||||
|
deploy_webapp,
|
||||||
|
deploy_webapp_from_registry,
|
||||||
|
undeploy_webapp_from_registry)
|
||||||
from stack_orchestrator.deploy import deploy
|
from stack_orchestrator.deploy import deploy
|
||||||
from stack_orchestrator import version
|
from stack_orchestrator import version
|
||||||
from stack_orchestrator.deploy import deployment
|
from stack_orchestrator.deploy import deployment
|
||||||
@@ -54,6 +57,7 @@ cli.add_command(build_webapp.command, "build-webapp")
|
|||||||
cli.add_command(run_webapp.command, "run-webapp")
|
cli.add_command(run_webapp.command, "run-webapp")
|
||||||
cli.add_command(deploy_webapp.command, "deploy-webapp")
|
cli.add_command(deploy_webapp.command, "deploy-webapp")
|
||||||
cli.add_command(deploy_webapp_from_registry.command, "deploy-webapp-from-registry")
|
cli.add_command(deploy_webapp_from_registry.command, "deploy-webapp-from-registry")
|
||||||
|
cli.add_command(undeploy_webapp_from_registry.command, "undeploy-webapp-from-registry")
|
||||||
cli.add_command(deploy.command, "deploy") # deploy is an alias for deploy-system
|
cli.add_command(deploy.command, "deploy") # deploy is an alias for deploy-system
|
||||||
cli.add_command(deploy.command, "deploy-system")
|
cli.add_command(deploy.command, "deploy-system")
|
||||||
cli.add_command(deployment.command, "deployment")
|
cli.add_command(deployment.command, "deployment")
|
||||||
|
|||||||
@@ -1,14 +1,59 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
||||||
set -x
|
set -x
|
||||||
|
# Dump environment variables for debugging
|
||||||
|
echo "Environment variables:"
|
||||||
|
env
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Helper functions: TODO move into a separate file
|
||||||
|
wait_for_pods_started () {
|
||||||
|
for i in {1..5}
|
||||||
|
do
|
||||||
|
local ps_output=$( $TEST_TARGET_SO deployment --dir $test_deployment_dir ps )
|
||||||
|
|
||||||
|
if [[ "$ps_output" == *"Running containers:"* ]]; then
|
||||||
|
# if ready, return
|
||||||
|
return
|
||||||
|
else
|
||||||
|
# if not ready, wait
|
||||||
|
sleep 5
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# Timed out, error exit
|
||||||
|
echo "waiting for pods to start: FAILED"
|
||||||
|
delete_cluster_exit
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_log_output () {
|
||||||
|
for i in {1..5}
|
||||||
|
do
|
||||||
|
|
||||||
|
local log_output=$( $TEST_TARGET_SO deployment --dir $test_deployment_dir logs )
|
||||||
|
|
||||||
|
if [[ ! -z "$log_output" ]]; then
|
||||||
|
# if ready, return
|
||||||
|
return
|
||||||
|
else
|
||||||
|
# if not ready, wait
|
||||||
|
sleep 5
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# Timed out, error exit
|
||||||
|
echo "waiting for pods log content: FAILED"
|
||||||
|
delete_cluster_exit
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
delete_cluster_exit () {
|
||||||
|
$TEST_TARGET_SO deployment --dir $test_deployment_dir stop --delete-volumes
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
# Note: eventually this test should be folded into ../deploy/
|
# Note: eventually this test should be folded into ../deploy/
|
||||||
# but keeping it separate for now for convenience
|
# but keeping it separate for now for convenience
|
||||||
TEST_TARGET_SO=$( ls -t1 ./package/laconic-so* | head -1 )
|
TEST_TARGET_SO=$( ls -t1 ./package/laconic-so* | head -1 )
|
||||||
# Dump environment variables for debugging
|
|
||||||
echo "Environment variables:"
|
|
||||||
env
|
|
||||||
# Set a non-default repo dir
|
# Set a non-default repo dir
|
||||||
export CERC_REPO_BASE_DIR=~/stack-orchestrator-test/repo-base-dir
|
export CERC_REPO_BASE_DIR=~/stack-orchestrator-test/repo-base-dir
|
||||||
echo "Testing this package: $TEST_TARGET_SO"
|
echo "Testing this package: $TEST_TARGET_SO"
|
||||||
@@ -18,7 +63,9 @@ echo "Version reported is: ${reported_version_string}"
|
|||||||
echo "Cloning repositories into: $CERC_REPO_BASE_DIR"
|
echo "Cloning repositories into: $CERC_REPO_BASE_DIR"
|
||||||
rm -rf $CERC_REPO_BASE_DIR
|
rm -rf $CERC_REPO_BASE_DIR
|
||||||
mkdir -p $CERC_REPO_BASE_DIR
|
mkdir -p $CERC_REPO_BASE_DIR
|
||||||
# Test basic stack-orchestrator deploy
|
$TEST_TARGET_SO --stack test setup-repositories
|
||||||
|
$TEST_TARGET_SO --stack test build-containers
|
||||||
|
# Test basic stack-orchestrator deploy to k8s
|
||||||
test_deployment_dir=$CERC_REPO_BASE_DIR/test-deployment-dir
|
test_deployment_dir=$CERC_REPO_BASE_DIR/test-deployment-dir
|
||||||
test_deployment_spec=$CERC_REPO_BASE_DIR/test-deployment-spec.yml
|
test_deployment_spec=$CERC_REPO_BASE_DIR/test-deployment-spec.yml
|
||||||
$TEST_TARGET_SO --stack test deploy --deploy-to k8s-kind init --output $test_deployment_spec --config CERC_TEST_PARAM_1=PASSED
|
$TEST_TARGET_SO --stack test deploy --deploy-to k8s-kind init --output $test_deployment_spec --config CERC_TEST_PARAM_1=PASSED
|
||||||
@@ -53,23 +100,36 @@ fi
|
|||||||
echo "deploy create output file test: passed"
|
echo "deploy create output file test: passed"
|
||||||
# Try to start the deployment
|
# Try to start the deployment
|
||||||
$TEST_TARGET_SO deployment --dir $test_deployment_dir start
|
$TEST_TARGET_SO deployment --dir $test_deployment_dir start
|
||||||
# TODO: add a check to see if the container is up
|
wait_for_pods_started
|
||||||
# Sleep because k8s not up yet
|
|
||||||
sleep 30
|
|
||||||
# Check logs command works
|
# Check logs command works
|
||||||
|
wait_for_log_output
|
||||||
log_output_3=$( $TEST_TARGET_SO deployment --dir $test_deployment_dir logs )
|
log_output_3=$( $TEST_TARGET_SO deployment --dir $test_deployment_dir logs )
|
||||||
if [[ "$log_output_3" == *"Filesystem is fresh"* ]]; then
|
if [[ "$log_output_3" == *"Filesystem is fresh"* ]]; then
|
||||||
echo "deployment logs test: passed"
|
echo "deployment logs test: passed"
|
||||||
else
|
else
|
||||||
echo "deployment logs test: FAILED"
|
echo "deployment logs test: FAILED"
|
||||||
exit 1
|
delete_cluster_exit
|
||||||
fi
|
fi
|
||||||
# Check the config variable CERC_TEST_PARAM_1 was passed correctly
|
# Check the config variable CERC_TEST_PARAM_1 was passed correctly
|
||||||
if [[ "$log_output_3" == *"Test-param-1: PASSED"* ]]; then
|
if [[ "$log_output_3" == *"Test-param-1: PASSED"* ]]; then
|
||||||
echo "deployment config test: passed"
|
echo "deployment config test: passed"
|
||||||
else
|
else
|
||||||
echo "deployment config test: FAILED"
|
echo "deployment config test: FAILED"
|
||||||
exit 1
|
delete_cluster_exit
|
||||||
|
fi
|
||||||
|
# Stop then start again and check the volume was preserved
|
||||||
|
$TEST_TARGET_SO deployment --dir $test_deployment_dir stop
|
||||||
|
# Sleep a bit just in case
|
||||||
|
sleep 2
|
||||||
|
$TEST_TARGET_SO deployment --dir $test_deployment_dir start
|
||||||
|
wait_for_pods_started
|
||||||
|
wait_for_log_output
|
||||||
|
log_output_4=$( $TEST_TARGET_SO deployment --dir $test_deployment_dir logs )
|
||||||
|
if [[ "$log_output_4" == *"Filesystem is old"* ]]; then
|
||||||
|
echo "Retain volumes test: passed"
|
||||||
|
else
|
||||||
|
echo "Retain volumes test: FAILED"
|
||||||
|
delete_cluster_exit
|
||||||
fi
|
fi
|
||||||
# Stop and clean up
|
# Stop and clean up
|
||||||
$TEST_TARGET_SO deployment --dir $test_deployment_dir stop --delete-volumes
|
$TEST_TARGET_SO deployment --dir $test_deployment_dir stop --delete-volumes
|
||||||
|
|||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# TODO: handle ARM
|
||||||
|
curl --silent -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
|
||||||
|
chmod +x ./kind
|
||||||
|
mv ./kind /usr/local/bin
|
||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# TODO: handle ARM
|
||||||
|
curl --silent -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||||
|
chmod +x ./kubectl
|
||||||
|
mv ./kubectl /usr/local/bin
|
||||||
Reference in New Issue
Block a user