Compare commits

...
Author SHA1 Message Date
dboreham faa48e8ca8 Merge branch 'main' into dboreham/laconicd-k8s 2024-02-06 12:32:41 -07:00
dboreham bfbcfb7904 Volume processing fixes (#729) 2024-02-06 12:32:10 -07:00
dboreham 037ffe9a47 Merge branch 'main' into dboreham/laconicd-k8s 2024-02-06 12:00:44 -07:00
dboreham 3d5ececba5 Remove duplicate plugin paths and resulting extraneous error message (#728) 2024-02-06 11:59:37 -07:00
dboreham 01ab438c7e Merge main 2024-02-06 07:11:08 -07:00
dboreham 6848fc33cf Implement dry run support for k8s deploy (#727) 2024-02-06 07:07:56 -07:00
telackeyanddboreham 36bb068983 Add ConfigMap test. (#726)
* Add ConfigMap test.

* eof

* Minor tweak

* Trigger test

---------

Co-authored-by: David Boreham <david@bozemanpass.com>
2024-02-05 14:15:11 -06:00
dboreham c85f31760d Merge main 2024-02-05 06:47:13 -07:00
dboreham 25a2b70f2c Fix command in mainnet-eth docs 2024-02-03 18:25:02 -07:00
telackey 2fcd416e29 Basic webapp deployer stack. (#722) 2024-02-02 19:05:15 -07:00
telackey 6629017d6a Support other webapp types (react, static). (#721)
* Support other webapp types (react, static).
2024-02-02 18:04:06 -06:00
dboreham 1c30441000 Add schedule for k8s deploy test 2024-02-01 07:40:20 -07:00
telackey b398050787 Don't include volumes in spec if we don't have any. (#720) 2024-01-31 15:11:32 -06:00
telackey 12ec1bec43 Add ConfigMap support for k8s. (#714)
* Minor fixes for deploying with k8s and podman.

* ConfigMap support
2024-01-30 23:09:48 -06:00
telackey 62af03077f Add deployed/error status output to the state file. (#719)
* More status info
* Up default resource limits.
* Need ps
2024-01-30 22:13:45 -06:00
telackey 428b05158e Fix DnsRecord ownership check. (#718)
* Fix DnsRecord ownership check.

* Var names
2024-01-30 13:31:59 -06:00
dboreham a750b645b9 Merge Ci test branch fixes (#717) 2024-01-30 11:18:08 -07:00
dboreham f67668c1be Fix lint error 2024-01-30 06:51:03 -07:00
dboreham 2c17b901a8 Fix volume parsing 2024-01-28 22:14:18 -07:00
dboreham 886f1f322c Fix template filename 2024-01-28 22:01:51 -07:00
dboreham d279aedf84 Changes for fixturenet-laconic-loaded in k8s 2024-01-28 21:57:01 -07:00
dboreham b7f215d9bf k8s test fixes (#713)
* Add cgroup setup, increase test timeouts

* Trigger from test script or CI job changes too
2024-01-28 16:21:39 -07:00
dboreham eca52b10b7 Fix copy-paste error 2024-01-25 11:46:50 -07:00
dboreham b9128841e4 Switch test back to stock runner 2024-01-25 11:42:07 -07:00
dboreham 0a302ea555 Add a schedule for fixturenet-eth-plugeth-test 2024-01-25 07:33:44 -07:00
dboreham aa0f60baa1 Trigger fixturenet-eth-plugeth-test run 2024-01-25 06:46:18 -07:00
dboreham cef73d8de2 Update fixturenet-laconicd-test schedule 2024-01-23 10:32:44 -07:00
dboreham 7d0f2adb46 Enable scheduled test run (#711) 2024-01-23 09:42:24 -07:00
dboreham 5fdee25dc1 update laconicd test (#710)
* Remove legacy docker config

* Trigger test run
2024-01-23 09:25:02 -07:00
telackey 554f05de87 Fix pip3 error (#709) 2024-01-22 21:06:15 -06:00
dboreham b4fbee9b13 Update fixturenet-laconicd-test 2024-01-22 07:43:38 -07:00
dboreham f826f50c4d Merge branch 'main' of github.com:cerc-io/stack-orchestrator 2024-01-17 08:27:38 -07:00
dboreham b83465767d Set k8s deploy test to manual trigger 2024-01-17 08:27:09 -07:00
dboreham 50509203d1 Set k8s deploy test to manual trigger 2024-01-17 08:26:51 -07:00
prathamesh0 282e175566 Remove unnecessary hyperlinks and pin image versions (#706)
* Remove invalid dashboard and panel ids from alert rules

* Pin grafana and prometheus versions

* Configure custom grafana server URL
2024-01-17 14:02:10 +05:30
dboreham 635aa7037b Build test container 2024-01-16 21:15:21 -07:00
dboreham 9877cfaf85 Update for new runner 2024-01-16 20:08:32 -07:00
dboreham c642e5d490 Try different runner 2024-01-16 17:09:58 -07:00
dboreham 02c49d66f5 Add debug output to check container 2024-01-16 17:07:03 -07:00
dboreham 90cebdb7a6 Add CI script for k8s deployment test (#705) 2024-01-16 16:16:07 -07:00
dboreham 1f9653e6f7 Fix kind mode and add k8s deployment test (#704)
* Fix kind mode and add k8s deployment test

* Fix lint errors
2024-01-16 15:55:58 -07:00
telackey 0587813dd0 Create next.config.js if it is missing. (#701)
* Create next.config.js if it is missing.

* Add comment.
2024-01-15 12:12:59 -06:00
telackey 4b3ea7c30f Update independent act-runner stack to use custom act as well. (#702)
* Update independent act-runner stack to use custom act as well.

* Remove branches which are not needed or already merged.
2024-01-15 12:10:48 -06:00
nabarun db8aec52aa Pin commit hash of asset list repo in osmosis frontend app (#703) 2024-01-15 16:56:06 +05:30
telackey b83030f63b Use custom act with gitea. (#700)
* Use custom act with gitea.

* Make sure wget is available

* Fix repo url
2024-01-09 22:53:43 -06:00
prathamesh0 a3eb3c0bb0 Setup basic alerting for watchers in monitoring stack (#698)
* Provision Grafana alert contactpoints and policies for Slack

* Add watcher alert rules

* Update watcher monitoring instructions

* Add listening port flag to node exporter command

* Add reference links
2024-01-08 17:25:30 +05:30
nabarun eae2af7ccc Upgrade watcher versions (#699) 2024-01-08 11:51:54 +05:30
telackey 837e443800 Support application removal requests. (#697)
* Support application removal request.

* Git should never prompt when deploying a webapp
2023-12-21 18:05:40 -06:00
prathamesh0 a57b0cdd26 Add a stack for prom node exporter and its dashboard in monitoring stack (#696)
* Add a stack for Prometheus node exporter

* Add node exporter dashboard to monitoring stack
2023-12-21 15:15:03 +05:30
prathamesh0 38622fb33c [WIP] Use templating for watcher dashboard and add Postgres exporter (#695)
* Add Postgres exporter and it's dashboard

* Use templating for watcher dashboard

* Add subgraph related panels to watcher dashboard

* Remove individual watcher dashboards and update instructions
2023-12-21 13:41:36 +05:30
prathamesh0 4a1a46facc Update monitoring stack with additional dashboards and watcher metrics (#693)
* Include retry jobs and update default refresh intervals

* Add prometheus blackbox exporter and it's dashboard

* Add NodeJS application dashboard

* Allow UI updates

* Update watcher dashboards for upstream and external chain heads

* Update watcher dashboards with watcher config metrics

* Upgrade sushiswap and azimuth watchers

* Removed fixed title size values

* Update instructions

* Update instructions for env config

* Update instructions with setup
2023-12-21 09:26:37 +05:30
Zach 42b92f7e23 use square logo for an urbit tile (#689)
* use square logo for an urbit tile

* bump version, improve info text
2023-12-19 09:50:14 -05:00
nabarun def192edab Update new environment values for Osmosis frontend app (#694)
* Update new env values for Osmosis frontend app

* Use .env.production instead of local
2023-12-18 17:49:45 +05:30
dboreham d8357df345 Add image pull secret to pods (#692) 2023-12-15 14:27:45 -07:00
telackey 997496b8a5 Update script for new nextjs build output. (#691) 2023-12-14 19:47:30 -06:00
telackey 61f2884505 Reduce base image size (first round of improvements) (#690) 2023-12-14 17:46:03 -06:00
telackey 27a14737f8 Make the container tag based on the deployment path. (#688) 2023-12-14 09:49:21 -06:00
prathamesh0andnabarun b9b758bfdd Add a stack for running Osmosis frontend app on Urbit (#683)
* Deploy osmosis on Urbit fake ship

* Remove Urbit configuration from existing osmosis stack

* Add a separate stack for Osmosis front end on Urbit

* Run script for renaming build files with bash

* Add environment variables required in urbit osmosis build

* Fix BASEPATH in compose file

* Remove ipfs-glob-host from network config in osmosis readme

* Use laconic branch for osmosis frontend

---------

Co-authored-by: Nabarun <nabarun@deepstacksoft.com>
2023-12-14 17:28:10 +05:30
prathamesh0 9ba410b095 Add a stack for monitoring watchers with prometheus and grafana (#687)
* Setup Prometheus and Grafana for monitoring stack

* Add dashboard for azimuth watchers

* Add a dashboard for sushiswap watcher

* Persist prometheus server data

* Additional metrics in watcher dashboards

* Update dashboards and add for merkl sushiswap watcher

* Add dashboards for remaining azimuth watchers

* Separate out preconfigured watcher dashboards and add instructions

* Keep the empty dashboards dir
2023-12-14 16:59:00 +05:30
telackey 1f4eb57069 Add --dry-run option (#686) 2023-12-13 22:56:40 -06:00
telackey 88f66a3626 Add deployment update and deploy-webapp-from-registry commands. (#676) 2023-12-13 21:02:34 -06:00
prathamesh0 1ef0b316c6 Expose metrics endpoints for sushiswap and merkl sushiswap watchers (#685) 2023-12-13 14:58:26 +05:30
prathamesh0 232d5618cb Update instructions in osmosis stack (#684) 2023-12-12 13:54:00 +05:30
fa6b570f4a Add stack for running osmosis frontend app (#673)
* osmosis FE stack

* chmod

* dont use 3000

* fix for neww stack format

* updates

* update osmosis readme

* Update stack.yml

* Update osmosis frontend stack to serve app

* Host osmosis app static build using python server

* Fix mapped ports in deployment for containers

* Update instructions

* Use nginx server to host files and handle page reloads

* Fix typo

---------

Co-authored-by: zramsay <zach@bluecollarcoding.ca>
Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
2023-12-11 14:10:54 +05:30
prathamesh0 f9eb5a4ba8 Refactor to make Urbit setup generic (#682)
* Refactor to make Urbit app deployment script generic

* Rename urbit pod and update instructions

* Add a flag to allow skipping app installation on Urbit

* Make remote Urbit app deployment scripts generic

* Move remote deployment scripts to urbit fixturenet

* Update and use existing kubo pod for Urbit glob hosting
2023-12-08 09:35:00 +05:30
132 changed files with 35391 additions and 689 deletions
@@ -6,6 +6,8 @@ on:
paths:
- '!**'
- '.gitea/workflows/triggers/fixturenet-eth-plugeth-test'
schedule: # Note: coordinate with other tests to not overload runners at the same time of day
- cron: '2 14 * * *'
# Needed until we can incorporate docker startup into the executor container
env:
@@ -6,11 +6,8 @@ on:
paths:
- '!**'
- '.gitea/workflows/triggers/fixturenet-laconicd-test'
# Needed until we can incorporate docker startup into the executor container
env:
DOCKER_HOST: unix:///var/run/dind.sock
schedule:
- cron: '1 13 * * *'
jobs:
test:
@@ -47,9 +44,5 @@ jobs:
run: ./scripts/create_build_tag_file.sh
- name: "Build local shiv package"
run: ./scripts/build_shiv_package.sh
- name: Start dockerd # Also needed until we can incorporate into the executor
run: |
dockerd -H $DOCKER_HOST --userland-proxy=false &
sleep 5
- name: "Run fixturenet-laconicd tests"
run: ./tests/fixturenet-laconicd/run-test.sh
+21 -24
View File
@@ -1,23 +1,20 @@
name: K8s Deploy Test
on:
pull_request:
branches: '*'
push:
branches:
- main
- ci-test
paths-ignore:
- '.gitea/workflows/triggers/*'
# Needed until we can incorporate docker startup into the executor container
env:
DOCKER_HOST: unix:///var/run/dind.sock
branches: '*'
paths:
- '!**'
- '.gitea/workflows/triggers/test-k8s-deploy'
- '.gitea/workflows/test-k8s-deploy.yml'
- 'tests/k8s-deploy/run-deploy-test.sh'
schedule: # Note: coordinate with other tests to not overload runners at the same time of day
- cron: '3 15 * * *'
jobs:
test:
name: "Run deploy test suite"
runs-on: ubuntu-latest
name: "Run deploy test suite on kind/k8s"
runs-on: ubuntu-22.04
steps:
- name: "Clone project repository"
uses: actions/checkout@v3
@@ -41,15 +38,15 @@ jobs:
run: ./scripts/create_build_tag_file.sh
- name: "Build local shiv package"
run: ./scripts/build_shiv_package.sh
- name: Start dockerd # Also needed until we can incorporate into the executor
- name: "Check cgroups version"
run: mount | grep cgroup
- name: "Install kind"
run: ./tests/scripts/install-kind.sh
- name: "Install Kubectl"
run: ./tests/scripts/install-kubectl.sh
- name: "Run k8s deployment test"
run: |
dockerd -H $DOCKER_HOST --userland-proxy=false &
sleep 5
- name: "Install Go"
uses: actions/setup-go@v4
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
source /opt/bash-utils/cgroup-helper.sh
join_cgroup
./tests/k8s-deploy/run-deploy-test.sh
+2
View File
@@ -41,6 +41,8 @@ jobs:
run: ./scripts/create_build_tag_file.sh
- name: "Build local shiv package"
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
run: |
dockerd -H $DOCKER_HOST --userland-proxy=false &
@@ -1,2 +1,3 @@
Change this file to trigger running the fixturenet-eth-plugeth-test CI job
trigger
trigger
@@ -1,2 +1,3 @@
Change this file to trigger running the fixturenet-laconicd-test CI job
Trigger
Trigger
@@ -0,0 +1,2 @@
Change this file to trigger running the test-k8s-deploy CI job
Trigger test on PR branch
@@ -33,6 +33,7 @@ from stack_orchestrator.base import get_npm_registry_url
# TODO: find a place for this
# epilog="Config provided either in .env or settings.ini or env vars: CERC_REPO_BASE_DIR (defaults to ~/cerc)"
def make_container_build_env(dev_root_path: str,
container_build_dir: str,
debug: bool,
@@ -104,6 +105,9 @@ def process_container(stack: str,
build_command = os.path.join(container_build_dir,
"default-build.sh") + f" {default_container_tag} {repo_dir_or_build_dir}"
if not dry_run:
# No PATH at all causes failures with podman.
if "PATH" not in container_build_env:
container_build_env["PATH"] = os.environ["PATH"]
if verbose:
print(f"Executing: {build_command} with environment: {container_build_env}")
build_result = subprocess.run(build_command, shell=True, env=container_build_env)
@@ -119,6 +123,7 @@ def process_container(stack: str,
else:
print("Skipped")
@click.command()
@click.option('--include', help="only build these containers")
@click.option('--exclude', help="don\'t build these containers")
+7 -4
View File
@@ -25,10 +25,11 @@ from decouple import config
import click
from pathlib import Path
from stack_orchestrator.build import build_containers
from stack_orchestrator.deploy.webapp.util import determine_base_container
@click.command()
@click.option('--base-container', default="cerc/nextjs-base")
@click.option('--base-container')
@click.option('--source-repo', help="directory containing the webapp to build", required=True)
@click.option("--force-rebuild", is_flag=True, default=False, help="Override dependency checking -- always rebuild")
@click.option("--extra-build-args", help="Supply extra arguments to build")
@@ -57,6 +58,9 @@ def command(ctx, base_container, source_repo, force_rebuild, extra_build_args, t
if not quiet:
print(f'Dev Root is: {dev_root_path}')
if not base_container:
base_container = determine_base_container(source_repo)
# First build the base container.
container_build_env = build_containers.make_container_build_env(dev_root_path, container_build_dir, debug,
force_rebuild, extra_build_args)
@@ -64,13 +68,12 @@ def command(ctx, base_container, source_repo, force_rebuild, extra_build_args, t
build_containers.process_container(None, base_container, container_build_dir, container_build_env, dev_root_path, quiet,
verbose, dry_run, continue_on_error)
# Now build the target webapp. We use the same build script, but with a different Dockerfile and work dir.
container_build_env["CERC_WEBAPP_BUILD_RUNNING"] = "true"
container_build_env["CERC_CONTAINER_BUILD_WORK_DIR"] = os.path.abspath(source_repo)
container_build_env["CERC_CONTAINER_BUILD_DOCKERFILE"] = os.path.join(container_build_dir,
base_container.replace("/", "-"),
"Dockerfile.webapp")
base_container.replace("/", "-"),
"Dockerfile.webapp")
if not tag:
webapp_name = os.path.abspath(source_repo).split(os.path.sep)[-1]
container_build_env["CERC_CONTAINER_BUILD_TAG"] = f"cerc/{webapp_name}:local"
@@ -7,9 +7,7 @@ services:
# The cosmos-sdk node's database directory:
- laconicd-data:/root/.laconicd
# TODO: look at folding these scripts into the container
- ../config/fixturenet-laconicd/create-fixturenet.sh:/docker-entrypoint-scripts.d/create-fixturenet.sh
- ../config/fixturenet-laconicd/export-mykey.sh:/docker-entrypoint-scripts.d/export-mykey.sh
- ../config/fixturenet-laconicd/export-myaddress.sh:/docker-entrypoint-scripts.d/export-myaddress.sh
- laconicd-scripts:/docker-entrypoint-scripts.d:ro
# TODO: determine which of the ports below is really needed
ports:
- "6060"
@@ -24,7 +22,9 @@ services:
cli:
image: cerc/laconic-registry-cli:local
volumes:
- ../config/fixturenet-laconicd/registry-cli-config-template.yml:/registry-cli-config-template.yml
- cli-config:/registry-cli-config
volumes:
laconicd-data:
laconicd-scripts:
cli-config:
@@ -0,0 +1,36 @@
version: '3.7'
services:
# Runs an Urbit fake ship and attempts an app installation using given data
# Uploads the app glob to given IPFS endpoint
# From urbit_app_builds volume:
# - takes app build from ${CERC_URBIT_APP}/build (waits for it to appear)
# - takes additional mark files from ${CERC_URBIT_APP}/mar
# - takes the docket file from ${CERC_URBIT_APP}/desk.docket-0
urbit-fake-ship:
restart: unless-stopped
image: tloncorp/vere
environment:
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
CERC_URBIT_APP: ${CERC_URBIT_APP}
CERC_ENABLE_APP_INSTALL: ${CERC_ENABLE_APP_INSTALL:-true}
CERC_IPFS_GLOB_HOST_ENDPOINT: ${CERC_IPFS_GLOB_HOST_ENDPOINT:-http://ipfs:5001}
CERC_IPFS_SERVER_ENDPOINT: ${CERC_IPFS_SERVER_ENDPOINT:-http://ipfs:8080}
entrypoint: ["bash", "-c", "./run-urbit-ship.sh && ./deploy-app.sh && tail -f /dev/null"]
volumes:
- urbit_data:/urbit
- urbit_app_builds:/app-builds
- ../config/urbit/run-urbit-ship.sh:/urbit/run-urbit-ship.sh
- ../config/urbit/deploy-app.sh:/urbit/deploy-app.sh
ports:
- "80"
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "80"]
interval: 20s
timeout: 5s
retries: 15
start_period: 10s
volumes:
urbit_data:
urbit_app_builds:
@@ -0,0 +1,23 @@
version: "3.7"
services:
grafana:
image: grafana/grafana:10.2.2
restart: always
environment:
GF_SERVER_ROOT_URL: ${GF_SERVER_ROOT_URL}
volumes:
- ../config/monitoring/grafana/provisioning:/etc/grafana/provisioning
- ../config/monitoring/grafana/dashboards:/etc/grafana/dashboards
- grafana_storage:/var/lib/grafana
ports:
- "3000"
healthcheck:
test: ["CMD", "nc", "-vz", "localhost", "3000"]
interval: 30s
timeout: 5s
retries: 10
start_period: 3s
volumes:
grafana_storage:
@@ -1,13 +1,24 @@
version: "3.2"
# See: https://docs.ipfs.tech/install/run-ipfs-inside-docker/#set-up
services:
ipfs:
image: ipfs/kubo:master-2023-02-20-714a968
image: ipfs/kubo:v0.24.0
restart: always
volumes:
- ./ipfs/import:/import
- ./ipfs/data:/data/ipfs
- ipfs-import:/import
- ipfs-data:/data/ipfs
ports:
- "0.0.0.0:8080:8080"
- "0.0.0.0:4001:4001"
- "4001"
- "8080"
- "0.0.0.0:5001:5001"
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "5001"]
interval: 20s
timeout: 5s
retries: 15
start_period: 10s
volumes:
ipfs-import:
ipfs-data:
@@ -9,9 +9,7 @@ services:
- laconicd-config:/root/.laconicd/config
- laconicd-keyring:/root/.laconicd/keyring-test
# TODO: look at folding these scripts into the container
- ../config/mainnet-laconicd/scripts/run-laconicd.sh:/opt/run-laconicd.sh
- ../config/mainnet-laconicd/scripts/export-mykey.sh:/docker-entrypoint-scripts.d/export-mykey.sh
- ../config/mainnet-laconicd/scripts/export-myaddress.sh:/docker-entrypoint-scripts.d/export-myaddress.sh
- laconicd-scripts:/docker-entrypoint-scripts.d:ro
# TODO: determine which of the ports below is really needed
ports:
- "6060"
@@ -26,9 +24,11 @@ services:
cli:
image: cerc/laconic-registry-cli:local
volumes:
- ../config/mainnet-laconicd/registry-cli-config-template.yml:/registry-cli-config-template.yml
- cli-config:/registry-cli-config
volumes:
laconicd-data:
laconicd-config:
laconicd-scripts:
laconicd-keyring:
cli-config:
@@ -0,0 +1,15 @@
version: '3.8'
services:
node-exporter:
image: prom/node-exporter:latest
restart: unless-stopped
command:
- '--web.listen-address=:9100'
- '--path.rootfs=/host'
- '--collector.systemd'
- '--collector.processes'
network_mode: host
pid: host
volumes:
- '/:/host:ro,rslave'
@@ -0,0 +1,22 @@
version: "3.2"
services:
osmosis-front-end:
image: cerc/osmosis-front-end-urbit:local
restart: on-failure
environment:
- NEXT_PUBLIC_WEB_API_BASE_URL=${CERC_WEB_API_BASE_URL}
- ASSET_LIST_COMMIT_HASH=a326bcefc51372b4912be5a2a2fa84a5d142a438
- NEXT_PUBLIC_BASEPATH=/apps/osmosis
- NEXT_PUBLIC_URBIT_DEPLOYMENT=true
working_dir: /app/packages/web
command: ["./build-app-for-urbit.sh"]
volumes:
- ../config/osmosis/build-app-for-urbit.sh:/app/packages/web/build-app-for-urbit.sh
- ../config/osmosis/.env.production:/app/packages/web/.env.production
- urbit_app_builds:/app-builds
- ../config/osmosis/urbit-files/mar:/app/packages/web/mar
- ../config/osmosis/urbit-files/desk.docket-0:/app/packages/web/desk.docket-0
volumes:
urbit_app_builds:
@@ -0,0 +1,36 @@
version: "3.2"
services:
osmosis-front-end:
image: cerc/osmosis-front-end:local
restart: on-failure
environment:
- NEXT_PUBLIC_WEB_API_BASE_URL=${CERC_WEB_API_BASE_URL}
- ASSET_LIST_COMMIT_HASH=a326bcefc51372b4912be5a2a2fa84a5d142a438
working_dir: /app/packages/web
command: ["./build-app.sh"]
volumes:
- ../config/osmosis/build-app.sh:/app/packages/web/build-app.sh
- ../config/osmosis/.env.production:/app/packages/web/.env.production
- app_builds:/app-builds
nginx:
image: nginx:1.23-alpine
restart: always
depends_on:
osmosis-front-end:
condition: service_completed_successfully
volumes:
- ../config/osmosis/nginx:/etc/nginx/conf.d
- app_builds:/usr/share/nginx
ports:
- "80"
healthcheck:
test: ["CMD", "nc", "-vz", "localhost", "80"]
interval: 20s
timeout: 5s
retries: 15
start_period: 5s
volumes:
app_builds:
@@ -0,0 +1,57 @@
version: "3.7"
services:
prometheus:
image: prom/prometheus:v2.49.1
restart: always
volumes:
- ../config/monitoring/prometheus:/etc/prometheus
- prometheus_data:/prometheus
ports:
- "9090"
healthcheck:
test: ["CMD", "nc", "-vz", "localhost", "9090"]
interval: 30s
timeout: 5s
retries: 10
start_period: 3s
extra_hosts:
- "host.docker.internal:host-gateway"
blackbox:
image: prom/blackbox-exporter:latest
restart: always
volumes:
- ../config/monitoring/blackbox.yml:/etc/blackbox_exporter/config.yml
ports:
- '9115'
extra_hosts:
- "host.docker.internal:host-gateway"
chain-head-exporter:
image: cerc/watcher-ts:local
restart: always
working_dir: /app/packages/cli
environment:
ETH_RPC_ENDPOINT: ${CERC_ETH_RPC_ENDPOINT}
FIL_RPC_ENDPOINT: ${CERC_FIL_RPC_ENDPOINT}
ETH_RPC_API_KEY: ${CERC_INFURA_KEY}
PORT: ${CERC_METRICS_PORT}
command: ["sh", "-c", "yarn export-metrics:chain-heads"]
ports:
- '5000'
extra_hosts:
- "host.docker.internal:host-gateway"
postgres-exporter:
image: quay.io/prometheuscommunity/postgres-exporter
restart: always
volumes:
- ../config/monitoring/postgres-exporter.yml:/postgres_exporter.yml
ports:
- '9187'
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
prometheus_data:
@@ -6,7 +6,7 @@ services:
restart: on-failure
working_dir: /app/packages/cli
environment:
ENABLE_PROXY: ${ENABLE_PROXY:-true}
ENABLE_PROXY: ${CERC_ENABLE_PROXY:-true}
PROXY_UPSTREAM: ${CERC_PROXY_UPSTREAM}
PROXY_ORIGIN_HEADER: ${CERC_PROXY_ORIGIN_HEADER}
command: ["sh", "-c", "./run.sh"]
@@ -7,8 +7,10 @@ services:
CERC_TEST_PARAM_1: ${CERC_TEST_PARAM_1:-FAILED}
volumes:
- test-data:/data
- test-config:/config:ro
ports:
- "80"
volumes:
test-data:
test-config:
@@ -9,9 +9,10 @@ services:
- REACT_APP_AWS_API_ENDPOINT=${CERC_UNISWAP_GQL}
command: ["./build-app.sh"]
volumes:
- app_builds:/app-builds
- ../config/uniswap-interface/build-app.sh:/app/build-app.sh
- urbit_app_builds:/app-builds
- ../config/uniswap-interface/urbit-files/mar:/app/mar
- ../config/uniswap-interface/urbit-files/desk.docket-0:/app/desk.docket-0
volumes:
app_builds:
app_globs:
urbit_app_builds:
@@ -1,46 +0,0 @@
version: '3.7'
services:
urbit-fake-ship:
restart: unless-stopped
image: tloncorp/vere
environment:
CERC_IPFS_GLOB_HOST_ENDPOINT: ${CERC_IPFS_GLOB_HOST_ENDPOINT:-http://ipfs-glob-host:5001}
CERC_IPFS_SERVER_ENDPOINT: ${CERC_IPFS_SERVER_ENDPOINT:-http://ipfs-glob-host:8080}
entrypoint: ["bash", "-c", "./run-urbit-ship.sh && ./deploy-uniswap-app.sh && tail -f /dev/null"]
volumes:
- urbit_data:/urbit
- app_builds:/app-builds
- app_globs:/app-globs
- ../config/urbit/run-urbit-ship.sh:/urbit/run-urbit-ship.sh
- ../config/uniswap-interface/deploy-uniswap-app.sh:/urbit/deploy-uniswap-app.sh
ports:
- "80"
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "80"]
interval: 20s
timeout: 5s
retries: 15
start_period: 10s
ipfs-glob-host:
image: ipfs/kubo:master-2023-02-20-714a968
volumes:
- ipfs-import:/import
- ipfs-data:/data/ipfs
ports:
- "8080"
- "5001"
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "5001"]
interval: 20s
timeout: 5s
retries: 15
start_period: 10s
volumes:
urbit_data:
app_builds:
app_globs:
ipfs-import:
ipfs-data:
@@ -35,7 +35,7 @@ services:
- ../config/watcher-merkl-sushiswap-v3/watcher-config-template.toml:/app/environments/watcher-config-template.toml
- ../config/watcher-merkl-sushiswap-v3/start-job-runner.sh:/app/start-job-runner.sh
ports:
- "9000"
- "9002:9000"
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "9000"]
interval: 20s
@@ -62,7 +62,7 @@ services:
- ../config/watcher-merkl-sushiswap-v3/start-server.sh:/app/start-server.sh
ports:
- "127.0.0.1:3007:3008"
- "9001"
- "9003:9001"
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "3008"]
interval: 20s
@@ -35,7 +35,7 @@ services:
- ../config/watcher-sushiswap-v3/watcher-config-template.toml:/app/environments/watcher-config-template.toml
- ../config/watcher-sushiswap-v3/start-job-runner.sh:/app/start-job-runner.sh
ports:
- "9000"
- "9000:9000"
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "9000"]
interval: 20s
@@ -62,7 +62,7 @@ services:
- ../config/watcher-sushiswap-v3/start-server.sh:/app/start-server.sh
ports:
- "127.0.0.1:3008:3008"
- "9001"
- "9001:9001"
healthcheck:
test: ["CMD", "nc", "-v", "localhost", "3008"]
interval: 20s
@@ -0,0 +1,125 @@
#!/bin/bash
# TODO: this file is now an unmodified copy of cerc-io/laconicd/init.sh
# so we should have a mechanism to bundle it inside the container rather than link from here
# at deploy time.
KEY="mykey"
CHAINID="laconic_9000-1"
MONIKER="localtestnet"
KEYRING="test"
KEYALGO="eth_secp256k1"
LOGLEVEL="info"
# trace evm
TRACE="--trace"
# TRACE=""
if [ "$1" == "clean" ] || [ ! -d "$HOME/.laconicd/data/blockstore.db" ]; then
# validate dependencies are installed
command -v jq > /dev/null 2>&1 || { echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/"; exit 1; }
# remove existing daemon and client
rm -rf $HOME/.laconicd/*
rm -rf $HOME/.laconic/*
if [ -n "`which make`" ]; then
make install
fi
laconicd config keyring-backend $KEYRING
laconicd config chain-id $CHAINID
# if $KEY exists it should be deleted
laconicd keys add $KEY --keyring-backend $KEYRING --algo $KEYALGO
# Set moniker and chain-id for Ethermint (Moniker can be anything, chain-id must be an integer)
laconicd init $MONIKER --chain-id $CHAINID
# Change parameter token denominations to aphoton
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["crisis"]["constant_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["mint"]["params"]["mint_denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
# Custom modules
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["record_rent"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_commit_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_reveal_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_minimum_bid"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
if [[ "$TEST_REGISTRY_EXPIRY" == "true" ]]; then
echo "Setting timers for expiry tests."
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["record_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_grace_period"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
fi
if [[ "$TEST_AUCTION_ENABLED" == "true" ]]; then
echo "Enabling auction and setting timers."
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_enabled"]=true' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_grace_period"]="300s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_commits_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_reveals_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
fi
# increase block time (?)
cat $HOME/.laconicd/config/genesis.json | jq '.consensus_params["block"]["time_iota_ms"]="1000"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
# Set gas limit in genesis
cat $HOME/.laconicd/config/genesis.json | jq '.consensus_params["block"]["max_gas"]="10000000"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json
# disable produce empty block
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.laconicd/config/config.toml
else
sed -i 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.laconicd/config/config.toml
fi
if [[ $1 == "pending" ]]; then
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.laconicd/config/config.toml
sed -i '' 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.laconicd/config/config.toml
else
sed -i 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.laconicd/config/config.toml
sed -i 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.laconicd/config/config.toml
fi
fi
# Allocate genesis accounts (cosmos formatted addresses)
laconicd add-genesis-account $KEY 100000000000000000000000000aphoton --keyring-backend $KEYRING
# Sign genesis transaction
laconicd gentx $KEY 1000000000000000000000aphoton --keyring-backend $KEYRING --chain-id $CHAINID
# Collect genesis tx
laconicd collect-gentxs
# Run this to ensure everything worked and that the genesis file is setup correctly
laconicd validate-genesis
if [[ $1 == "pending" ]]; then
echo "pending mode is on, please wait for the first block committed."
fi
else
echo "Using existing database at $HOME/.laconicd. To replace, run '`basename $0` clean'"
fi
# Start the node (remove the --pruning=nothing flag if historical queries are not needed)
laconicd start --pruning=nothing --evm.tracer=json $TRACE --log_level $LOGLEVEL --minimum-gas-prices=0.0001aphoton --json-rpc.api eth,txpool,personal,net,debug,web3,miner --api.enable --gql-server --gql-playground
@@ -0,0 +1,2 @@
#!/bin/sh
laconicd keys show mykey | grep address | cut -d ' ' -f 3
@@ -0,0 +1,2 @@
#!/bin/sh
echo y | laconicd keys export mykey --unarmored-hex --unsafe
@@ -0,0 +1,9 @@
services:
cns:
restEndpoint: 'http://laconicd:1317'
gqlEndpoint: 'http://laconicd:9473/api'
userKey: REPLACE_WITH_MYKEY
bondId:
chainId: laconic_9000-1
gas: 350000
fees: 200000aphoton
@@ -0,0 +1,7 @@
modules:
http_2xx:
prober: http
timeout: 5s
http:
valid_status_codes: [] #default to 2xx
method: GET
@@ -0,0 +1,943 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "node.js prometheus client basic metrics",
"editable": true,
"fiscalYearStartMonth": 0,
"gnetId": 11159,
"graphTooltip": 0,
"id": 15,
"links": [],
"liveNow": false,
"panels": [
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 10,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 6,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"paceLength": 10,
"percentage": false,
"pluginVersion": "10.2.2",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "irate(process_cpu_user_seconds_total{instance=~\"$instance\"}[2m]) * 100",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "User CPU - {{instance}}",
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "irate(process_cpu_system_seconds_total{instance=~\"$instance\"}[2m]) * 100",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "Sys CPU - {{instance}}",
"refId": "B"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Process CPU Usage",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "percent",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 9,
"x": 10,
"y": 0
},
"hiddenSeries": false,
"id": 8,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"paceLength": 10,
"percentage": false,
"pluginVersion": "10.2.2",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "nodejs_eventloop_lag_seconds{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "{{instance}}",
"refId": "A"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Event Loop Lag",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "s",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"fixedColor": "text",
"mode": "fixed"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 3,
"w": 5,
"x": 19,
"y": 0
},
"id": 2,
"interval": "",
"links": [],
"maxDataPoints": 100,
"options": {
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"mean"
],
"fields": "",
"values": false
},
"textMode": "name",
"wideLayout": true
},
"pluginVersion": "10.2.2",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "sum(nodejs_version_info{instance=~\"$instance\"}) by (version)",
"format": "time_series",
"instant": false,
"interval": "",
"intervalFactor": 1,
"legendFormat": "{{version}}",
"refId": "A"
}
],
"title": "Node.js Version",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"color": {
"fixedColor": "#F2495C",
"mode": "fixed"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 5,
"x": 19,
"y": 3
},
"id": 4,
"links": [],
"maxDataPoints": 100,
"options": {
"colorMode": "none",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "10.2.2",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "sum(changes(process_start_time_seconds{instance=~\"$instance\"}[1m]))",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "{{instance}}",
"refId": "A"
}
],
"title": "Process Restart Times",
"type": "stat"
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 16,
"x": 0,
"y": 7
},
"hiddenSeries": false,
"id": 7,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"rightSide": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"paceLength": 10,
"percentage": false,
"pluginVersion": "10.2.2",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "process_resident_memory_bytes{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "Process Memory - {{instance}}",
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "nodejs_heap_size_total_bytes{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "Heap Total - {{instance}}",
"refId": "B"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "nodejs_heap_size_used_bytes{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "Heap Used - {{instance}}",
"refId": "C"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "nodejs_external_memory_bytes{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "External Memory - {{instance}}",
"refId": "D"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Process Memory Usage",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 8,
"x": 16,
"y": 7
},
"hiddenSeries": false,
"id": 9,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"paceLength": 10,
"percentage": false,
"pluginVersion": "10.2.2",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "nodejs_active_handles_total{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "Active Handler - {{instance}}",
"refId": "A"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "nodejs_active_requests_total{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "Active Request - {{instance}}",
"refId": "B"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Active Handlers/Requests Total",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 8,
"x": 0,
"y": 14
},
"hiddenSeries": false,
"id": 10,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"rightSide": false,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"paceLength": 10,
"percentage": false,
"pluginVersion": "10.2.2",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "nodejs_heap_space_size_total_bytes{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "Heap Total - {{instance}} - {{space}}",
"refId": "A"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Heap Total Detail",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 8,
"x": 8,
"y": 14
},
"hiddenSeries": false,
"id": 11,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"rightSide": false,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"paceLength": 10,
"percentage": false,
"pluginVersion": "10.2.2",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "nodejs_heap_space_size_used_bytes{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "Heap Used - {{instance}} - {{space}}",
"refId": "A"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Heap Used Detail",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 8,
"x": 16,
"y": 14
},
"hiddenSeries": false,
"id": 12,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"rightSide": false,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"paceLength": 10,
"percentage": false,
"pluginVersion": "10.2.2",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"expr": "nodejs_heap_space_size_available_bytes{instance=~\"$instance\"}",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "Heap Used - {{instance}} - {{space}}",
"refId": "A"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Heap Available Detail",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "bytes",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
}
],
"refresh": "10s",
"schemaVersion": 38,
"tags": [
"nodejs"
],
"templating": {
"list": [
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"definition": "label_values(nodejs_version_info, instance)",
"hide": 0,
"includeAll": true,
"label": "instance",
"multi": true,
"name": "instance",
"options": [],
"query": "label_values(nodejs_version_info, instance)",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
}
]
},
"time": {
"from": "now-15m",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "",
"title": "NodeJS Application Dashboard",
"uid": "PTSqcpJWk",
"version": 3,
"weekStart": ""
}
@@ -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,10 @@
apiVersion: 1
providers:
- name: dashboards
type: file
updateIntervalSeconds: 10
allowUiUpdates: true
options:
path: /etc/grafana/dashboards
foldersFromFilesStructure: true
@@ -0,0 +1,16 @@
apiVersion: 1
datasources:
- id: 1
orgId: 1
name: Prometheus
type: prometheus
typeName: Prometheus
typeLogoUrl: public/app/plugins/datasource/prometheus/img/prometheus_logo.svg
access: proxy
url: http://prometheus:9090
isDefault: true
jsonData:
httpMethod: POST
version: 1
editable: true
@@ -0,0 +1,8 @@
auth_modules:
foo:
type: userpass
userpass:
username: username
password: password
options:
sslmode: disable
@@ -0,0 +1,67 @@
global:
scrape_interval: 10s
evaluation_interval: 15s
rule_files:
# - "first.rules"
# - "second.rules"
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['localhost:9090']
- job_name: node
static_configs:
# Add node-exporter targets to be monitored below
# - targets: ['example-host:9100']
# labels:
# instance: 'my-host'
- job_name: 'blackbox'
scrape_interval: 10s
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
# Add URLs to be monitored below
- targets:
# - https://github.com
relabel_configs:
- source_labels: [__address__]
regex: (.*)(:80)?
target_label: __param_target
- source_labels: [__param_target]
regex: (.*)
target_label: instance
replacement: ${1}
- source_labels: []
regex: .*
target_label: __address__
replacement: blackbox:9115
- job_name: chain_heads
scrape_interval: 10s
metrics_path: /metrics
scheme: http
static_configs:
- targets: ['chain-head-exporter:5000']
- job_name: 'postgres'
scrape_interval: 30s
scrape_timeout: 30s
static_configs:
# Add DB targets below
# - targets: [example-server:5432]
# labels:
# instance: 'example-label'
metrics_path: /probe
params:
auth_module: [foo]
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: postgres-exporter:9187
@@ -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
@@ -0,0 +1,3 @@
NEXT_PUBLIC_COINGECKO_URL=https://api.coingecko.com
NEXT_PUBLIC_ENABLE_FEATURES=true
@@ -0,0 +1,22 @@
#!/bin/bash
set -e
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
# Check and exit if a deployment already exists (on restarts)
if [ -d /app-builds/osmosis/build ]; then
echo "Build already exists, remove volume to rebuild"
exit 0
fi
yarn build:static
./build-urbit.sh
# Move build to app-builds
mkdir -p /app-builds/osmosis
cp -r ./out /app-builds/osmosis/build
cp -r mar /app-builds/osmosis/
cp desk.docket-0 /app-builds/osmosis/
+18
View File
@@ -0,0 +1,18 @@
#!/bin/bash
set -e
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
# Check and exit if a deployment already exists (on restarts)
if [ -d /app-builds/osmosis/build ]; then
echo "Build already exists, remove volume to rebuild"
exit 0
fi
yarn build:static
# Move build to app-builds
mkdir -p /app-builds/osmosis
cp -r ./out /app-builds/osmosis/build
@@ -0,0 +1,16 @@
server {
listen 80;
listen [::]:80;
server_name _;
error_page 500 502 503 504 /50x.html;
location / {
root /usr/share/nginx/osmosis/build;
index index.html index.htm index.nginx-debian.html;
# First attempt to serve request as file, then as html,
# then as directory, then fall back to displaying a 404.
try_files $uri $uri.html $uri/ /index.html =404;
}
}
@@ -0,0 +1,10 @@
:~ title+'Osmosis'
info+'Osmosis DEX Frontend, built and maintained by Laconic'
color+0xcd.75df
image+'https://altcoinsbox.com/wp-content/uploads/2023/03/osmosis-logo.png'
base+'osmosis'
glob-http+['REPLACE_WITH_GLOB_URL' REPLACE_WITH_GLOB_HASH]
version+[0 0 2]
website+'https://osmosis.zone/'
license+'MIT'
==
@@ -0,0 +1,12 @@
|_ dat=@
++ grow
|%
++ mime [/image/x-icon (as-octs:mimes:html dat)]
--
++ grab
|%
++ mime |=([p=mite q=octs] q.q)
++ noun @
--
++ grad %mime
--
@@ -0,0 +1,12 @@
|_ dat=@
++ grow
|%
++ mime [/image/jpeg (as-octs:mimes:html dat)]
--
++ grab
|%
++ mime |=([p=mite q=octs] q.q)
++ noun @
--
++ grad %mime
--
@@ -0,0 +1,18 @@
::
:::: /hoon/map/mar
:: Mark for js source maps
/? 310
::
=, eyre
|_ mud=@
++ grow
|%
++ mime [/application/octet-stream (as-octs:mimes:html (@t mud))]
--
++ grab
|% :: convert from
++ mime |=([p=mite q=octs] (@t q.q))
++ noun cord :: clam from %noun
--
++ grad %mime
--
@@ -0,0 +1,12 @@
|_ dat=@
++ grow
|%
++ mime [/image/webp (as-octs:mimes:html dat)]
--
++ grab
|%
++ mime |=([p=mite q=octs] q.q)
++ noun @
--
++ grad %mime
--
@@ -13,6 +13,9 @@ fi
yarn build
# Move build to app-builds so urbit can deploy it
mkdir /app-builds/uniswap
# Copy over build and other files to app-builds for urbit deployment
mkdir -p /app-builds/uniswap
cp -r ./build /app-builds/uniswap/
cp -r mar /app-builds/uniswap/
cp desk.docket-0 /app-builds/uniswap/
@@ -1,149 +0,0 @@
#!/bin/bash
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
echo "Using IPFS endpoint ${CERC_IPFS_GLOB_HOST_ENDPOINT} for hosting globs"
echo "Using IPFS server endpoint ${CERC_IPFS_SERVER_ENDPOINT} for reading glob files"
ipfs_host_endpoint=${CERC_IPFS_GLOB_HOST_ENDPOINT}
ipfs_server_endpoint=${CERC_IPFS_SERVER_ENDPOINT}
uniswap_app_build='/app-builds/uniswap/build'
uniswap_desk_dir='/urbit/zod/uniswap'
if [ -d ${uniswap_desk_dir} ]; then
echo "Uniswap desk dir already exists, skipping deployment..."
exit 0
fi
# Fire curl requests to perform operations on the ship
dojo () {
curl -s --data '{"source":{"dojo":"'"$1"'"},"sink":{"stdout":null}}' http://localhost:12321
}
hood () {
curl -s --data '{"source":{"dojo":"+hood/'"$1"'"},"sink":{"app":"hood"}}' http://localhost:12321
}
# Create/mount a uniswap desk
hood "merge %uniswap our %landscape"
hood "mount %uniswap"
# Loop until the uniswap build appears
while [ ! -d ${uniswap_app_build} ]; do
echo "Uniswap app build not found, retrying in 5s..."
sleep 5
done
echo "Build found..."
# Copy over build to desk data dir
cp -r ${uniswap_app_build} ${uniswap_desk_dir}
# Create a mark file for .map file type
cat << EOF > "${uniswap_desk_dir}/mar/map.hoon"
::
:::: /hoon/map/mar
:: Mark for js source maps
/? 310
::
=, eyre
|_ mud=@
++ grow
|%
++ mime [/application/octet-stream (as-octs:mimes:html (@t mud))]
--
++ grab
|% :: convert from
++ mime |=([p=mite q=octs] (@t q.q))
++ noun cord :: clam from %noun
--
++ grad %mime
--
EOF
# Create a mark file for .woff file type
cat << EOF > "${uniswap_desk_dir}/mar/woff.hoon"
|_ dat=octs
++ grow
|%
++ mime [/font/woff dat]
--
++ grab
|%
++ mime |=([=mite =octs] octs)
++ noun octs
--
++ grad %mime
--
EOF
# Create a mark file for .ttf file type
cat << EOF > "${uniswap_desk_dir}/mar/ttf.hoon"
|_ dat=octs
++ grow
|%
++ mime [/font/ttf dat]
--
++ grab
|%
++ mime |=([=mite =octs] octs)
++ noun octs
--
++ grad %mime
--
EOF
rm "${uniswap_desk_dir}/desk.bill"
rm "${uniswap_desk_dir}/desk.ship"
# Commit changes and create a glob
hood "commit %uniswap"
dojo "-landscape!make-glob %uniswap /build"
glob_file=$(ls -1 -c zod/.urb/put | head -1)
echo "Created glob file: ${glob_file}"
upload_response=$(curl -X POST -F file=@./zod/.urb/put/${glob_file} ${ipfs_host_endpoint}/api/v0/add)
glob_cid=$(echo "$upload_response" | grep -o '"Hash":"[^"]*' | sed 's/"Hash":"//')
echo "Glob file uploaded to IFPS:"
echo "{ cid: ${glob_cid}, filename: ${glob_file} }"
# Curl and wait for the glob to be hosted
glob_url="${ipfs_server_endpoint}/ipfs/${glob_cid}?filename=${glob_file}"
echo "Checking if glob file hosted at ${glob_url}"
while true; do
response=$(curl -sL -w "%{http_code}" -o /dev/null "$glob_url")
if [ $response -eq 200 ]; then
echo "File found at $glob_url"
break # Exit the loop if the file is found
else
echo "File not found. Retrying in a few seconds..."
sleep 5
fi
done
glob_hash=$(echo "$glob_file" | sed "s/glob-\([a-z0-9\.]*\).glob/\1/")
# Update the docket file
cat << EOF > "${uniswap_desk_dir}/desk.docket-0"
:~ title+'Uniswap'
info+'Self-hosted uniswap frontend.'
color+0xcd.75df
image+'https://logowik.com/content/uploads/images/uniswap-uni7403.jpg'
base+'uniswap'
glob-http+['${glob_url}' ${glob_hash}]
version+[0 0 1]
website+'https://uniswap.org/'
license+'MIT'
==
EOF
# Commit changes and install the app
hood "commit %uniswap"
hood "install our %uniswap"
echo "Uniswap app installed"
@@ -1,110 +0,0 @@
#!/bin/bash
# $1: Glob file URL (eg. https://xyz.com/glob-0vabcd.glob)
# $2: Glob file hash (eg. 0vabcd)
# $3: Urbit ship's pier dir (default: ./zod)
if [ "$#" -lt 2 ]; then
echo "Insufficient arguments"
exit 0
fi
glob_url=$1
glob_hash=$2
echo "Using glob file from ${glob_url} with hash ${glob_hash}"
# Default pier dir: ./zod
# Default desk dir: ./zod/uniswap
pier_dir="${3:-./zod}"
uniswap_desk_dir="${pier_dir}/uniswap"
echo "Using ${uniswap_desk_dir} as the Uniswap desk dir path"
# Fire curl requests to perform operations on the ship
dojo () {
curl -s --data '{"source":{"dojo":"'"$1"'"},"sink":{"stdout":null}}' http://localhost:12321
}
hood () {
curl -s --data '{"source":{"dojo":"+hood/'"$1"'"},"sink":{"app":"hood"}}' http://localhost:12321
}
# Create/mount a uniswap desk
hood "merge %uniswap our %landscape"
hood "mount %uniswap"
# Create a mark file for .map file type
cat << EOF > "${uniswap_desk_dir}/mar/map.hoon"
::
:::: /hoon/map/mar
:: Mark for js source maps
/? 310
::
=, eyre
|_ mud=@
++ grow
|%
++ mime [/application/octet-stream (as-octs:mimes:html (@t mud))]
--
++ grab
|% :: convert from
++ mime |=([p=mite q=octs] (@t q.q))
++ noun cord :: clam from %noun
--
++ grad %mime
--
EOF
# Create a mark file for .woff file type
cat << EOF > "${uniswap_desk_dir}/mar/woff.hoon"
|_ dat=octs
++ grow
|%
++ mime [/font/woff dat]
--
++ grab
|%
++ mime |=([=mite =octs] octs)
++ noun octs
--
++ grad %mime
--
EOF
# Create a mark file for .ttf file type
cat << EOF > "${uniswap_desk_dir}/mar/ttf.hoon"
|_ dat=octs
++ grow
|%
++ mime [/font/ttf dat]
--
++ grab
|%
++ mime |=([=mite =octs] octs)
++ noun octs
--
++ grad %mime
--
EOF
rm "${uniswap_desk_dir}/desk.bill"
rm "${uniswap_desk_dir}/desk.ship"
# Update the docket file
cat << EOF > "${uniswap_desk_dir}/desk.docket-0"
:~ title+'Uniswap'
info+'Self-hosted uniswap frontend.'
color+0xcd.75df
image+'https://logowik.com/content/uploads/images/uniswap-uni7403.jpg'
base+'uniswap'
glob-http+['${glob_url}' ${glob_hash}]
version+[0 0 1]
website+'https://uniswap.org/'
license+'MIT'
==
EOF
# Commit changes and install the app
hood "commit %uniswap"
hood "install our %uniswap"
echo "Uniswap app installed"
@@ -1,21 +0,0 @@
#!/bin/bash
# $1: Remote user host
# $2: Remote Urbit ship's pier dir path (eg. /home/user/zod)
# $3: Glob file URL (eg. https://xyz.com/glob-0vabcd.glob)
# $4: Glob file hash (eg. 0vabcd)
if [ "$#" -ne 4 ]; then
echo "Incorrect number of arguments"
echo "Usage: $0 <username@remote_host> </path/to/remote/pier/folder> <glob_url> <glob_hash>"
exit 1
fi
remote_user_host="$1"
remote_pier_folder="$2"
glob_url="$3"
glob_hash="$4"
installation_script="./install-uniswap-app.sh"
ssh "$remote_user_host" "bash -s $glob_url $glob_hash $remote_pier_folder" < "$installation_script"
@@ -0,0 +1,10 @@
:~ title+'Uniswap'
info+'Self-hosted uniswap frontend.'
color+0xcd.75df
image+'https://logowik.com/content/uploads/images/uniswap-uni7403.jpg'
base+'uniswap'
glob-http+['REPLACE_WITH_GLOB_URL' REPLACE_WITH_GLOB_HASH]
version+[0 0 1]
website+'https://uniswap.org/'
license+'MIT'
==
@@ -0,0 +1,18 @@
::
:::: /hoon/map/mar
:: Mark for js source maps
/? 310
::
=, eyre
|_ mud=@
++ grow
|%
++ mime [/application/octet-stream (as-octs:mimes:html (@t mud))]
--
++ grab
|% :: convert from
++ mime |=([p=mite q=octs] (@t q.q))
++ noun cord :: clam from %noun
--
++ grad %mime
--
@@ -0,0 +1,12 @@
|_ dat=octs
++ grow
|%
++ mime [/font/ttf dat]
--
++ grab
|%
++ mime |=([=mite =octs] octs)
++ noun octs
--
++ grad %mime
--
@@ -0,0 +1,12 @@
|_ dat=octs
++ grow
|%
++ mime [/font/woff dat]
--
++ grab
|%
++ mime |=([=mite =octs] octs)
++ noun octs
--
++ grad %mime
--
@@ -0,0 +1,34 @@
#!/bin/bash
# $1: Remote user host
# $2: App name (eg. uniswap)
# $3: Assets dir path (local) for app (eg. /home/user/myapp/urbit-files)
# $4: Remote Urbit ship's pier dir path (eg. /home/user/zod)
# $5: Glob file URL (eg. https://xyz.com/glob-0vabcd.glob)
# $6: Glob file hash (eg. 0vabcd)
if [ "$#" -ne 6 ]; then
echo "Incorrect number of arguments"
echo "Usage: $0 <username@remote_host> <app_name> </path/to/app/assets/folder> </path/to/remote/pier/folder> <glob_url> <glob_hash>"
exit 1
fi
remote_user_host="$1"
app_name=$2
app_assets_folder=$3
remote_pier_folder="$4"
glob_url="$5"
glob_hash="$6"
installation_script="./install-urbit-app.sh"
# Copy over the assets to remote machine in a tmp dir
remote_app_assets_folder=/tmp/urbit-app-assets/$app_name
ssh "$remote_user_host" "mkdir -p $remote_app_assets_folder"
scp -r $app_assets_folder/* $remote_user_host:$remote_app_assets_folder
# Run the installation script
ssh "$remote_user_host" "bash -s $app_name $remote_app_assets_folder '${glob_url}' $glob_hash $remote_pier_folder" < "$installation_script"
# Remove the tmp assets dir
ssh "$remote_user_host" "rm -rf $remote_app_assets_folder"
+110
View File
@@ -0,0 +1,110 @@
#!/bin/bash
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
if [ -z "$CERC_URBIT_APP" ]; then
echo "CERC_URBIT_APP not set, exiting"
exit 0
fi
echo "Creating Urbit application for ${CERC_URBIT_APP}"
app_desk_dir=/urbit/zod/${CERC_URBIT_APP}
if [ -d ${app_desk_dir} ]; then
echo "Desk dir already exists for ${CERC_URBIT_APP}, skipping deployment..."
exit 0
fi
app_build=/app-builds/${CERC_URBIT_APP}/build
app_mark_files=/app-builds/${CERC_URBIT_APP}/mar
app_docket_file=/app-builds/${CERC_URBIT_APP}/desk.docket-0
echo "Reading app build from ${app_build}"
echo "Reading additional mark files from ${app_mark_files}"
echo "Reading docket file ${app_docket_file}"
# Loop until the app's build appears
while [ ! -d ${app_build} ]; do
echo "${CERC_URBIT_APP} app build not found, retrying in 5s..."
sleep 5
done
echo "Build found..."
echo "Using IPFS endpoint ${CERC_IPFS_GLOB_HOST_ENDPOINT} for hosting the ${CERC_URBIT_APP} glob"
echo "Using IPFS server endpoint ${CERC_IPFS_SERVER_ENDPOINT} for reading ${CERC_URBIT_APP} glob"
ipfs_host_endpoint=${CERC_IPFS_GLOB_HOST_ENDPOINT}
ipfs_server_endpoint=${CERC_IPFS_SERVER_ENDPOINT}
# Fire curl requests to perform operations on the ship
dojo () {
curl -s --data '{"source":{"dojo":"'"$1"'"},"sink":{"stdout":null}}' http://localhost:12321
}
hood () {
curl -s --data '{"source":{"dojo":"+hood/'"$1"'"},"sink":{"app":"hood"}}' http://localhost:12321
}
# Create / mount the app's desk
hood "merge %${CERC_URBIT_APP} our %landscape"
hood "mount %${CERC_URBIT_APP}"
# Copy over build to desk data dir
cp -r ${app_build} ${app_desk_dir}
# Copy over the additional mark files
cp ${app_mark_files}/* ${app_desk_dir}/mar/
rm "${app_desk_dir}/desk.bill"
rm "${app_desk_dir}/desk.ship"
# Commit changes and create a glob
hood "commit %${CERC_URBIT_APP}"
dojo "-landscape!make-glob %${CERC_URBIT_APP} /build"
glob_file=$(ls -1 -c zod/.urb/put | head -1)
echo "Created glob file: ${glob_file}"
# Upload the glob file to IPFS
echo "Uploading glob file to ${ipfs_host_endpoint}"
upload_response=$(curl -X POST -F file=@./zod/.urb/put/${glob_file} ${ipfs_host_endpoint}/api/v0/add)
glob_cid=$(echo "$upload_response" | grep -o '"Hash":"[^"]*' | sed 's/"Hash":"//')
glob_url="${ipfs_server_endpoint}/ipfs/${glob_cid}?filename=${glob_file}"
glob_hash=$(echo "$glob_file" | sed "s/glob-\([a-z0-9\.]*\).glob/\1/")
echo "Glob file uploaded to IFPS:"
echo "{ cid: ${glob_cid}, filename: ${glob_file} }"
echo "{ url: ${glob_url}, hash: ${glob_hash} }"
# Exit if the installation not required
if [ "$CERC_ENABLE_APP_INSTALL" = "false" ]; then
echo "CERC_ENABLE_APP_INSTALL set to false, skipping app installation"
exit 0
fi
# Curl and wait for the glob to be hosted
echo "Checking if glob file hosted at ${glob_url}"
while true; do
response=$(curl -sL -w "%{http_code}" -o /dev/null "$glob_url")
if [ $response -eq 200 ]; then
echo "File found at $glob_url"
break # Exit the loop if the file is found
else
echo "File not found, retrying in a 5s..."
sleep 5
fi
done
# Replace the docket file for app
# Substitue the glob URL and hash
cp ${app_docket_file} ${app_desk_dir}/
sed -i "s|REPLACE_WITH_GLOB_URL|${glob_url}|g; s|REPLACE_WITH_GLOB_HASH|${glob_hash}|g" ${app_desk_dir}/desk.docket-0
# Commit changes and install the app
hood "commit %${CERC_URBIT_APP}"
hood "install our %${CERC_URBIT_APP}"
echo "${CERC_URBIT_APP} app installed"
+60
View File
@@ -0,0 +1,60 @@
#!/bin/bash
# $1: App name (eg. uniswap)
# $2: Assets dir path (local) for app (eg. /home/user/myapp/urbit-files)
# $3: Glob file URL (eg. https://xyz.com/glob-0vabcd.glob)
# $4: Glob file hash (eg. 0vabcd)
# $5: Urbit ship's pier dir (default: ./zod)
if [ "$#" -lt 4 ]; then
echo "Insufficient arguments"
echo "Usage: $0 <app_name> </path/to/app/assets/folder> <glob_url> <glob_hash> [/path/to/remote/pier/folder]"
exit 1
fi
app_name=$1
app_mark_files=$2/mar
app_docket_file=$2/desk.docket-0
echo "Creating Urbit application for ${app_name}"
echo "Reading additional mark files from ${app_mark_files}"
echo "Reading docket file ${app_docket_file}"
glob_url=$3
glob_hash=$4
echo "Using glob file from ${glob_url} with hash ${glob_hash}"
# Default pier dir: ./zod
# Default desk dir: ./zod/<app_name>
pier_dir="${5:-./zod}"
app_desk_dir="${pier_dir}/${app_name}"
echo "Using ${app_desk_dir} as the ${app_name} desk dir path"
# Fire curl requests to perform operations on the ship
dojo () {
curl -s --data '{"source":{"dojo":"'"$1"'"},"sink":{"stdout":null}}' http://localhost:12321
}
hood () {
curl -s --data '{"source":{"dojo":"+hood/'"$1"'"},"sink":{"app":"hood"}}' http://localhost:12321
}
# Create / mount the app's desk
hood "merge %${app_name} our %landscape"
hood "mount %${app_name}"
# Copy over the additional mark files
cp ${app_mark_files}/* ${app_desk_dir}/mar/
rm "${app_desk_dir}/desk.bill"
rm "${app_desk_dir}/desk.ship"
# Replace the docket file for app
# Substitue the glob URL and hash
cp ${app_docket_file} ${app_desk_dir}/
sed -i "s|REPLACE_WITH_GLOB_URL|${glob_url}|g; s|REPLACE_WITH_GLOB_HASH|${glob_hash}|g" ${app_desk_dir}/desk.docket-0
# Commit changes and install the app
hood "commit %${app_name}"
hood "install our %${app_name}"
echo "${app_name} app installed"
@@ -7,11 +7,13 @@ fi
pier_dir="/urbit/zod"
# TODO: Bootstrap fake ship on the first run
# Run urbit ship in daemon mode
# Check if the directory exists
if [ -d "$pier_dir" ]; then
echo "Pier directory already exists, rebooting..."
urbit -d zod
/urbit/zod/.run -d
else
echo "Creating a new fake ship..."
urbit -d -F zod
@@ -41,7 +41,7 @@
timeTravelMaxAge = 86400 # 1 day
[metrics]
host = "127.0.0.1"
host = "0.0.0.0"
port = 9000
[metrics.gql]
port = 9001
@@ -84,8 +84,6 @@
subgraphEventsOrder = true
# Filecoin block time: https://docs.filecoin.io/basics/the-blockchain/blocks-and-tipsets#blocktime
blockDelayInMilliSecs = 30000
prefetchBlocksInMem = false
prefetchBlockCount = 10
# Boolean to switch between modes of processing events when starting the server.
# Setting to true will fetch filtered events and required blocks in a range of blocks and then process them.
@@ -41,7 +41,7 @@
timeTravelMaxAge = 86400 # 1 day
[metrics]
host = "127.0.0.1"
host = "0.0.0.0"
port = 9000
[metrics.gql]
port = 9001
@@ -84,8 +84,6 @@
subgraphEventsOrder = true
# Filecoin block time: https://docs.filecoin.io/basics/the-blockchain/blocks-and-tipsets#blocktime
blockDelayInMilliSecs = 30000
prefetchBlocksInMem = false
prefetchBlockCount = 10
# Boolean to switch between modes of processing events when starting the server.
# Setting to true will fetch filtered events and required blocks in a range of blocks and then process them.
@@ -2,4 +2,6 @@
# Build a local version of the task executor for act-runner
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
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} .
@@ -10,9 +10,10 @@ COPY genesis /opt/genesis
COPY --from=ethgen /usr/local/bin/eth2-testnet-genesis /usr/local/bin/
COPY --from=ethgen /usr/local/bin/eth2-val-tools /usr/local/bin/
COPY --from=ethgen /apps /apps
RUN cd /apps/el-gen && pip3 install -r requirements.txt
RUN cd /apps/el-gen && pip3 install --break-system-packages -r requirements.txt
# web3==5.24.0 used by el-gen is broken on python 3.11
RUN pip3 install --upgrade "web3==6.5.0"
RUN pip3 install --break-system-packages --upgrade "web3==6.5.0"
RUN pip3 install --break-system-packages --upgrade "typing-extensions"
# Build genesis config
RUN apk add --no-cache make bash envsubst jq
@@ -0,0 +1,14 @@
record:
type: ApplicationDeploymentRecord
version: 1.2.3
name: name
description: description
application: application
url: url
dns: dns
request: request
meta:
foo: bar
tags:
- a
- b
@@ -0,0 +1,12 @@
record:
type: GeneralRecord
version: 1.2.3
name: name
description: description
category: category
value: value
meta:
foo: bar
tags:
- a
- b
@@ -0,0 +1,17 @@
record:
type: ApplicationArtifact
version: 1.2.3
name: name
description: description
application: appidgoeshere
content_type: content_type
os: os
cpu: cpu
uri:
- uri://a
- uri://b
meta:
foo: bar
tags:
- a
- b
@@ -0,0 +1,11 @@
record:
type: DnsRecord
version: 0.0.1
name: "foo"
resource_type: "A"
value: "bar"
meta:
foo: bar
tags:
- a
- b
@@ -0,0 +1,18 @@
record:
type: ApplicationRecord
version: 0.0.1
name: my-demo-app
description: "Description of my app"
homepage: http://my.demo.app
license: license
author: author
repository:
- "https://my.demo.repo"
repository_ref: "v0.1.0"
app_version: "0.1.0"
app_type: "webapp"
meta:
foo: bar
tags:
- a
- b
@@ -0,0 +1,17 @@
record:
type: ApplicationDeploymentRequest
version: 1.2.3
application: application
dns: dns
config:
env:
ENV_VAR_A: A
ENV_VAR_B: B
crn:
- crn://foo.bar
- crn://bar.baz
meta:
foo: bar
tags:
- a
- b
@@ -1,2 +1,2 @@
#!/bin/sh
sed 's/REPLACE_WITH_MYKEY/'${1}'/' registry-cli-config-template.yml > config.yml
sed 's/REPLACE_WITH_MYKEY/'${1}'/' /registry-cli-config/registry-cli-config-template.yml > config.yml
@@ -1,6 +1,6 @@
# Originally from: https://github.com/devcontainers/images/blob/main/src/javascript-node/.devcontainer/Dockerfile
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
ARG VARIANT=20-bullseye
ARG VARIANT=20-bullseye-slim
FROM node:${VARIANT}
ARG USERNAME=node
@@ -30,13 +30,13 @@ RUN \
# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends jq gettext-base moreutils
&& apt-get -y install --no-install-recommends jq gettext-base procps
# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>"
# Expose port for http
EXPOSE 3000
EXPOSE 80
COPY /scripts /scripts
@@ -21,6 +21,11 @@ WORK_DIR="${1:-/app}"
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
cp next.config.js next.config.dist
fi
@@ -104,7 +109,8 @@ CUR_NEXT_VERSION="`jq -r '.dependencies.next' package.json`"
if [ "$CERC_NEXT_VERSION" != "keep" ] && [ "$CUR_NEXT_VERSION" != "$CERC_NEXT_VERSION" ]; then
echo "Changing 'next' version specifier from '$CUR_NEXT_VERSION' to '$CERC_NEXT_VERSION' (set with '--extra-build-args \"--build-arg CERC_NEXT_VERSION=$CERC_NEXT_VERSION\"')"
cat package.json | jq ".dependencies.next = \"$CERC_NEXT_VERSION\"" | sponge package.json
cat package.json | jq ".dependencies.next = \"$CERC_NEXT_VERSION\"" > package.json.$$
mv package.json.$$ package.json
fi
$CERC_BUILD_TOOL install || exit 1
@@ -128,7 +134,8 @@ to use for the build with:
###############################################################################
EOF
cat package.json | jq ".dependencies.next = \"^$CERC_MIN_NEXTVER\"" | sponge package.json
cat package.json | jq ".dependencies.next = \"^$CERC_MIN_NEXTVER\"" > package.json.$$
mv package.json.$$ package.json
$CERC_BUILD_TOOL install || exit 1
fi
@@ -42,7 +42,7 @@ if [ "$CERC_NEXTJS_SKIP_GENERATE" != "true" ]; then
while [ $count -lt $CERC_MAX_GENERATE_TIME ] && [ "$generate_done" == "false" ]; do
sleep 1
count=$((count + 1))
grep 'rendered as static HTML' gen.out > /dev/null
grep 'rendered as static' gen.out > /dev/null
if [ $? -eq 0 ]; then
generate_done="true"
fi
@@ -58,4 +58,4 @@ if [ "$CERC_NEXTJS_SKIP_GENERATE" != "true" ]; then
fi
fi
$CERC_BUILD_TOOL start . -p ${CERC_LISTEN_PORT:-3000}
$CERC_BUILD_TOOL start . -- -p ${CERC_LISTEN_PORT:-80}
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
# Build the osmosis front end image
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
docker build -t cerc/osmosis-front-end-urbit:local -f ${CERC_REPO_BASE_DIR}/osmosis-frontend/docker/Dockerfile.static ${build_command_args} ${CERC_REPO_BASE_DIR}/osmosis-frontend
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
# Build the osmosis front end image
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
docker build -t cerc/osmosis-front-end:local -f ${CERC_REPO_BASE_DIR}/osmosis-frontend/docker/Dockerfile.static ${build_command_args} ${CERC_REPO_BASE_DIR}/osmosis-frontend
@@ -17,5 +17,20 @@ fi
if [ -n "$CERC_TEST_PARAM_1" ]; then
echo "Test-param-1: ${CERC_TEST_PARAM_1}"
fi
if [ -d "/config" ]; then
echo "/config: EXISTS"
for f in /config/*; do
if [[ -f "$f" ]] || [[ -L "$f" ]]; then
echo "$f:"
cat "$f"
echo ""
echo ""
fi
done
else
echo "/config: does NOT EXIST"
fi
# Run nginx which will block here forever
/usr/sbin/nginx -g "daemon off;"
@@ -1,7 +0,0 @@
FROM python:3.13.0a2-alpine3.18
RUN apk --update --no-cache add alpine-sdk jq bash curl wget
WORKDIR /app
ENTRYPOINT [ "bash" ]
@@ -1,6 +1,6 @@
# Originally from: https://github.com/devcontainers/images/blob/main/src/javascript-node/.devcontainer/Dockerfile
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
ARG VARIANT=18-bullseye
ARG VARIANT=20-bullseye
FROM node:${VARIANT}
ARG USERNAME=node
@@ -28,7 +28,7 @@ RUN \
# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends jq
&& apt-get -y install --no-install-recommends jq gettext-base
# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
@@ -37,9 +37,7 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# We do this to get a yq binary from the published container, for the correct architecture we're building here
COPY --from=docker.io/mikefarah/yq:latest /usr/bin/yq /usr/local/bin/yq
RUN mkdir -p /scripts
COPY ./apply-webapp-config.sh /scripts
COPY ./start-serving-app.sh /scripts
COPY scripts /scripts
# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>"
@@ -0,0 +1,11 @@
FROM cerc/webapp-base:local as builder
ARG CERC_BUILD_TOOL
WORKDIR /app
COPY . .
RUN rm -rf node_modules build .next*
RUN /scripts/build-app.sh /app build /data
FROM cerc/webapp-base:local
COPY --from=builder /data /data
@@ -1,9 +1,29 @@
#!/usr/bin/env bash
# Build cerc/laconic-registry-cli
# Build cerc/webapp-base
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
# See: https://stackoverflow.com/a/246128/1701505
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -t cerc/webapp-base:local ${build_command_args} -f ${SCRIPT_DIR}/Dockerfile ${SCRIPT_DIR}
CERC_CONTAINER_BUILD_WORK_DIR=${CERC_CONTAINER_BUILD_WORK_DIR:-$SCRIPT_DIR}
CERC_CONTAINER_BUILD_DOCKERFILE=${CERC_CONTAINER_BUILD_DOCKERFILE:-$SCRIPT_DIR/Dockerfile}
CERC_CONTAINER_BUILD_TAG=${CERC_CONTAINER_BUILD_TAG:-cerc/webapp-base:local}
docker build -t $CERC_CONTAINER_BUILD_TAG ${build_command_args} -f $CERC_CONTAINER_BUILD_DOCKERFILE $CERC_CONTAINER_BUILD_WORK_DIR
if [ $? -eq 0 ] && [ "$CERC_CONTAINER_BUILD_TAG" != "cerc/webapp-base:local" ]; then
cat <<EOF
#################################################################
Built host container for $CERC_CONTAINER_BUILD_WORK_DIR with tag:
$CERC_CONTAINER_BUILD_TAG
To test locally run:
laconic-so run-webapp --image $CERC_CONTAINER_BUILD_TAG --env-file /path/to/environment.env
EOF
fi
@@ -0,0 +1,33 @@
#!/bin/bash
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
WORK_DIR="${1:-./}"
cd "${WORK_DIR}" || exit 1
if [ -f ".env" ]; then
TMP_ENV=`mktemp`
declare -px > $TMP_ENV
set -a
source .env
source $TMP_ENV
set +a
rm -f $TMP_ENV
fi
for f in $(find . -regex ".*.[tj]sx?$" -type f | grep -v 'node_modules'); do
for e in $(cat "${f}" | tr -s '[:blank:]' '\n' | tr -s '[{},();]' '\n' | egrep -o -e '^"CERC_RUNTIME_ENV_[^\"]+"' -e '^"LACONIC_HOSTED_CONFIG_[^\"]+"'); do
orig_name=$(echo -n "${e}" | sed 's/"//g')
cur_name=$(echo -n "${orig_name}" | sed 's/CERC_RUNTIME_ENV_//g')
cur_val=$(echo -n "\$${cur_name}" | envsubst)
if [ "$CERC_RETAIN_ENV_QUOTES" != "true" ]; then
cur_val=$(sed "s/^[\"']//" <<< "$cur_val" | sed "s/[\"']//")
fi
esc_val=$(sed 's/[&/\]/\\&/g' <<< "$cur_val")
echo "$f: $cur_name=$cur_val"
sed -i "s/$orig_name/$esc_val/g" $f
done
done
@@ -0,0 +1,36 @@
#!/bin/bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
CERC_BUILD_TOOL="${CERC_BUILD_TOOL}"
WORK_DIR="${1:-/app}"
OUTPUT_DIR="${2:-build}"
DEST_DIR="${3:-/data}"
if [ -f "${WORK_DIR}/package.json" ]; then
echo "Building node-based webapp ..."
cd "${WORK_DIR}" || exit 1
if [ -z "$CERC_BUILD_TOOL" ]; then
if [ -f "yarn.lock" ]; then
CERC_BUILD_TOOL=yarn
else
CERC_BUILD_TOOL=npm
fi
fi
$CERC_BUILD_TOOL install || exit 1
$CERC_BUILD_TOOL build || exit 1
rm -rf "${DEST_DIR}"
mv "${WORK_DIR}/${OUTPUT_DIR}" "${DEST_DIR}"
else
echo "Copying static app ..."
mv "${WORK_DIR}" "${DEST_DIR}"
fi
exit 0
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
CERC_WEBAPP_FILES_DIR="${CERC_WEBAPP_FILES_DIR:-/data}"
CERC_ENABLE_CORS="${CERC_ENABLE_CORS:-false}"
if [ "true" == "$CERC_ENABLE_CORS" ]; then
CERC_HTTP_EXTRA_ARGS="$CERC_HTTP_EXTRA_ARGS --cors"
fi
/scripts/apply-webapp-config.sh /config/config.yml ${CERC_WEBAPP_FILES_DIR}
/scripts/apply-runtime-env.sh ${CERC_WEBAPP_FILES_DIR}
http-server $CERC_HTTP_EXTRA_ARGS -p ${CERC_LISTEN_PORT:-80} ${CERC_WEBAPP_FILES_DIR}
@@ -1,9 +0,0 @@
#!/usr/bin/env bash
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
CERC_WEBAPP_FILES_DIR="${CERC_WEBAPP_FILES_DIR:-/data}"
/scripts/apply-webapp-config.sh /config/config.yml ${CERC_WEBAPP_FILES_DIR}
http-server -p 80 ${CERC_WEBAPP_FILES_DIR}
@@ -1,9 +1,9 @@
#!/usr/bin/env bash
# Build the urbit-globs-host image
# Build cerc/webapp-deployer-backend
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
# See: https://stackoverflow.com/a/246128/1701505
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker build -t cerc/urbit-globs-host:local -f ${SCRIPT_DIR}/Dockerfile ${build_command_args} ${SCRIPT_DIR}
docker build -t cerc/webapp-deployer-backend:local ${build_command_args} ${CERC_REPO_BASE_DIR}/webapp-deployment-status-api
@@ -3,7 +3,7 @@ name: act-runner
description: "Local act-runner"
repos:
- git.vdb.to/cerc-io/hosting
- gitea.com/gitea/act_runner
- gitea.com/telackey/act_runner@telackey/entrypoint
containers:
- cerc/act-runner
- cerc/act-runner-task-executor
@@ -40,20 +40,36 @@ network:
ports:
watcher-db:
- 0.0.0.0:15432:5432
azimuth-watcher-job-runner:
- 0.0.0.0:9000:9000
azimuth-watcher-server:
- 0.0.0.0:3001:3001
censures-watcher-job-runner:
- 0.0.0.0:9002:9002
censures-watcher-server:
- 0.0.0.0:3002:3002
claims-watcher-job-runner:
- 0.0.0.0:9004:9004
claims-watcher-server:
- 0.0.0.0:3003:3003
conditional-star-release-watcher-job-runner:
- 0.0.0.0:9006:9006
conditional-star-release-watcher-server:
- 0.0.0.0:3004:3004
delegated-sending-watcher-job-runner:
- 0.0.0.0:9008:9008
delegated-sending-watcher-server:
- 0.0.0.0:3005:3005
ecliptic-watcher-job-runner:
- 0.0.0.0:9010:9010
ecliptic-watcher-server:
- 0.0.0.0:3006:3006
linear-star-release-watcher-job-runner:
- 0.0.0.0:9012:9012
linear-star-release-watcher-server:
- 0.0.0.0:3007:3007
polls-watcher-job-runner:
- 0.0.0.0:9014:9014
polls-watcher-server:
- 0.0.0.0:3008:3008
gateway-server:
@@ -1,7 +1,7 @@
version: "1.0"
name: azimuth
repos:
- github.com/cerc-io/azimuth-watcher-ts@v0.1.2
- github.com/cerc-io/azimuth-watcher-ts@v0.1.3
containers:
- cerc/watcher-azimuth
pods:
@@ -0,0 +1,72 @@
# Copyright © 2022-2024 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/>.
from stack_orchestrator.util import get_yaml, get_config_file_dir
from stack_orchestrator.deploy.deploy_types import DeployCommandContext
from stack_orchestrator.deploy.deployment_context import DeploymentContext
from pathlib import Path
from shutil import copy
default_spec_file_content = ""
def _stack_config_dir(context: DeploymentContext) -> Path:
return get_config_file_dir().joinpath(context.stack.name)
def _deployment_volume_dir(context: DeploymentContext, volume_name: str) -> Path:
return context.deployment_dir.joinpath("data", volume_name)
def _copy_laconicd_scripts(context: DeploymentContext):
scripts = [
"create-fixturenet.sh",
"export-mykey.sh",
"export-myaddress.sh"
]
destination_dir = _deployment_volume_dir(context, "laconicd-scripts")
for script in scripts:
# ../config/fixturenet-laconicd/
source_file = _stack_config_dir(context).joinpath(script)
copy(source_file, destination_dir)
def _copy_cli_template(context: DeploymentContext):
destination_dir = _deployment_volume_dir(context, "cli-config")
# ../config/fixturenet-laconicd/
source_file = _stack_config_dir(context).joinpath("registry-cli-config-template.yml")
copy(source_file, destination_dir)
def setup(command_context: DeployCommandContext, parameters, extra_args):
pass
def init(command_context: DeployCommandContext):
yaml = get_yaml()
return yaml.load(default_spec_file_content)
def create(context: DeploymentContext, extra_args):
_copy_laconicd_scripts(context)
_copy_cli_template(context)
def get_state(command_context: DeployCommandContext):
pass
def change_state(command_context: DeployCommandContext):
pass
@@ -18,7 +18,7 @@ $ laconic-so --stack mainnet-eth build-containers
```
$ laconic-so --stack mainnet-eth deploy init --map-ports-to-host any-same --output mainnet-eth-spec.yml
$ laconic-so deploy create --spec-file mainnet-eth-spec.yml --deployment-dir mainnet-eth-deployment
$ laconic-so deploy --stack mainnet-eth create --spec-file mainnet-eth-spec.yml --deployment-dir mainnet-eth-deployment
```
## Start the stack
```
@@ -2,7 +2,7 @@ version: "1.0"
name: merkl-sushiswap-v3
description: "SushiSwap v3 watcher stack"
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:
- cerc/watcher-merkl-sushiswap-v3
pods:
@@ -0,0 +1,180 @@
# monitoring
* Instructions to setup and run a Prometheus server and Grafana dashboard
* Comes with the following built-in exporters / dashboards:
* Chain Head Exporter - for tracking chain heads given external ETH RPC endpoints
* Watchers dashboard
* [Prometheus Blackbox](https://grafana.com/grafana/dashboards/7587-prometheus-blackbox-exporter/) - for tracking HTTP endpoints
* [NodeJS Application Dashboard](https://grafana.com/grafana/dashboards/11159-nodejs-application-dashboard/) - for default NodeJS metrics
* [PostgreSQL Database](https://grafana.com/grafana/dashboards/9628-postgresql-database/) - for monitoring Postgres dbs
* [Node Exporter Full](https://grafana.com/grafana/dashboards/1860-node-exporter-full/) - for monitoring system metrics
* See [monitoring-watchers.md](./monitoring-watchers.md) for an example usage of the stack with pre-configured dashboards for watchers
## Setup
Clone required repositories:
```bash
laconic-so --stack monitoring setup-repositories --git-ssh --pull
```
Build the container images:
```bash
laconic-so --stack monitoring build-containers
```
## Create a deployment
First, create a spec file for the deployment, which will map the stack's ports and volumes to the host:
```bash
laconic-so --stack monitoring deploy init --output monitoring-spec.yml
```
### Ports
Edit `network` in spec file to map container ports to same ports in host:
```
...
network:
ports:
prometheus:
- '9090:9090'
grafana:
- '3000:3000'
...
```
### Data volumes
Container data volumes are bind-mounted to specified paths in the host filesystem.
The default setup (generated by `laconic-so deploy init`) places the volumes in the `./data` subdirectory of the deployment directory. The default mappings can be customized by editing the "spec" file generated by `laconic-so deploy init`.
---
Once you've made any needed changes to the spec file, create a deployment from it:
```bash
laconic-so --stack monitoring deploy create --spec-file monitoring-spec.yml --deployment-dir monitoring-deployment
```
## Configure
### Prometheus Config
* Add desired scrape configs to prometheus config file (`monitoring-deployment/config/monitoring/prometheus/prometheus.yml`) in the deployment folder; for example:
```yml
...
- job_name: <JOB_NAME>
metrics_path: /metrics/path
scheme: http
static_configs:
- targets: ['<METRICS_ENDPOINT_HOST>:<METRICS_ENDPOINT_PORT>']
```
* Node exporter: update the `node` job to add any node-exporter targets to be monitored:
```yml
...
- job_name: 'node'
...
static_configs:
# Add node-exporter targets to be monitored below
- targets: [example-host:9100]
labels:
instance: 'my-host'
```
* Blackbox (in-stack exporter): update the `blackbox` job to add any endpoints to be monitored on the Blackbox dashboard:
```yml
...
- job_name: 'blackbox'
...
static_configs:
# Add URLs to be monitored below
- targets:
- <HTTP_ENDPOINT_1>
- <HTTP_ENDPOINT_2>
```
* Postgres (in-stack exporter):
* Update the `postgres` job to add Postgres db targets to be monitored:
```yml
...
- job_name: 'postgres'
...
static_configs:
# Add DB targets below
- targets: [example-server:5432]
labels:
instance: 'example-db'
```
* Add database credentials to be used in `auth_modules` in the postgres-exporter config file (`monitoring-deployment/config/monitoring/postgres-exporter.yml`)
Note: Use `host.docker.internal` as host to access ports on the host machine
### Grafana Config
Place the dashboard json files in grafana dashboards config directory (`monitoring-deployment/config/monitoring/grafana/dashboards`) in the deployment folder
### Env
Set the following env variables in the deployment env config file (`monitoring-deployment/config.env`):
```bash
# For chain-head exporter
# External ETH RPC endpoint (ethereum)
# (Optional, default: https://mainnet.infura.io/v3)
CERC_ETH_RPC_ENDPOINT=
# Infura key to be used
# (Optional, used with ETH_RPC_ENDPOINT if provided)
CERC_INFURA_KEY=
# External ETH RPC endpoint (filecoin)
# (Optional, default: https://api.node.glif.io/rpc/v1)
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 deployment:
```bash
laconic-so deployment --dir monitoring-deployment start
```
* List and check the health status of all the containers using `docker ps` and wait for them to be `healthy`
* Grafana should now be visible at http://localhost:3000 with configured dashboards
## Clean up
To stop monitoring services running in the background, while preserving data:
```bash
# Only stop the docker containers
laconic-so deployment --dir monitoring-deployment stop
# Run 'start' to restart the deployment
```
To stop monitoring services and also delete data:
```bash
# Stop the docker containers
laconic-so deployment --dir monitoring-deployment stop --delete-volumes
# Remove deployment directory (deployment will have to be recreated for a re-run)
rm -rf monitoring-deployment
```
@@ -0,0 +1,170 @@
# Monitoring Watchers
Instructions to setup and run monitoring stack with configured Watchers dashboard
## Create a deployment
After completing [setup](./README.md#setup), create a spec file for the deployment, which will map the stack's ports and volumes to the host:
```bash
laconic-so --stack monitoring deploy init --output monitoring-watchers-spec.yml
```
### Ports
Edit `network` in spec file to map container ports to same ports in host:
```
...
network:
ports:
prometheus:
- '9090:9090'
grafana:
- '3000:3000'
...
```
---
Once you've made any needed changes to the spec file, create a deployment from it:
```bash
laconic-so --stack monitoring deploy create --spec-file monitoring-watchers-spec.yml --deployment-dir monitoring-watchers-deployment
```
## 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:
```yml
...
- job_name: 'blackbox'
...
static_configs:
- targets:
- <AZIMUTH_GATEWAY_GQL_ENDPOINT>
...
- job_name: azimuth
scrape_interval: 10s
metrics_path: /metrics
scheme: http
static_configs:
- targets: ['AZIMUTH_WATCHER_HOST:AZIMUTH_WATCHER_PORT']
labels:
instance: 'azimuth'
chain: 'ethereum'
- targets: ['CENSURES_WATCHER_HOST:CENSURES_WATCHER_PORT']
labels:
instance: 'censures'
chain: 'ethereum'
- targets: ['CLAIMS_WATCHER_HOST:CLAIMS_WATCHER_PORT']
labels:
instance: 'claims'
chain: 'ethereum'
- targets: ['CONDITIONAL_STAR_RELEASE_WATCHER_HOST:CONDITIONAL_STAR_RELEASE_WATCHER_PORT']
labels:
instance: 'conditional_star_release'
chain: 'ethereum'
- targets: ['DELEGATED_SENDING_WATCHER_HOST:DELEGATED_SENDING_WATCHER_PORT']
labels:
instance: 'delegated_sending'
chain: 'ethereum'
- targets: ['ECLIPTIC_WATCHER_HOST:ECLIPTIC_WATCHER_PORT']
labels:
instance: 'ecliptic'
chain: 'ethereum'
- targets: ['LINEAR_STAR_WATCHER_HOST:LINEAR_STAR_WATCHER_PORT']
labels:
instance: 'linear_star_release'
chain: 'ethereum'
- targets: ['POLLS_WATCHER_HOST:POLLS_WATCHER_PORT']
labels:
instance: 'polls'
chain: 'ethereum'
- job_name: sushi
scrape_interval: 20s
metrics_path: /metrics
scheme: http
static_configs:
- targets: ['SUSHISWAP_WATCHER_HOST:SUSHISWAP_WATCHER_PORT']
labels:
instance: 'sushiswap'
chain: 'filecoin'
- targets: ['MERKLE_SUSHISWAP_WATCHER_HOST:MERKLE_SUSHISWAP_WATCHER_PORT']
labels:
instance: 'merkl_sushiswap'
chain: 'filecoin'
```
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
Set the following env variables in the deployment env config file (`monitoring-watchers-deployment/config.env`):
```bash
# Infura key to be used
CERC_INFURA_KEY=
# Grafana server host URL to be used
# (Optional, default: http://localhost:3000)
GF_SERVER_ROOT_URL=
```
## Start the stack
Start the deployment:
```bash
laconic-so deployment --dir monitoring-watchers-deployment start
```
* List and check the health status of all the containers using `docker ps` and wait for them to be `healthy`
* Grafana should now be visible at http://localhost:3000 with configured dashboards
## Clean up
To stop monitoring services running in the background, while preserving data:
```bash
# Only stop the docker containers
laconic-so deployment --dir monitoring-watchers-deployment stop
# Run 'start' to restart the deployment
```
To stop monitoring services and also delete data:
```bash
# Stop the docker containers
laconic-so deployment --dir monitoring-watchers-deployment stop --delete-volumes
# Remove deployment directory (deployment will have to be recreated for a re-run)
rm -rf monitoring-watchers-deployment
```
@@ -0,0 +1,9 @@
version: "0.1"
name: monitoring
repos:
- github.com/cerc-io/watcher-ts@v0.2.79
containers:
- cerc/watcher-ts
pods:
- prom-server
- grafana
@@ -0,0 +1,17 @@
# node-exporter
## Start the stack
```bash
laconic-so --stack node-exporter deploy up
```
* The host node's metrics can be accessed at `http://localhost:9100/metrics`
## Clean up
Stop the node-exporter running in background:
```bash
laconic-so --stack node-exporter deploy down
```
@@ -0,0 +1,6 @@
version: "0.1"
name: node-exporter
repos:
containers:
pods:
- node-exporter

Some files were not shown because too many files have changed in this diff Show More